diff --git a/PhaseCompAcq/PhaseCompAcq.pro b/PhaseCompAcq/PhaseCompAcq.pro index ebb2309..f51a158 100644 --- a/PhaseCompAcq/PhaseCompAcq.pro +++ b/PhaseCompAcq/PhaseCompAcq.pro @@ -4,8 +4,7 @@ CONFIG += c++11 -FORMS += \ - PhaseWindow.ui +FORMS += PhaseWindow.ui include(common/common.pri) include(protocol/protocol.pri) diff --git a/PhaseCompAcq/PhaseCompAcq.pro b/PhaseCompAcq/PhaseCompAcq.pro index ebb2309..f51a158 100644 --- a/PhaseCompAcq/PhaseCompAcq.pro +++ b/PhaseCompAcq/PhaseCompAcq.pro @@ -4,8 +4,7 @@ CONFIG += c++11 -FORMS += \ - PhaseWindow.ui +FORMS += PhaseWindow.ui include(common/common.pri) include(protocol/protocol.pri) diff --git a/PhaseCompAcq/PhaseDevice.cpp b/PhaseCompAcq/PhaseDevice.cpp index c5466bb..b5be574 100644 --- a/PhaseCompAcq/PhaseDevice.cpp +++ b/PhaseCompAcq/PhaseDevice.cpp @@ -3,6 +3,8 @@ #include #include #include +#include +#include PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) { @@ -14,6 +16,20 @@ kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); kafkaUtil.createProducer(); } + + QVector> initPhase(PHASE_MESSURE_CHANNEL, QVector(0, 0)); + phaseVector = initPhase; + + QVector> initAllen(PHASE_MESSURE_CHANNEL, QVector(5, 0)); + channelAllen = initAllen; + + QVector> initSigma(PHASE_MESSURE_CHANNEL, QVector(5, 0)); + channelAllenSigma = initSigma; + + QVector initResult(PHASE_MESSURE_CHANNEL); + channelAllenResultStr = initResult; + + connect(this, &PhaseDevice::calculateAllen, this, &PhaseDevice::onCalculateAllen); } PhaseDevice::~PhaseDevice() @@ -134,23 +150,19 @@ QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); QLogUtil::writeRawDataLogByDate(date, filename, content); + // 发送到消息队列里的内容 QJsonArray messageArray; + QJsonArray performArray; QString msgLogFilename = "msg_" + devCode + ".log"; + QString perfLogFilename = "perf_" + devCode + ".log"; // 2.2 各个通道的相差数据 for (int i = 1; i <= phaseData->channelActive.size(); i++) { if (phaseData->channelActive.at(i-1).toUInt() == 1) { - QString chFilename("%1_CH_%2.log"); - chFilename = chFilename.arg(devCode); - if (i < 10) - { - chFilename = chFilename.arg(QString("0%1").arg(i)); - } else - { - chFilename = chFilename.arg(i); - } + // 存日志 + QString chFilename = QString("%1_CH_%2.log").arg(devCode).arg(i, 2, 10, QLatin1Char('0')); QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); @@ -160,6 +172,15 @@ jsonObj.insert("master", SettingConfig::getInstance().MASTER); jsonObj.insert("deviceId", deviceId); messageArray.append(jsonObj); + + // 将相位数据存入数据栈, 用于计算allen方差 + QMutex mutex; + mutex.lock(); + phaseVector[i - 1].append(phaseData->channelData.at(i - 1)); + if (phaseVector[i - 1].size() > SettingConfig::getInstance().MAX_DATA_SIZE) { + phaseVector[i - 1] = phaseVector[i - 1].mid(phaseVector[i - 1].size() - SettingConfig::getInstance().MAX_DATA_SIZE); + } + mutex.unlock(); } } @@ -177,10 +198,107 @@ if (QDateTime::currentDateTime().time().second() % 10 == 0) { kafkaUtil.produceMessage(SettingConfig::getInstance().KAFKA_STATUS_TOPIC, QString(QJsonDocument(statusObj).toJson(QJsonDocument::Compact))); } + + // 模拟发送稳定度计算结果 + // 1s 10s 100s 1000s 10000s + kafkaUtil.produceMessage(SettingConfig::getInstance().KAFKA_PERFORM_TOPIC, QString(QJsonDocument(performArray).toJson(QJsonDocument::Compact))); } QLogUtil::writeChannelDataLogByDate(date, msgLogFilename, QString(QJsonDocument(messageArray).toJson(QJsonDocument::Compact))); + QLogUtil::writeChannelDataLogByDate(date, perfLogFilename, QString(QJsonDocument(performArray).toJson(QJsonDocument::Compact))); // 4. 在界面上简单显示相差数据结果 emit this->sendDataToDraw(phaseData); + + // send signal to calculate allen and produce message to kafka + emit calculateAllen(); +} + +void PhaseDevice::onCalculateAllen() +{ + // 不同维度的稳定度数据 1s - 10000s + for (int i = 0; i < phaseVector.size(); i++) + { + QStringList result; + int size = phaseVector[i].size(); + for (int j = 0; j < 5; j++) + { + if (size >= 5 * pow(10, j)) { + channelAllen[i][j] = calAllan(i, pow(10, j), size); + } else { + channelAllen[i][j] = 0.0; + } + + result << QString::number(channelAllen[i][j], 'e', 4) << QString::number((int)(size / pow(10, j))); + } + + channelAllenResultStr[i] = result; +// qDebug() << result; + } + + emit this->sendAllenToDraw(devCode, channelAllenResultStr); +/* + // 分别计算不同时间维度的稳定度 + int size = phaseVector[i - 1].size(); + if(size >= 5) allen[0] = calAllan(i - 1, 1, size); else allen[0] = 0; + if(size >= 50) allen[1] = calAllan(i - 1, 10, size); else allen[1] = 0; + if(size >= 500) allen[2] = calAllan(i - 1, 100, size); else allen[2] = 0; + if(size >= 5000) allen[3] = calAllan(i - 1, 1000, size); else allen[3] = 0; + if(size >= 50000) allen[4] = calAllan(i - 1, 10000, size); else allen[4] = 0; + + // mock perform data + QJsonObject performData; + performData.insert("channelNo", i); + performData.insert("ts", (phaseData->milisecond / 1000) * 1000); + performData.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + performData.insert("master", SettingConfig::getInstance().MASTER); + performData.insert("deviceId", deviceId); + QJsonArray dataArr; + for (int k = 0; k < 5; k++) { + QJsonObject dataObj; + dataObj.insert("tau", QString::number(qPow(10, k))); + dataObj.insert("allen", QString::number(allen[k], 'e', 4)); + dataObj.insert("count", QString::number((int)(size / qPow(10, k)))); + dataArr.append(dataObj); + + QStringList allenStrList; + allenStrList << QString::number(qPow(10, k)) << QString::number(allen[k], 'e', 4) << QString::number((int)(size / qPow(10, k))); + phaseData->allenDataStr.append(allenStrList); + } + performData.insert("data", dataArr); + performArray.append(performData); + */ +} + +double PhaseDevice::calAllan(int index, int d, int aN) +{ + int i = 0; + double tau0 = 1; //tau0是基本采样间隔,由计数器或比相仪的最小采样间隔决定,最小为1s + double allan[2] = {0.0}; + double *y = new double[3]; + double tau_2 = pow(d * tau0, 2); //pow是计算x的y次幂 + + int logd = log10(d); + + double sum = channelAllenSigma[index][logd]; + + for (int j = 3; j > 0; j--) + { + i = aN - 2*d - j; + double v2 = phaseVector[index][i+2*d]; + double v1 = phaseVector[index][i+d]; + double v0 = phaseVector[index][i]; + y[3 - j] = pow(v2 - 2 * v1 + v0, 2); + + sum += y[3 - j]; + } + + channelAllenSigma[index][logd] += y[0]; + + allan[0] = sum/(2*tau_2*(aN-2*d)); //delta的平方 + allan[1] = sqrt(sum/(2*tau_2*(aN-2*d))); //delta + + delete[] y; + + return allan[1]; } diff --git a/PhaseCompAcq/PhaseCompAcq.pro b/PhaseCompAcq/PhaseCompAcq.pro index ebb2309..f51a158 100644 --- a/PhaseCompAcq/PhaseCompAcq.pro +++ b/PhaseCompAcq/PhaseCompAcq.pro @@ -4,8 +4,7 @@ CONFIG += c++11 -FORMS += \ - PhaseWindow.ui +FORMS += PhaseWindow.ui include(common/common.pri) include(protocol/protocol.pri) diff --git a/PhaseCompAcq/PhaseDevice.cpp b/PhaseCompAcq/PhaseDevice.cpp index c5466bb..b5be574 100644 --- a/PhaseCompAcq/PhaseDevice.cpp +++ b/PhaseCompAcq/PhaseDevice.cpp @@ -3,6 +3,8 @@ #include #include #include +#include +#include PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) { @@ -14,6 +16,20 @@ kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); kafkaUtil.createProducer(); } + + QVector> initPhase(PHASE_MESSURE_CHANNEL, QVector(0, 0)); + phaseVector = initPhase; + + QVector> initAllen(PHASE_MESSURE_CHANNEL, QVector(5, 0)); + channelAllen = initAllen; + + QVector> initSigma(PHASE_MESSURE_CHANNEL, QVector(5, 0)); + channelAllenSigma = initSigma; + + QVector initResult(PHASE_MESSURE_CHANNEL); + channelAllenResultStr = initResult; + + connect(this, &PhaseDevice::calculateAllen, this, &PhaseDevice::onCalculateAllen); } PhaseDevice::~PhaseDevice() @@ -134,23 +150,19 @@ QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); QLogUtil::writeRawDataLogByDate(date, filename, content); + // 发送到消息队列里的内容 QJsonArray messageArray; + QJsonArray performArray; QString msgLogFilename = "msg_" + devCode + ".log"; + QString perfLogFilename = "perf_" + devCode + ".log"; // 2.2 各个通道的相差数据 for (int i = 1; i <= phaseData->channelActive.size(); i++) { if (phaseData->channelActive.at(i-1).toUInt() == 1) { - QString chFilename("%1_CH_%2.log"); - chFilename = chFilename.arg(devCode); - if (i < 10) - { - chFilename = chFilename.arg(QString("0%1").arg(i)); - } else - { - chFilename = chFilename.arg(i); - } + // 存日志 + QString chFilename = QString("%1_CH_%2.log").arg(devCode).arg(i, 2, 10, QLatin1Char('0')); QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); @@ -160,6 +172,15 @@ jsonObj.insert("master", SettingConfig::getInstance().MASTER); jsonObj.insert("deviceId", deviceId); messageArray.append(jsonObj); + + // 将相位数据存入数据栈, 用于计算allen方差 + QMutex mutex; + mutex.lock(); + phaseVector[i - 1].append(phaseData->channelData.at(i - 1)); + if (phaseVector[i - 1].size() > SettingConfig::getInstance().MAX_DATA_SIZE) { + phaseVector[i - 1] = phaseVector[i - 1].mid(phaseVector[i - 1].size() - SettingConfig::getInstance().MAX_DATA_SIZE); + } + mutex.unlock(); } } @@ -177,10 +198,107 @@ if (QDateTime::currentDateTime().time().second() % 10 == 0) { kafkaUtil.produceMessage(SettingConfig::getInstance().KAFKA_STATUS_TOPIC, QString(QJsonDocument(statusObj).toJson(QJsonDocument::Compact))); } + + // 模拟发送稳定度计算结果 + // 1s 10s 100s 1000s 10000s + kafkaUtil.produceMessage(SettingConfig::getInstance().KAFKA_PERFORM_TOPIC, QString(QJsonDocument(performArray).toJson(QJsonDocument::Compact))); } QLogUtil::writeChannelDataLogByDate(date, msgLogFilename, QString(QJsonDocument(messageArray).toJson(QJsonDocument::Compact))); + QLogUtil::writeChannelDataLogByDate(date, perfLogFilename, QString(QJsonDocument(performArray).toJson(QJsonDocument::Compact))); // 4. 在界面上简单显示相差数据结果 emit this->sendDataToDraw(phaseData); + + // send signal to calculate allen and produce message to kafka + emit calculateAllen(); +} + +void PhaseDevice::onCalculateAllen() +{ + // 不同维度的稳定度数据 1s - 10000s + for (int i = 0; i < phaseVector.size(); i++) + { + QStringList result; + int size = phaseVector[i].size(); + for (int j = 0; j < 5; j++) + { + if (size >= 5 * pow(10, j)) { + channelAllen[i][j] = calAllan(i, pow(10, j), size); + } else { + channelAllen[i][j] = 0.0; + } + + result << QString::number(channelAllen[i][j], 'e', 4) << QString::number((int)(size / pow(10, j))); + } + + channelAllenResultStr[i] = result; +// qDebug() << result; + } + + emit this->sendAllenToDraw(devCode, channelAllenResultStr); +/* + // 分别计算不同时间维度的稳定度 + int size = phaseVector[i - 1].size(); + if(size >= 5) allen[0] = calAllan(i - 1, 1, size); else allen[0] = 0; + if(size >= 50) allen[1] = calAllan(i - 1, 10, size); else allen[1] = 0; + if(size >= 500) allen[2] = calAllan(i - 1, 100, size); else allen[2] = 0; + if(size >= 5000) allen[3] = calAllan(i - 1, 1000, size); else allen[3] = 0; + if(size >= 50000) allen[4] = calAllan(i - 1, 10000, size); else allen[4] = 0; + + // mock perform data + QJsonObject performData; + performData.insert("channelNo", i); + performData.insert("ts", (phaseData->milisecond / 1000) * 1000); + performData.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + performData.insert("master", SettingConfig::getInstance().MASTER); + performData.insert("deviceId", deviceId); + QJsonArray dataArr; + for (int k = 0; k < 5; k++) { + QJsonObject dataObj; + dataObj.insert("tau", QString::number(qPow(10, k))); + dataObj.insert("allen", QString::number(allen[k], 'e', 4)); + dataObj.insert("count", QString::number((int)(size / qPow(10, k)))); + dataArr.append(dataObj); + + QStringList allenStrList; + allenStrList << QString::number(qPow(10, k)) << QString::number(allen[k], 'e', 4) << QString::number((int)(size / qPow(10, k))); + phaseData->allenDataStr.append(allenStrList); + } + performData.insert("data", dataArr); + performArray.append(performData); + */ +} + +double PhaseDevice::calAllan(int index, int d, int aN) +{ + int i = 0; + double tau0 = 1; //tau0是基本采样间隔,由计数器或比相仪的最小采样间隔决定,最小为1s + double allan[2] = {0.0}; + double *y = new double[3]; + double tau_2 = pow(d * tau0, 2); //pow是计算x的y次幂 + + int logd = log10(d); + + double sum = channelAllenSigma[index][logd]; + + for (int j = 3; j > 0; j--) + { + i = aN - 2*d - j; + double v2 = phaseVector[index][i+2*d]; + double v1 = phaseVector[index][i+d]; + double v0 = phaseVector[index][i]; + y[3 - j] = pow(v2 - 2 * v1 + v0, 2); + + sum += y[3 - j]; + } + + channelAllenSigma[index][logd] += y[0]; + + allan[0] = sum/(2*tau_2*(aN-2*d)); //delta的平方 + allan[1] = sqrt(sum/(2*tau_2*(aN-2*d))); //delta + + delete[] y; + + return allan[1]; } diff --git a/PhaseCompAcq/PhaseDevice.h b/PhaseCompAcq/PhaseDevice.h index 887ed10..13b7c2d 100644 --- a/PhaseCompAcq/PhaseDevice.h +++ b/PhaseCompAcq/PhaseDevice.h @@ -2,6 +2,8 @@ #define PHASEDEVICE_H #include +#include +#include #include "common/utils/QSerialPortUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" @@ -38,11 +40,29 @@ QKafkaUtil kafkaUtil; QByteArray dataBuff; + // 原始数据 - 补偿之前的值 + QVector> phaseVector; + + // 不同维度的稳定度数据 1s - 10000s + QVector> channelAllen; + + // 计算过程中的累计和 + QVector> channelAllenSigma; + + // 各个通道的allen方差结果 + QVector channelAllenResultStr; + + // 计算allen方差 + double calAllan(int index, int d, int aN); + signals: void sendDataToDraw(PhaseDataDto * phaseData); + void calculateAllen(); + void sendAllenToDraw(QString devCode, QVector channelAllenResultStr); public slots: void dataReceivedHandler(QByteArray data); + void onCalculateAllen(); }; diff --git a/PhaseCompAcq/PhaseCompAcq.pro b/PhaseCompAcq/PhaseCompAcq.pro index ebb2309..f51a158 100644 --- a/PhaseCompAcq/PhaseCompAcq.pro +++ b/PhaseCompAcq/PhaseCompAcq.pro @@ -4,8 +4,7 @@ CONFIG += c++11 -FORMS += \ - PhaseWindow.ui +FORMS += PhaseWindow.ui include(common/common.pri) include(protocol/protocol.pri) diff --git a/PhaseCompAcq/PhaseDevice.cpp b/PhaseCompAcq/PhaseDevice.cpp index c5466bb..b5be574 100644 --- a/PhaseCompAcq/PhaseDevice.cpp +++ b/PhaseCompAcq/PhaseDevice.cpp @@ -3,6 +3,8 @@ #include #include #include +#include +#include PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) { @@ -14,6 +16,20 @@ kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); kafkaUtil.createProducer(); } + + QVector> initPhase(PHASE_MESSURE_CHANNEL, QVector(0, 0)); + phaseVector = initPhase; + + QVector> initAllen(PHASE_MESSURE_CHANNEL, QVector(5, 0)); + channelAllen = initAllen; + + QVector> initSigma(PHASE_MESSURE_CHANNEL, QVector(5, 0)); + channelAllenSigma = initSigma; + + QVector initResult(PHASE_MESSURE_CHANNEL); + channelAllenResultStr = initResult; + + connect(this, &PhaseDevice::calculateAllen, this, &PhaseDevice::onCalculateAllen); } PhaseDevice::~PhaseDevice() @@ -134,23 +150,19 @@ QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); QLogUtil::writeRawDataLogByDate(date, filename, content); + // 发送到消息队列里的内容 QJsonArray messageArray; + QJsonArray performArray; QString msgLogFilename = "msg_" + devCode + ".log"; + QString perfLogFilename = "perf_" + devCode + ".log"; // 2.2 各个通道的相差数据 for (int i = 1; i <= phaseData->channelActive.size(); i++) { if (phaseData->channelActive.at(i-1).toUInt() == 1) { - QString chFilename("%1_CH_%2.log"); - chFilename = chFilename.arg(devCode); - if (i < 10) - { - chFilename = chFilename.arg(QString("0%1").arg(i)); - } else - { - chFilename = chFilename.arg(i); - } + // 存日志 + QString chFilename = QString("%1_CH_%2.log").arg(devCode).arg(i, 2, 10, QLatin1Char('0')); QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); @@ -160,6 +172,15 @@ jsonObj.insert("master", SettingConfig::getInstance().MASTER); jsonObj.insert("deviceId", deviceId); messageArray.append(jsonObj); + + // 将相位数据存入数据栈, 用于计算allen方差 + QMutex mutex; + mutex.lock(); + phaseVector[i - 1].append(phaseData->channelData.at(i - 1)); + if (phaseVector[i - 1].size() > SettingConfig::getInstance().MAX_DATA_SIZE) { + phaseVector[i - 1] = phaseVector[i - 1].mid(phaseVector[i - 1].size() - SettingConfig::getInstance().MAX_DATA_SIZE); + } + mutex.unlock(); } } @@ -177,10 +198,107 @@ if (QDateTime::currentDateTime().time().second() % 10 == 0) { kafkaUtil.produceMessage(SettingConfig::getInstance().KAFKA_STATUS_TOPIC, QString(QJsonDocument(statusObj).toJson(QJsonDocument::Compact))); } + + // 模拟发送稳定度计算结果 + // 1s 10s 100s 1000s 10000s + kafkaUtil.produceMessage(SettingConfig::getInstance().KAFKA_PERFORM_TOPIC, QString(QJsonDocument(performArray).toJson(QJsonDocument::Compact))); } QLogUtil::writeChannelDataLogByDate(date, msgLogFilename, QString(QJsonDocument(messageArray).toJson(QJsonDocument::Compact))); + QLogUtil::writeChannelDataLogByDate(date, perfLogFilename, QString(QJsonDocument(performArray).toJson(QJsonDocument::Compact))); // 4. 在界面上简单显示相差数据结果 emit this->sendDataToDraw(phaseData); + + // send signal to calculate allen and produce message to kafka + emit calculateAllen(); +} + +void PhaseDevice::onCalculateAllen() +{ + // 不同维度的稳定度数据 1s - 10000s + for (int i = 0; i < phaseVector.size(); i++) + { + QStringList result; + int size = phaseVector[i].size(); + for (int j = 0; j < 5; j++) + { + if (size >= 5 * pow(10, j)) { + channelAllen[i][j] = calAllan(i, pow(10, j), size); + } else { + channelAllen[i][j] = 0.0; + } + + result << QString::number(channelAllen[i][j], 'e', 4) << QString::number((int)(size / pow(10, j))); + } + + channelAllenResultStr[i] = result; +// qDebug() << result; + } + + emit this->sendAllenToDraw(devCode, channelAllenResultStr); +/* + // 分别计算不同时间维度的稳定度 + int size = phaseVector[i - 1].size(); + if(size >= 5) allen[0] = calAllan(i - 1, 1, size); else allen[0] = 0; + if(size >= 50) allen[1] = calAllan(i - 1, 10, size); else allen[1] = 0; + if(size >= 500) allen[2] = calAllan(i - 1, 100, size); else allen[2] = 0; + if(size >= 5000) allen[3] = calAllan(i - 1, 1000, size); else allen[3] = 0; + if(size >= 50000) allen[4] = calAllan(i - 1, 10000, size); else allen[4] = 0; + + // mock perform data + QJsonObject performData; + performData.insert("channelNo", i); + performData.insert("ts", (phaseData->milisecond / 1000) * 1000); + performData.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + performData.insert("master", SettingConfig::getInstance().MASTER); + performData.insert("deviceId", deviceId); + QJsonArray dataArr; + for (int k = 0; k < 5; k++) { + QJsonObject dataObj; + dataObj.insert("tau", QString::number(qPow(10, k))); + dataObj.insert("allen", QString::number(allen[k], 'e', 4)); + dataObj.insert("count", QString::number((int)(size / qPow(10, k)))); + dataArr.append(dataObj); + + QStringList allenStrList; + allenStrList << QString::number(qPow(10, k)) << QString::number(allen[k], 'e', 4) << QString::number((int)(size / qPow(10, k))); + phaseData->allenDataStr.append(allenStrList); + } + performData.insert("data", dataArr); + performArray.append(performData); + */ +} + +double PhaseDevice::calAllan(int index, int d, int aN) +{ + int i = 0; + double tau0 = 1; //tau0是基本采样间隔,由计数器或比相仪的最小采样间隔决定,最小为1s + double allan[2] = {0.0}; + double *y = new double[3]; + double tau_2 = pow(d * tau0, 2); //pow是计算x的y次幂 + + int logd = log10(d); + + double sum = channelAllenSigma[index][logd]; + + for (int j = 3; j > 0; j--) + { + i = aN - 2*d - j; + double v2 = phaseVector[index][i+2*d]; + double v1 = phaseVector[index][i+d]; + double v0 = phaseVector[index][i]; + y[3 - j] = pow(v2 - 2 * v1 + v0, 2); + + sum += y[3 - j]; + } + + channelAllenSigma[index][logd] += y[0]; + + allan[0] = sum/(2*tau_2*(aN-2*d)); //delta的平方 + allan[1] = sqrt(sum/(2*tau_2*(aN-2*d))); //delta + + delete[] y; + + return allan[1]; } diff --git a/PhaseCompAcq/PhaseDevice.h b/PhaseCompAcq/PhaseDevice.h index 887ed10..13b7c2d 100644 --- a/PhaseCompAcq/PhaseDevice.h +++ b/PhaseCompAcq/PhaseDevice.h @@ -2,6 +2,8 @@ #define PHASEDEVICE_H #include +#include +#include #include "common/utils/QSerialPortUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" @@ -38,11 +40,29 @@ QKafkaUtil kafkaUtil; QByteArray dataBuff; + // 原始数据 - 补偿之前的值 + QVector> phaseVector; + + // 不同维度的稳定度数据 1s - 10000s + QVector> channelAllen; + + // 计算过程中的累计和 + QVector> channelAllenSigma; + + // 各个通道的allen方差结果 + QVector channelAllenResultStr; + + // 计算allen方差 + double calAllan(int index, int d, int aN); + signals: void sendDataToDraw(PhaseDataDto * phaseData); + void calculateAllen(); + void sendAllenToDraw(QString devCode, QVector channelAllenResultStr); public slots: void dataReceivedHandler(QByteArray data); + void onCalculateAllen(); }; diff --git a/PhaseCompAcq/PhaseWindow.cpp b/PhaseCompAcq/PhaseWindow.cpp index 514b271..a082818 100644 --- a/PhaseCompAcq/PhaseWindow.cpp +++ b/PhaseCompAcq/PhaseWindow.cpp @@ -72,8 +72,8 @@ device->setDevCode(devItem.find("deviceNo")->toString()); device->setDeviceId(devItem.find("deviceId")->toString()); - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); + connect(device, &PhaseDevice::sendDataToDraw, this, &PhaseWindow::drawPhaseDataOnPage); + connect(device, &PhaseDevice::sendAllenToDraw, this, &PhaseWindow::drawPhaseAllenOnPage); device->initSerialPort(); @@ -111,6 +111,8 @@ return; } + ui->labTm->setText(phaseData->timestamp.left(19)); + // 更新所有通道BOX的值 for (int i = 0; i < phaseData->channelActive.size(); i++) { @@ -118,13 +120,49 @@ QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); // 赋值,对应的lineEdit/label - ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); - ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); - ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); - ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + ((QLabel *)channelBox->children().at(1))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); // 有效性 + ((QLabel *)channelBox->children().at(2))->setText(phaseData->frameId); // 数据ID + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); // 测量数据值 } } +void PhaseWindow::drawPhaseAllenOnPage(QString devCode, QVector channelAllenResultStr) +{ + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 + if (devCode != currentDevCode) + { + return; + } + + // 更新所有通道BOX的值 + for (int i = 0; i < channelAllenResultStr.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的label + ((QLabel *)channelBox->children().at(7))->setText(channelAllenResultStr.at(i).at(0)); // tau=1 Allen + ((QLabel *)channelBox->children().at(8))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(1))); // tau=1 Count + + ((QLabel *)channelBox->children().at(10))->setText(channelAllenResultStr.at(i).at(2)); // tau=10 Allen + ((QLabel *)channelBox->children().at(11))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(3))); // tau=10 Count + + ((QLabel *)channelBox->children().at(13))->setText(channelAllenResultStr.at(i).at(4)); // tau=100 Allen + ((QLabel *)channelBox->children().at(14))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(5))); // tau=100 Count + + ((QLabel *)channelBox->children().at(16))->setText(channelAllenResultStr.at(i).at(6)); // tau=1000 Allen + ((QLabel *)channelBox->children().at(17))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(7))); // tau=1000 Count + + ((QLabel *)channelBox->children().at(19))->setText(channelAllenResultStr.at(i).at(8)); // tau=10000 Allen + ((QLabel *)channelBox->children().at(20))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(9))); // tau=10000 Count + } + +// qDebug() << channelAllenResultStr; +} + void PhaseWindow::generateWidgetForDevice() { // 获取设备数据 @@ -146,42 +184,124 @@ QHBoxLayout * vbox = new QHBoxLayout(group); - QLabel * tmLabel = new QLabel(); - tmLabel->setText("时间"); - tmLabel->setFont(labelFont); - tmLabel->setStyleSheet("margin-left:20;"); - vbox->addWidget(tmLabel); - QLineEdit * tmValue = new QLineEdit(); - tmValue->setFixedWidth(200); - tmValue->setFont(labelFont); - vbox->addWidget(tmValue); - - QLabel * dataLabel = new QLabel(); - dataLabel->setText("测量数据"); - dataLabel->setFont(labelFont); - dataLabel->setStyleSheet("margin-left:20;"); - vbox->addWidget(dataLabel); - QLineEdit * dataValue = new QLineEdit(); - dataValue->setFixedWidth(250); - dataValue->setFont(labelFont); - vbox->addWidget(dataValue); - - QLabel * idLabel = new QLabel(); - idLabel->setText("数据ID"); - idLabel->setFont(labelFont); - idLabel->setStyleSheet("margin-left:20;"); - vbox->addWidget(idLabel); - QLineEdit * idValue = new QLineEdit(); - idValue->setFixedWidth(100); - idValue->setFont(labelFont); - vbox->addWidget(idValue); - + // index = 1 QLabel * validLabel = new QLabel(); validLabel->setText("-"); validLabel->setFont(labelFont); validLabel->setStyleSheet("margin-left:20;"); vbox->addWidget(validLabel); + // index = 2 + QLabel * idLabel = new QLabel(); + idLabel->setText("0000"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + + // index = 3 + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + // index = 4 + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(200); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + // index = 5 + QLabel * perfLabel = new QLabel(); + perfLabel->setText("稳定度"); + perfLabel->setFont(labelFont); + perfLabel->setStyleSheet("margin-left:50;"); + vbox->addWidget(perfLabel); + + // index = 6 + QLabel * oneLabel = new QLabel(); + oneLabel->setText("Tau(s)=1"); + oneLabel->setFont(labelFont); + oneLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(oneLabel); + // index = 7 + QLabel * oneAllen = new QLabel(); + oneAllen->setText("0.00"); + oneAllen->setFont(labelFont); + vbox->addWidget(oneAllen); + // index = 8 + QLabel * oneCount = new QLabel(); + oneCount->setText("0"); + oneCount->setFont(labelFont); + vbox->addWidget(oneCount); + + // index = 9 + QLabel * tenLabel = new QLabel(); + tenLabel->setText("Tau(s)=10"); + tenLabel->setFont(labelFont); + tenLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tenLabel); + // index = 10 + QLabel * tenAllen = new QLabel(); + tenAllen->setText("0.00"); + tenAllen->setFont(labelFont); + vbox->addWidget(tenAllen); + // index = 11 + QLabel * tenCount = new QLabel(); + tenCount->setText("0"); + tenCount->setFont(labelFont); + vbox->addWidget(tenCount); + + // index = 12 + QLabel * hundLabel = new QLabel(); + hundLabel->setText("Tau(s)=100"); + hundLabel->setFont(labelFont); + hundLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(hundLabel); + // index = 13 + QLabel * hundAllen = new QLabel(); + hundAllen->setText("0.00"); + hundAllen->setFont(labelFont); + vbox->addWidget(hundAllen); + // index = 14 + QLabel * hundCount = new QLabel(); + hundCount->setText("0"); + hundCount->setFont(labelFont); + vbox->addWidget(hundCount); + + // index = 15 + QLabel * thouLabel = new QLabel(); + thouLabel->setText("Tau(s)=1000"); + thouLabel->setFont(labelFont); + thouLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(thouLabel); + // index = 16 + QLabel * thouAllen = new QLabel(); + thouAllen->setText("0.00"); + thouAllen->setFont(labelFont); + vbox->addWidget(thouAllen); + // index = 17 + QLabel * thouCount = new QLabel(); + thouCount->setText("0"); + thouCount->setFont(labelFont); + vbox->addWidget(thouCount); + + // index = 18 + QLabel * ttLabel = new QLabel(); + ttLabel->setText("Tau(s)=10000"); + ttLabel->setFont(labelFont); + ttLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(ttLabel); + // index = 19 + QLabel * ttAllen = new QLabel(); + ttAllen->setText("0.00"); + ttAllen->setFont(labelFont); + vbox->addWidget(ttAllen); + // index = 20 + QLabel * ttCount = new QLabel(); + ttCount->setText("0"); + ttCount->setFont(labelFont); + vbox->addWidget(ttCount); + QSpacerItem * hSpace = new QSpacerItem(20, 20); hSpace->changeSize(20, 20, QSizePolicy::Expanding); vbox->addItem(hSpace); @@ -247,9 +367,23 @@ QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); // 赋值,对应的lineEdit/label - ((QLineEdit *)channelBox->children().at(2))->setText(""); - ((QLineEdit *)channelBox->children().at(4))->setText(""); - ((QLineEdit *)channelBox->children().at(6))->setText(""); - ((QLabel *)channelBox->children().at(7))->setText("-"); + ((QLabel *)channelBox->children().at(1))->setText("-"); // 有效性 + ((QLabel *)channelBox->children().at(2))->setText("0000"); // 数据ID + ((QLineEdit *)channelBox->children().at(4))->setText(""); // 测量数据值 + + ((QLabel *)channelBox->children().at(7))->setText("0.00"); // tau=1 Allen + ((QLabel *)channelBox->children().at(8))->setText(QString("采样数(%1)").arg(0)); // tau=1 Count + + ((QLabel *)channelBox->children().at(10))->setText("0.00"); // tau=10 Allen + ((QLabel *)channelBox->children().at(11))->setText(QString("采样数(%1)").arg(0)); // tau=10 Count + + ((QLabel *)channelBox->children().at(13))->setText("0.00"); // tau=100 Allen + ((QLabel *)channelBox->children().at(14))->setText(QString("采样数(%1)").arg(0)); // tau=100 Count + + ((QLabel *)channelBox->children().at(16))->setText("0.00"); // tau=1000 Allen + ((QLabel *)channelBox->children().at(17))->setText(QString("采样数(%1)").arg(0)); // tau=1000 Count + + ((QLabel *)channelBox->children().at(19))->setText("0.00"); // tau=10000 Allen + ((QLabel *)channelBox->children().at(20))->setText(QString("采样数(%1)").arg(0)); // tau=10000 Count } } diff --git a/PhaseCompAcq/PhaseCompAcq.pro b/PhaseCompAcq/PhaseCompAcq.pro index ebb2309..f51a158 100644 --- a/PhaseCompAcq/PhaseCompAcq.pro +++ b/PhaseCompAcq/PhaseCompAcq.pro @@ -4,8 +4,7 @@ CONFIG += c++11 -FORMS += \ - PhaseWindow.ui +FORMS += PhaseWindow.ui include(common/common.pri) include(protocol/protocol.pri) diff --git a/PhaseCompAcq/PhaseDevice.cpp b/PhaseCompAcq/PhaseDevice.cpp index c5466bb..b5be574 100644 --- a/PhaseCompAcq/PhaseDevice.cpp +++ b/PhaseCompAcq/PhaseDevice.cpp @@ -3,6 +3,8 @@ #include #include #include +#include +#include PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) { @@ -14,6 +16,20 @@ kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); kafkaUtil.createProducer(); } + + QVector> initPhase(PHASE_MESSURE_CHANNEL, QVector(0, 0)); + phaseVector = initPhase; + + QVector> initAllen(PHASE_MESSURE_CHANNEL, QVector(5, 0)); + channelAllen = initAllen; + + QVector> initSigma(PHASE_MESSURE_CHANNEL, QVector(5, 0)); + channelAllenSigma = initSigma; + + QVector initResult(PHASE_MESSURE_CHANNEL); + channelAllenResultStr = initResult; + + connect(this, &PhaseDevice::calculateAllen, this, &PhaseDevice::onCalculateAllen); } PhaseDevice::~PhaseDevice() @@ -134,23 +150,19 @@ QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); QLogUtil::writeRawDataLogByDate(date, filename, content); + // 发送到消息队列里的内容 QJsonArray messageArray; + QJsonArray performArray; QString msgLogFilename = "msg_" + devCode + ".log"; + QString perfLogFilename = "perf_" + devCode + ".log"; // 2.2 各个通道的相差数据 for (int i = 1; i <= phaseData->channelActive.size(); i++) { if (phaseData->channelActive.at(i-1).toUInt() == 1) { - QString chFilename("%1_CH_%2.log"); - chFilename = chFilename.arg(devCode); - if (i < 10) - { - chFilename = chFilename.arg(QString("0%1").arg(i)); - } else - { - chFilename = chFilename.arg(i); - } + // 存日志 + QString chFilename = QString("%1_CH_%2.log").arg(devCode).arg(i, 2, 10, QLatin1Char('0')); QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); @@ -160,6 +172,15 @@ jsonObj.insert("master", SettingConfig::getInstance().MASTER); jsonObj.insert("deviceId", deviceId); messageArray.append(jsonObj); + + // 将相位数据存入数据栈, 用于计算allen方差 + QMutex mutex; + mutex.lock(); + phaseVector[i - 1].append(phaseData->channelData.at(i - 1)); + if (phaseVector[i - 1].size() > SettingConfig::getInstance().MAX_DATA_SIZE) { + phaseVector[i - 1] = phaseVector[i - 1].mid(phaseVector[i - 1].size() - SettingConfig::getInstance().MAX_DATA_SIZE); + } + mutex.unlock(); } } @@ -177,10 +198,107 @@ if (QDateTime::currentDateTime().time().second() % 10 == 0) { kafkaUtil.produceMessage(SettingConfig::getInstance().KAFKA_STATUS_TOPIC, QString(QJsonDocument(statusObj).toJson(QJsonDocument::Compact))); } + + // 模拟发送稳定度计算结果 + // 1s 10s 100s 1000s 10000s + kafkaUtil.produceMessage(SettingConfig::getInstance().KAFKA_PERFORM_TOPIC, QString(QJsonDocument(performArray).toJson(QJsonDocument::Compact))); } QLogUtil::writeChannelDataLogByDate(date, msgLogFilename, QString(QJsonDocument(messageArray).toJson(QJsonDocument::Compact))); + QLogUtil::writeChannelDataLogByDate(date, perfLogFilename, QString(QJsonDocument(performArray).toJson(QJsonDocument::Compact))); // 4. 在界面上简单显示相差数据结果 emit this->sendDataToDraw(phaseData); + + // send signal to calculate allen and produce message to kafka + emit calculateAllen(); +} + +void PhaseDevice::onCalculateAllen() +{ + // 不同维度的稳定度数据 1s - 10000s + for (int i = 0; i < phaseVector.size(); i++) + { + QStringList result; + int size = phaseVector[i].size(); + for (int j = 0; j < 5; j++) + { + if (size >= 5 * pow(10, j)) { + channelAllen[i][j] = calAllan(i, pow(10, j), size); + } else { + channelAllen[i][j] = 0.0; + } + + result << QString::number(channelAllen[i][j], 'e', 4) << QString::number((int)(size / pow(10, j))); + } + + channelAllenResultStr[i] = result; +// qDebug() << result; + } + + emit this->sendAllenToDraw(devCode, channelAllenResultStr); +/* + // 分别计算不同时间维度的稳定度 + int size = phaseVector[i - 1].size(); + if(size >= 5) allen[0] = calAllan(i - 1, 1, size); else allen[0] = 0; + if(size >= 50) allen[1] = calAllan(i - 1, 10, size); else allen[1] = 0; + if(size >= 500) allen[2] = calAllan(i - 1, 100, size); else allen[2] = 0; + if(size >= 5000) allen[3] = calAllan(i - 1, 1000, size); else allen[3] = 0; + if(size >= 50000) allen[4] = calAllan(i - 1, 10000, size); else allen[4] = 0; + + // mock perform data + QJsonObject performData; + performData.insert("channelNo", i); + performData.insert("ts", (phaseData->milisecond / 1000) * 1000); + performData.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + performData.insert("master", SettingConfig::getInstance().MASTER); + performData.insert("deviceId", deviceId); + QJsonArray dataArr; + for (int k = 0; k < 5; k++) { + QJsonObject dataObj; + dataObj.insert("tau", QString::number(qPow(10, k))); + dataObj.insert("allen", QString::number(allen[k], 'e', 4)); + dataObj.insert("count", QString::number((int)(size / qPow(10, k)))); + dataArr.append(dataObj); + + QStringList allenStrList; + allenStrList << QString::number(qPow(10, k)) << QString::number(allen[k], 'e', 4) << QString::number((int)(size / qPow(10, k))); + phaseData->allenDataStr.append(allenStrList); + } + performData.insert("data", dataArr); + performArray.append(performData); + */ +} + +double PhaseDevice::calAllan(int index, int d, int aN) +{ + int i = 0; + double tau0 = 1; //tau0是基本采样间隔,由计数器或比相仪的最小采样间隔决定,最小为1s + double allan[2] = {0.0}; + double *y = new double[3]; + double tau_2 = pow(d * tau0, 2); //pow是计算x的y次幂 + + int logd = log10(d); + + double sum = channelAllenSigma[index][logd]; + + for (int j = 3; j > 0; j--) + { + i = aN - 2*d - j; + double v2 = phaseVector[index][i+2*d]; + double v1 = phaseVector[index][i+d]; + double v0 = phaseVector[index][i]; + y[3 - j] = pow(v2 - 2 * v1 + v0, 2); + + sum += y[3 - j]; + } + + channelAllenSigma[index][logd] += y[0]; + + allan[0] = sum/(2*tau_2*(aN-2*d)); //delta的平方 + allan[1] = sqrt(sum/(2*tau_2*(aN-2*d))); //delta + + delete[] y; + + return allan[1]; } diff --git a/PhaseCompAcq/PhaseDevice.h b/PhaseCompAcq/PhaseDevice.h index 887ed10..13b7c2d 100644 --- a/PhaseCompAcq/PhaseDevice.h +++ b/PhaseCompAcq/PhaseDevice.h @@ -2,6 +2,8 @@ #define PHASEDEVICE_H #include +#include +#include #include "common/utils/QSerialPortUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" @@ -38,11 +40,29 @@ QKafkaUtil kafkaUtil; QByteArray dataBuff; + // 原始数据 - 补偿之前的值 + QVector> phaseVector; + + // 不同维度的稳定度数据 1s - 10000s + QVector> channelAllen; + + // 计算过程中的累计和 + QVector> channelAllenSigma; + + // 各个通道的allen方差结果 + QVector channelAllenResultStr; + + // 计算allen方差 + double calAllan(int index, int d, int aN); + signals: void sendDataToDraw(PhaseDataDto * phaseData); + void calculateAllen(); + void sendAllenToDraw(QString devCode, QVector channelAllenResultStr); public slots: void dataReceivedHandler(QByteArray data); + void onCalculateAllen(); }; diff --git a/PhaseCompAcq/PhaseWindow.cpp b/PhaseCompAcq/PhaseWindow.cpp index 514b271..a082818 100644 --- a/PhaseCompAcq/PhaseWindow.cpp +++ b/PhaseCompAcq/PhaseWindow.cpp @@ -72,8 +72,8 @@ device->setDevCode(devItem.find("deviceNo")->toString()); device->setDeviceId(devItem.find("deviceId")->toString()); - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); + connect(device, &PhaseDevice::sendDataToDraw, this, &PhaseWindow::drawPhaseDataOnPage); + connect(device, &PhaseDevice::sendAllenToDraw, this, &PhaseWindow::drawPhaseAllenOnPage); device->initSerialPort(); @@ -111,6 +111,8 @@ return; } + ui->labTm->setText(phaseData->timestamp.left(19)); + // 更新所有通道BOX的值 for (int i = 0; i < phaseData->channelActive.size(); i++) { @@ -118,13 +120,49 @@ QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); // 赋值,对应的lineEdit/label - ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); - ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); - ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); - ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + ((QLabel *)channelBox->children().at(1))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); // 有效性 + ((QLabel *)channelBox->children().at(2))->setText(phaseData->frameId); // 数据ID + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); // 测量数据值 } } +void PhaseWindow::drawPhaseAllenOnPage(QString devCode, QVector channelAllenResultStr) +{ + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 + if (devCode != currentDevCode) + { + return; + } + + // 更新所有通道BOX的值 + for (int i = 0; i < channelAllenResultStr.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的label + ((QLabel *)channelBox->children().at(7))->setText(channelAllenResultStr.at(i).at(0)); // tau=1 Allen + ((QLabel *)channelBox->children().at(8))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(1))); // tau=1 Count + + ((QLabel *)channelBox->children().at(10))->setText(channelAllenResultStr.at(i).at(2)); // tau=10 Allen + ((QLabel *)channelBox->children().at(11))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(3))); // tau=10 Count + + ((QLabel *)channelBox->children().at(13))->setText(channelAllenResultStr.at(i).at(4)); // tau=100 Allen + ((QLabel *)channelBox->children().at(14))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(5))); // tau=100 Count + + ((QLabel *)channelBox->children().at(16))->setText(channelAllenResultStr.at(i).at(6)); // tau=1000 Allen + ((QLabel *)channelBox->children().at(17))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(7))); // tau=1000 Count + + ((QLabel *)channelBox->children().at(19))->setText(channelAllenResultStr.at(i).at(8)); // tau=10000 Allen + ((QLabel *)channelBox->children().at(20))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(9))); // tau=10000 Count + } + +// qDebug() << channelAllenResultStr; +} + void PhaseWindow::generateWidgetForDevice() { // 获取设备数据 @@ -146,42 +184,124 @@ QHBoxLayout * vbox = new QHBoxLayout(group); - QLabel * tmLabel = new QLabel(); - tmLabel->setText("时间"); - tmLabel->setFont(labelFont); - tmLabel->setStyleSheet("margin-left:20;"); - vbox->addWidget(tmLabel); - QLineEdit * tmValue = new QLineEdit(); - tmValue->setFixedWidth(200); - tmValue->setFont(labelFont); - vbox->addWidget(tmValue); - - QLabel * dataLabel = new QLabel(); - dataLabel->setText("测量数据"); - dataLabel->setFont(labelFont); - dataLabel->setStyleSheet("margin-left:20;"); - vbox->addWidget(dataLabel); - QLineEdit * dataValue = new QLineEdit(); - dataValue->setFixedWidth(250); - dataValue->setFont(labelFont); - vbox->addWidget(dataValue); - - QLabel * idLabel = new QLabel(); - idLabel->setText("数据ID"); - idLabel->setFont(labelFont); - idLabel->setStyleSheet("margin-left:20;"); - vbox->addWidget(idLabel); - QLineEdit * idValue = new QLineEdit(); - idValue->setFixedWidth(100); - idValue->setFont(labelFont); - vbox->addWidget(idValue); - + // index = 1 QLabel * validLabel = new QLabel(); validLabel->setText("-"); validLabel->setFont(labelFont); validLabel->setStyleSheet("margin-left:20;"); vbox->addWidget(validLabel); + // index = 2 + QLabel * idLabel = new QLabel(); + idLabel->setText("0000"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + + // index = 3 + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + // index = 4 + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(200); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + // index = 5 + QLabel * perfLabel = new QLabel(); + perfLabel->setText("稳定度"); + perfLabel->setFont(labelFont); + perfLabel->setStyleSheet("margin-left:50;"); + vbox->addWidget(perfLabel); + + // index = 6 + QLabel * oneLabel = new QLabel(); + oneLabel->setText("Tau(s)=1"); + oneLabel->setFont(labelFont); + oneLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(oneLabel); + // index = 7 + QLabel * oneAllen = new QLabel(); + oneAllen->setText("0.00"); + oneAllen->setFont(labelFont); + vbox->addWidget(oneAllen); + // index = 8 + QLabel * oneCount = new QLabel(); + oneCount->setText("0"); + oneCount->setFont(labelFont); + vbox->addWidget(oneCount); + + // index = 9 + QLabel * tenLabel = new QLabel(); + tenLabel->setText("Tau(s)=10"); + tenLabel->setFont(labelFont); + tenLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tenLabel); + // index = 10 + QLabel * tenAllen = new QLabel(); + tenAllen->setText("0.00"); + tenAllen->setFont(labelFont); + vbox->addWidget(tenAllen); + // index = 11 + QLabel * tenCount = new QLabel(); + tenCount->setText("0"); + tenCount->setFont(labelFont); + vbox->addWidget(tenCount); + + // index = 12 + QLabel * hundLabel = new QLabel(); + hundLabel->setText("Tau(s)=100"); + hundLabel->setFont(labelFont); + hundLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(hundLabel); + // index = 13 + QLabel * hundAllen = new QLabel(); + hundAllen->setText("0.00"); + hundAllen->setFont(labelFont); + vbox->addWidget(hundAllen); + // index = 14 + QLabel * hundCount = new QLabel(); + hundCount->setText("0"); + hundCount->setFont(labelFont); + vbox->addWidget(hundCount); + + // index = 15 + QLabel * thouLabel = new QLabel(); + thouLabel->setText("Tau(s)=1000"); + thouLabel->setFont(labelFont); + thouLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(thouLabel); + // index = 16 + QLabel * thouAllen = new QLabel(); + thouAllen->setText("0.00"); + thouAllen->setFont(labelFont); + vbox->addWidget(thouAllen); + // index = 17 + QLabel * thouCount = new QLabel(); + thouCount->setText("0"); + thouCount->setFont(labelFont); + vbox->addWidget(thouCount); + + // index = 18 + QLabel * ttLabel = new QLabel(); + ttLabel->setText("Tau(s)=10000"); + ttLabel->setFont(labelFont); + ttLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(ttLabel); + // index = 19 + QLabel * ttAllen = new QLabel(); + ttAllen->setText("0.00"); + ttAllen->setFont(labelFont); + vbox->addWidget(ttAllen); + // index = 20 + QLabel * ttCount = new QLabel(); + ttCount->setText("0"); + ttCount->setFont(labelFont); + vbox->addWidget(ttCount); + QSpacerItem * hSpace = new QSpacerItem(20, 20); hSpace->changeSize(20, 20, QSizePolicy::Expanding); vbox->addItem(hSpace); @@ -247,9 +367,23 @@ QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); // 赋值,对应的lineEdit/label - ((QLineEdit *)channelBox->children().at(2))->setText(""); - ((QLineEdit *)channelBox->children().at(4))->setText(""); - ((QLineEdit *)channelBox->children().at(6))->setText(""); - ((QLabel *)channelBox->children().at(7))->setText("-"); + ((QLabel *)channelBox->children().at(1))->setText("-"); // 有效性 + ((QLabel *)channelBox->children().at(2))->setText("0000"); // 数据ID + ((QLineEdit *)channelBox->children().at(4))->setText(""); // 测量数据值 + + ((QLabel *)channelBox->children().at(7))->setText("0.00"); // tau=1 Allen + ((QLabel *)channelBox->children().at(8))->setText(QString("采样数(%1)").arg(0)); // tau=1 Count + + ((QLabel *)channelBox->children().at(10))->setText("0.00"); // tau=10 Allen + ((QLabel *)channelBox->children().at(11))->setText(QString("采样数(%1)").arg(0)); // tau=10 Count + + ((QLabel *)channelBox->children().at(13))->setText("0.00"); // tau=100 Allen + ((QLabel *)channelBox->children().at(14))->setText(QString("采样数(%1)").arg(0)); // tau=100 Count + + ((QLabel *)channelBox->children().at(16))->setText("0.00"); // tau=1000 Allen + ((QLabel *)channelBox->children().at(17))->setText(QString("采样数(%1)").arg(0)); // tau=1000 Count + + ((QLabel *)channelBox->children().at(19))->setText("0.00"); // tau=10000 Allen + ((QLabel *)channelBox->children().at(20))->setText(QString("采样数(%1)").arg(0)); // tau=10000 Count } } diff --git a/PhaseCompAcq/PhaseWindow.h b/PhaseCompAcq/PhaseWindow.h index bf1cb57..572bbde 100644 --- a/PhaseCompAcq/PhaseWindow.h +++ b/PhaseCompAcq/PhaseWindow.h @@ -25,6 +25,7 @@ public slots: void drawPhaseDataOnPage(PhaseDataDto * phaseData); + void drawPhaseAllenOnPage(QString devCode, QVector channelAllenResultStr); private slots: void on_minButt_clicked(); diff --git a/PhaseCompAcq/PhaseCompAcq.pro b/PhaseCompAcq/PhaseCompAcq.pro index ebb2309..f51a158 100644 --- a/PhaseCompAcq/PhaseCompAcq.pro +++ b/PhaseCompAcq/PhaseCompAcq.pro @@ -4,8 +4,7 @@ CONFIG += c++11 -FORMS += \ - PhaseWindow.ui +FORMS += PhaseWindow.ui include(common/common.pri) include(protocol/protocol.pri) diff --git a/PhaseCompAcq/PhaseDevice.cpp b/PhaseCompAcq/PhaseDevice.cpp index c5466bb..b5be574 100644 --- a/PhaseCompAcq/PhaseDevice.cpp +++ b/PhaseCompAcq/PhaseDevice.cpp @@ -3,6 +3,8 @@ #include #include #include +#include +#include PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) { @@ -14,6 +16,20 @@ kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); kafkaUtil.createProducer(); } + + QVector> initPhase(PHASE_MESSURE_CHANNEL, QVector(0, 0)); + phaseVector = initPhase; + + QVector> initAllen(PHASE_MESSURE_CHANNEL, QVector(5, 0)); + channelAllen = initAllen; + + QVector> initSigma(PHASE_MESSURE_CHANNEL, QVector(5, 0)); + channelAllenSigma = initSigma; + + QVector initResult(PHASE_MESSURE_CHANNEL); + channelAllenResultStr = initResult; + + connect(this, &PhaseDevice::calculateAllen, this, &PhaseDevice::onCalculateAllen); } PhaseDevice::~PhaseDevice() @@ -134,23 +150,19 @@ QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); QLogUtil::writeRawDataLogByDate(date, filename, content); + // 发送到消息队列里的内容 QJsonArray messageArray; + QJsonArray performArray; QString msgLogFilename = "msg_" + devCode + ".log"; + QString perfLogFilename = "perf_" + devCode + ".log"; // 2.2 各个通道的相差数据 for (int i = 1; i <= phaseData->channelActive.size(); i++) { if (phaseData->channelActive.at(i-1).toUInt() == 1) { - QString chFilename("%1_CH_%2.log"); - chFilename = chFilename.arg(devCode); - if (i < 10) - { - chFilename = chFilename.arg(QString("0%1").arg(i)); - } else - { - chFilename = chFilename.arg(i); - } + // 存日志 + QString chFilename = QString("%1_CH_%2.log").arg(devCode).arg(i, 2, 10, QLatin1Char('0')); QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); @@ -160,6 +172,15 @@ jsonObj.insert("master", SettingConfig::getInstance().MASTER); jsonObj.insert("deviceId", deviceId); messageArray.append(jsonObj); + + // 将相位数据存入数据栈, 用于计算allen方差 + QMutex mutex; + mutex.lock(); + phaseVector[i - 1].append(phaseData->channelData.at(i - 1)); + if (phaseVector[i - 1].size() > SettingConfig::getInstance().MAX_DATA_SIZE) { + phaseVector[i - 1] = phaseVector[i - 1].mid(phaseVector[i - 1].size() - SettingConfig::getInstance().MAX_DATA_SIZE); + } + mutex.unlock(); } } @@ -177,10 +198,107 @@ if (QDateTime::currentDateTime().time().second() % 10 == 0) { kafkaUtil.produceMessage(SettingConfig::getInstance().KAFKA_STATUS_TOPIC, QString(QJsonDocument(statusObj).toJson(QJsonDocument::Compact))); } + + // 模拟发送稳定度计算结果 + // 1s 10s 100s 1000s 10000s + kafkaUtil.produceMessage(SettingConfig::getInstance().KAFKA_PERFORM_TOPIC, QString(QJsonDocument(performArray).toJson(QJsonDocument::Compact))); } QLogUtil::writeChannelDataLogByDate(date, msgLogFilename, QString(QJsonDocument(messageArray).toJson(QJsonDocument::Compact))); + QLogUtil::writeChannelDataLogByDate(date, perfLogFilename, QString(QJsonDocument(performArray).toJson(QJsonDocument::Compact))); // 4. 在界面上简单显示相差数据结果 emit this->sendDataToDraw(phaseData); + + // send signal to calculate allen and produce message to kafka + emit calculateAllen(); +} + +void PhaseDevice::onCalculateAllen() +{ + // 不同维度的稳定度数据 1s - 10000s + for (int i = 0; i < phaseVector.size(); i++) + { + QStringList result; + int size = phaseVector[i].size(); + for (int j = 0; j < 5; j++) + { + if (size >= 5 * pow(10, j)) { + channelAllen[i][j] = calAllan(i, pow(10, j), size); + } else { + channelAllen[i][j] = 0.0; + } + + result << QString::number(channelAllen[i][j], 'e', 4) << QString::number((int)(size / pow(10, j))); + } + + channelAllenResultStr[i] = result; +// qDebug() << result; + } + + emit this->sendAllenToDraw(devCode, channelAllenResultStr); +/* + // 分别计算不同时间维度的稳定度 + int size = phaseVector[i - 1].size(); + if(size >= 5) allen[0] = calAllan(i - 1, 1, size); else allen[0] = 0; + if(size >= 50) allen[1] = calAllan(i - 1, 10, size); else allen[1] = 0; + if(size >= 500) allen[2] = calAllan(i - 1, 100, size); else allen[2] = 0; + if(size >= 5000) allen[3] = calAllan(i - 1, 1000, size); else allen[3] = 0; + if(size >= 50000) allen[4] = calAllan(i - 1, 10000, size); else allen[4] = 0; + + // mock perform data + QJsonObject performData; + performData.insert("channelNo", i); + performData.insert("ts", (phaseData->milisecond / 1000) * 1000); + performData.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + performData.insert("master", SettingConfig::getInstance().MASTER); + performData.insert("deviceId", deviceId); + QJsonArray dataArr; + for (int k = 0; k < 5; k++) { + QJsonObject dataObj; + dataObj.insert("tau", QString::number(qPow(10, k))); + dataObj.insert("allen", QString::number(allen[k], 'e', 4)); + dataObj.insert("count", QString::number((int)(size / qPow(10, k)))); + dataArr.append(dataObj); + + QStringList allenStrList; + allenStrList << QString::number(qPow(10, k)) << QString::number(allen[k], 'e', 4) << QString::number((int)(size / qPow(10, k))); + phaseData->allenDataStr.append(allenStrList); + } + performData.insert("data", dataArr); + performArray.append(performData); + */ +} + +double PhaseDevice::calAllan(int index, int d, int aN) +{ + int i = 0; + double tau0 = 1; //tau0是基本采样间隔,由计数器或比相仪的最小采样间隔决定,最小为1s + double allan[2] = {0.0}; + double *y = new double[3]; + double tau_2 = pow(d * tau0, 2); //pow是计算x的y次幂 + + int logd = log10(d); + + double sum = channelAllenSigma[index][logd]; + + for (int j = 3; j > 0; j--) + { + i = aN - 2*d - j; + double v2 = phaseVector[index][i+2*d]; + double v1 = phaseVector[index][i+d]; + double v0 = phaseVector[index][i]; + y[3 - j] = pow(v2 - 2 * v1 + v0, 2); + + sum += y[3 - j]; + } + + channelAllenSigma[index][logd] += y[0]; + + allan[0] = sum/(2*tau_2*(aN-2*d)); //delta的平方 + allan[1] = sqrt(sum/(2*tau_2*(aN-2*d))); //delta + + delete[] y; + + return allan[1]; } diff --git a/PhaseCompAcq/PhaseDevice.h b/PhaseCompAcq/PhaseDevice.h index 887ed10..13b7c2d 100644 --- a/PhaseCompAcq/PhaseDevice.h +++ b/PhaseCompAcq/PhaseDevice.h @@ -2,6 +2,8 @@ #define PHASEDEVICE_H #include +#include +#include #include "common/utils/QSerialPortUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" @@ -38,11 +40,29 @@ QKafkaUtil kafkaUtil; QByteArray dataBuff; + // 原始数据 - 补偿之前的值 + QVector> phaseVector; + + // 不同维度的稳定度数据 1s - 10000s + QVector> channelAllen; + + // 计算过程中的累计和 + QVector> channelAllenSigma; + + // 各个通道的allen方差结果 + QVector channelAllenResultStr; + + // 计算allen方差 + double calAllan(int index, int d, int aN); + signals: void sendDataToDraw(PhaseDataDto * phaseData); + void calculateAllen(); + void sendAllenToDraw(QString devCode, QVector channelAllenResultStr); public slots: void dataReceivedHandler(QByteArray data); + void onCalculateAllen(); }; diff --git a/PhaseCompAcq/PhaseWindow.cpp b/PhaseCompAcq/PhaseWindow.cpp index 514b271..a082818 100644 --- a/PhaseCompAcq/PhaseWindow.cpp +++ b/PhaseCompAcq/PhaseWindow.cpp @@ -72,8 +72,8 @@ device->setDevCode(devItem.find("deviceNo")->toString()); device->setDeviceId(devItem.find("deviceId")->toString()); - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); + connect(device, &PhaseDevice::sendDataToDraw, this, &PhaseWindow::drawPhaseDataOnPage); + connect(device, &PhaseDevice::sendAllenToDraw, this, &PhaseWindow::drawPhaseAllenOnPage); device->initSerialPort(); @@ -111,6 +111,8 @@ return; } + ui->labTm->setText(phaseData->timestamp.left(19)); + // 更新所有通道BOX的值 for (int i = 0; i < phaseData->channelActive.size(); i++) { @@ -118,13 +120,49 @@ QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); // 赋值,对应的lineEdit/label - ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); - ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); - ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); - ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + ((QLabel *)channelBox->children().at(1))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); // 有效性 + ((QLabel *)channelBox->children().at(2))->setText(phaseData->frameId); // 数据ID + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); // 测量数据值 } } +void PhaseWindow::drawPhaseAllenOnPage(QString devCode, QVector channelAllenResultStr) +{ + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 + if (devCode != currentDevCode) + { + return; + } + + // 更新所有通道BOX的值 + for (int i = 0; i < channelAllenResultStr.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的label + ((QLabel *)channelBox->children().at(7))->setText(channelAllenResultStr.at(i).at(0)); // tau=1 Allen + ((QLabel *)channelBox->children().at(8))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(1))); // tau=1 Count + + ((QLabel *)channelBox->children().at(10))->setText(channelAllenResultStr.at(i).at(2)); // tau=10 Allen + ((QLabel *)channelBox->children().at(11))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(3))); // tau=10 Count + + ((QLabel *)channelBox->children().at(13))->setText(channelAllenResultStr.at(i).at(4)); // tau=100 Allen + ((QLabel *)channelBox->children().at(14))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(5))); // tau=100 Count + + ((QLabel *)channelBox->children().at(16))->setText(channelAllenResultStr.at(i).at(6)); // tau=1000 Allen + ((QLabel *)channelBox->children().at(17))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(7))); // tau=1000 Count + + ((QLabel *)channelBox->children().at(19))->setText(channelAllenResultStr.at(i).at(8)); // tau=10000 Allen + ((QLabel *)channelBox->children().at(20))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(9))); // tau=10000 Count + } + +// qDebug() << channelAllenResultStr; +} + void PhaseWindow::generateWidgetForDevice() { // 获取设备数据 @@ -146,42 +184,124 @@ QHBoxLayout * vbox = new QHBoxLayout(group); - QLabel * tmLabel = new QLabel(); - tmLabel->setText("时间"); - tmLabel->setFont(labelFont); - tmLabel->setStyleSheet("margin-left:20;"); - vbox->addWidget(tmLabel); - QLineEdit * tmValue = new QLineEdit(); - tmValue->setFixedWidth(200); - tmValue->setFont(labelFont); - vbox->addWidget(tmValue); - - QLabel * dataLabel = new QLabel(); - dataLabel->setText("测量数据"); - dataLabel->setFont(labelFont); - dataLabel->setStyleSheet("margin-left:20;"); - vbox->addWidget(dataLabel); - QLineEdit * dataValue = new QLineEdit(); - dataValue->setFixedWidth(250); - dataValue->setFont(labelFont); - vbox->addWidget(dataValue); - - QLabel * idLabel = new QLabel(); - idLabel->setText("数据ID"); - idLabel->setFont(labelFont); - idLabel->setStyleSheet("margin-left:20;"); - vbox->addWidget(idLabel); - QLineEdit * idValue = new QLineEdit(); - idValue->setFixedWidth(100); - idValue->setFont(labelFont); - vbox->addWidget(idValue); - + // index = 1 QLabel * validLabel = new QLabel(); validLabel->setText("-"); validLabel->setFont(labelFont); validLabel->setStyleSheet("margin-left:20;"); vbox->addWidget(validLabel); + // index = 2 + QLabel * idLabel = new QLabel(); + idLabel->setText("0000"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + + // index = 3 + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + // index = 4 + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(200); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + // index = 5 + QLabel * perfLabel = new QLabel(); + perfLabel->setText("稳定度"); + perfLabel->setFont(labelFont); + perfLabel->setStyleSheet("margin-left:50;"); + vbox->addWidget(perfLabel); + + // index = 6 + QLabel * oneLabel = new QLabel(); + oneLabel->setText("Tau(s)=1"); + oneLabel->setFont(labelFont); + oneLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(oneLabel); + // index = 7 + QLabel * oneAllen = new QLabel(); + oneAllen->setText("0.00"); + oneAllen->setFont(labelFont); + vbox->addWidget(oneAllen); + // index = 8 + QLabel * oneCount = new QLabel(); + oneCount->setText("0"); + oneCount->setFont(labelFont); + vbox->addWidget(oneCount); + + // index = 9 + QLabel * tenLabel = new QLabel(); + tenLabel->setText("Tau(s)=10"); + tenLabel->setFont(labelFont); + tenLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tenLabel); + // index = 10 + QLabel * tenAllen = new QLabel(); + tenAllen->setText("0.00"); + tenAllen->setFont(labelFont); + vbox->addWidget(tenAllen); + // index = 11 + QLabel * tenCount = new QLabel(); + tenCount->setText("0"); + tenCount->setFont(labelFont); + vbox->addWidget(tenCount); + + // index = 12 + QLabel * hundLabel = new QLabel(); + hundLabel->setText("Tau(s)=100"); + hundLabel->setFont(labelFont); + hundLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(hundLabel); + // index = 13 + QLabel * hundAllen = new QLabel(); + hundAllen->setText("0.00"); + hundAllen->setFont(labelFont); + vbox->addWidget(hundAllen); + // index = 14 + QLabel * hundCount = new QLabel(); + hundCount->setText("0"); + hundCount->setFont(labelFont); + vbox->addWidget(hundCount); + + // index = 15 + QLabel * thouLabel = new QLabel(); + thouLabel->setText("Tau(s)=1000"); + thouLabel->setFont(labelFont); + thouLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(thouLabel); + // index = 16 + QLabel * thouAllen = new QLabel(); + thouAllen->setText("0.00"); + thouAllen->setFont(labelFont); + vbox->addWidget(thouAllen); + // index = 17 + QLabel * thouCount = new QLabel(); + thouCount->setText("0"); + thouCount->setFont(labelFont); + vbox->addWidget(thouCount); + + // index = 18 + QLabel * ttLabel = new QLabel(); + ttLabel->setText("Tau(s)=10000"); + ttLabel->setFont(labelFont); + ttLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(ttLabel); + // index = 19 + QLabel * ttAllen = new QLabel(); + ttAllen->setText("0.00"); + ttAllen->setFont(labelFont); + vbox->addWidget(ttAllen); + // index = 20 + QLabel * ttCount = new QLabel(); + ttCount->setText("0"); + ttCount->setFont(labelFont); + vbox->addWidget(ttCount); + QSpacerItem * hSpace = new QSpacerItem(20, 20); hSpace->changeSize(20, 20, QSizePolicy::Expanding); vbox->addItem(hSpace); @@ -247,9 +367,23 @@ QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); // 赋值,对应的lineEdit/label - ((QLineEdit *)channelBox->children().at(2))->setText(""); - ((QLineEdit *)channelBox->children().at(4))->setText(""); - ((QLineEdit *)channelBox->children().at(6))->setText(""); - ((QLabel *)channelBox->children().at(7))->setText("-"); + ((QLabel *)channelBox->children().at(1))->setText("-"); // 有效性 + ((QLabel *)channelBox->children().at(2))->setText("0000"); // 数据ID + ((QLineEdit *)channelBox->children().at(4))->setText(""); // 测量数据值 + + ((QLabel *)channelBox->children().at(7))->setText("0.00"); // tau=1 Allen + ((QLabel *)channelBox->children().at(8))->setText(QString("采样数(%1)").arg(0)); // tau=1 Count + + ((QLabel *)channelBox->children().at(10))->setText("0.00"); // tau=10 Allen + ((QLabel *)channelBox->children().at(11))->setText(QString("采样数(%1)").arg(0)); // tau=10 Count + + ((QLabel *)channelBox->children().at(13))->setText("0.00"); // tau=100 Allen + ((QLabel *)channelBox->children().at(14))->setText(QString("采样数(%1)").arg(0)); // tau=100 Count + + ((QLabel *)channelBox->children().at(16))->setText("0.00"); // tau=1000 Allen + ((QLabel *)channelBox->children().at(17))->setText(QString("采样数(%1)").arg(0)); // tau=1000 Count + + ((QLabel *)channelBox->children().at(19))->setText("0.00"); // tau=10000 Allen + ((QLabel *)channelBox->children().at(20))->setText(QString("采样数(%1)").arg(0)); // tau=10000 Count } } diff --git a/PhaseCompAcq/PhaseWindow.h b/PhaseCompAcq/PhaseWindow.h index bf1cb57..572bbde 100644 --- a/PhaseCompAcq/PhaseWindow.h +++ b/PhaseCompAcq/PhaseWindow.h @@ -25,6 +25,7 @@ public slots: void drawPhaseDataOnPage(PhaseDataDto * phaseData); + void drawPhaseAllenOnPage(QString devCode, QVector channelAllenResultStr); private slots: void on_minButt_clicked(); diff --git a/PhaseCompAcq/PhaseWindow.ui b/PhaseCompAcq/PhaseWindow.ui index 2df6062..d083fb9 100644 --- a/PhaseCompAcq/PhaseWindow.ui +++ b/PhaseCompAcq/PhaseWindow.ui @@ -182,6 +182,25 @@ 开始 + + + + 750 + 10 + 200 + 40 + + + + + 微软雅黑 + 12 + + + + + + diff --git a/PhaseCompAcq/PhaseCompAcq.pro b/PhaseCompAcq/PhaseCompAcq.pro index ebb2309..f51a158 100644 --- a/PhaseCompAcq/PhaseCompAcq.pro +++ b/PhaseCompAcq/PhaseCompAcq.pro @@ -4,8 +4,7 @@ CONFIG += c++11 -FORMS += \ - PhaseWindow.ui +FORMS += PhaseWindow.ui include(common/common.pri) include(protocol/protocol.pri) diff --git a/PhaseCompAcq/PhaseDevice.cpp b/PhaseCompAcq/PhaseDevice.cpp index c5466bb..b5be574 100644 --- a/PhaseCompAcq/PhaseDevice.cpp +++ b/PhaseCompAcq/PhaseDevice.cpp @@ -3,6 +3,8 @@ #include #include #include +#include +#include PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) { @@ -14,6 +16,20 @@ kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); kafkaUtil.createProducer(); } + + QVector> initPhase(PHASE_MESSURE_CHANNEL, QVector(0, 0)); + phaseVector = initPhase; + + QVector> initAllen(PHASE_MESSURE_CHANNEL, QVector(5, 0)); + channelAllen = initAllen; + + QVector> initSigma(PHASE_MESSURE_CHANNEL, QVector(5, 0)); + channelAllenSigma = initSigma; + + QVector initResult(PHASE_MESSURE_CHANNEL); + channelAllenResultStr = initResult; + + connect(this, &PhaseDevice::calculateAllen, this, &PhaseDevice::onCalculateAllen); } PhaseDevice::~PhaseDevice() @@ -134,23 +150,19 @@ QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); QLogUtil::writeRawDataLogByDate(date, filename, content); + // 发送到消息队列里的内容 QJsonArray messageArray; + QJsonArray performArray; QString msgLogFilename = "msg_" + devCode + ".log"; + QString perfLogFilename = "perf_" + devCode + ".log"; // 2.2 各个通道的相差数据 for (int i = 1; i <= phaseData->channelActive.size(); i++) { if (phaseData->channelActive.at(i-1).toUInt() == 1) { - QString chFilename("%1_CH_%2.log"); - chFilename = chFilename.arg(devCode); - if (i < 10) - { - chFilename = chFilename.arg(QString("0%1").arg(i)); - } else - { - chFilename = chFilename.arg(i); - } + // 存日志 + QString chFilename = QString("%1_CH_%2.log").arg(devCode).arg(i, 2, 10, QLatin1Char('0')); QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); @@ -160,6 +172,15 @@ jsonObj.insert("master", SettingConfig::getInstance().MASTER); jsonObj.insert("deviceId", deviceId); messageArray.append(jsonObj); + + // 将相位数据存入数据栈, 用于计算allen方差 + QMutex mutex; + mutex.lock(); + phaseVector[i - 1].append(phaseData->channelData.at(i - 1)); + if (phaseVector[i - 1].size() > SettingConfig::getInstance().MAX_DATA_SIZE) { + phaseVector[i - 1] = phaseVector[i - 1].mid(phaseVector[i - 1].size() - SettingConfig::getInstance().MAX_DATA_SIZE); + } + mutex.unlock(); } } @@ -177,10 +198,107 @@ if (QDateTime::currentDateTime().time().second() % 10 == 0) { kafkaUtil.produceMessage(SettingConfig::getInstance().KAFKA_STATUS_TOPIC, QString(QJsonDocument(statusObj).toJson(QJsonDocument::Compact))); } + + // 模拟发送稳定度计算结果 + // 1s 10s 100s 1000s 10000s + kafkaUtil.produceMessage(SettingConfig::getInstance().KAFKA_PERFORM_TOPIC, QString(QJsonDocument(performArray).toJson(QJsonDocument::Compact))); } QLogUtil::writeChannelDataLogByDate(date, msgLogFilename, QString(QJsonDocument(messageArray).toJson(QJsonDocument::Compact))); + QLogUtil::writeChannelDataLogByDate(date, perfLogFilename, QString(QJsonDocument(performArray).toJson(QJsonDocument::Compact))); // 4. 在界面上简单显示相差数据结果 emit this->sendDataToDraw(phaseData); + + // send signal to calculate allen and produce message to kafka + emit calculateAllen(); +} + +void PhaseDevice::onCalculateAllen() +{ + // 不同维度的稳定度数据 1s - 10000s + for (int i = 0; i < phaseVector.size(); i++) + { + QStringList result; + int size = phaseVector[i].size(); + for (int j = 0; j < 5; j++) + { + if (size >= 5 * pow(10, j)) { + channelAllen[i][j] = calAllan(i, pow(10, j), size); + } else { + channelAllen[i][j] = 0.0; + } + + result << QString::number(channelAllen[i][j], 'e', 4) << QString::number((int)(size / pow(10, j))); + } + + channelAllenResultStr[i] = result; +// qDebug() << result; + } + + emit this->sendAllenToDraw(devCode, channelAllenResultStr); +/* + // 分别计算不同时间维度的稳定度 + int size = phaseVector[i - 1].size(); + if(size >= 5) allen[0] = calAllan(i - 1, 1, size); else allen[0] = 0; + if(size >= 50) allen[1] = calAllan(i - 1, 10, size); else allen[1] = 0; + if(size >= 500) allen[2] = calAllan(i - 1, 100, size); else allen[2] = 0; + if(size >= 5000) allen[3] = calAllan(i - 1, 1000, size); else allen[3] = 0; + if(size >= 50000) allen[4] = calAllan(i - 1, 10000, size); else allen[4] = 0; + + // mock perform data + QJsonObject performData; + performData.insert("channelNo", i); + performData.insert("ts", (phaseData->milisecond / 1000) * 1000); + performData.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + performData.insert("master", SettingConfig::getInstance().MASTER); + performData.insert("deviceId", deviceId); + QJsonArray dataArr; + for (int k = 0; k < 5; k++) { + QJsonObject dataObj; + dataObj.insert("tau", QString::number(qPow(10, k))); + dataObj.insert("allen", QString::number(allen[k], 'e', 4)); + dataObj.insert("count", QString::number((int)(size / qPow(10, k)))); + dataArr.append(dataObj); + + QStringList allenStrList; + allenStrList << QString::number(qPow(10, k)) << QString::number(allen[k], 'e', 4) << QString::number((int)(size / qPow(10, k))); + phaseData->allenDataStr.append(allenStrList); + } + performData.insert("data", dataArr); + performArray.append(performData); + */ +} + +double PhaseDevice::calAllan(int index, int d, int aN) +{ + int i = 0; + double tau0 = 1; //tau0是基本采样间隔,由计数器或比相仪的最小采样间隔决定,最小为1s + double allan[2] = {0.0}; + double *y = new double[3]; + double tau_2 = pow(d * tau0, 2); //pow是计算x的y次幂 + + int logd = log10(d); + + double sum = channelAllenSigma[index][logd]; + + for (int j = 3; j > 0; j--) + { + i = aN - 2*d - j; + double v2 = phaseVector[index][i+2*d]; + double v1 = phaseVector[index][i+d]; + double v0 = phaseVector[index][i]; + y[3 - j] = pow(v2 - 2 * v1 + v0, 2); + + sum += y[3 - j]; + } + + channelAllenSigma[index][logd] += y[0]; + + allan[0] = sum/(2*tau_2*(aN-2*d)); //delta的平方 + allan[1] = sqrt(sum/(2*tau_2*(aN-2*d))); //delta + + delete[] y; + + return allan[1]; } diff --git a/PhaseCompAcq/PhaseDevice.h b/PhaseCompAcq/PhaseDevice.h index 887ed10..13b7c2d 100644 --- a/PhaseCompAcq/PhaseDevice.h +++ b/PhaseCompAcq/PhaseDevice.h @@ -2,6 +2,8 @@ #define PHASEDEVICE_H #include +#include +#include #include "common/utils/QSerialPortUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" @@ -38,11 +40,29 @@ QKafkaUtil kafkaUtil; QByteArray dataBuff; + // 原始数据 - 补偿之前的值 + QVector> phaseVector; + + // 不同维度的稳定度数据 1s - 10000s + QVector> channelAllen; + + // 计算过程中的累计和 + QVector> channelAllenSigma; + + // 各个通道的allen方差结果 + QVector channelAllenResultStr; + + // 计算allen方差 + double calAllan(int index, int d, int aN); + signals: void sendDataToDraw(PhaseDataDto * phaseData); + void calculateAllen(); + void sendAllenToDraw(QString devCode, QVector channelAllenResultStr); public slots: void dataReceivedHandler(QByteArray data); + void onCalculateAllen(); }; diff --git a/PhaseCompAcq/PhaseWindow.cpp b/PhaseCompAcq/PhaseWindow.cpp index 514b271..a082818 100644 --- a/PhaseCompAcq/PhaseWindow.cpp +++ b/PhaseCompAcq/PhaseWindow.cpp @@ -72,8 +72,8 @@ device->setDevCode(devItem.find("deviceNo")->toString()); device->setDeviceId(devItem.find("deviceId")->toString()); - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); + connect(device, &PhaseDevice::sendDataToDraw, this, &PhaseWindow::drawPhaseDataOnPage); + connect(device, &PhaseDevice::sendAllenToDraw, this, &PhaseWindow::drawPhaseAllenOnPage); device->initSerialPort(); @@ -111,6 +111,8 @@ return; } + ui->labTm->setText(phaseData->timestamp.left(19)); + // 更新所有通道BOX的值 for (int i = 0; i < phaseData->channelActive.size(); i++) { @@ -118,13 +120,49 @@ QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); // 赋值,对应的lineEdit/label - ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); - ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); - ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); - ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + ((QLabel *)channelBox->children().at(1))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); // 有效性 + ((QLabel *)channelBox->children().at(2))->setText(phaseData->frameId); // 数据ID + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); // 测量数据值 } } +void PhaseWindow::drawPhaseAllenOnPage(QString devCode, QVector channelAllenResultStr) +{ + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 + if (devCode != currentDevCode) + { + return; + } + + // 更新所有通道BOX的值 + for (int i = 0; i < channelAllenResultStr.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的label + ((QLabel *)channelBox->children().at(7))->setText(channelAllenResultStr.at(i).at(0)); // tau=1 Allen + ((QLabel *)channelBox->children().at(8))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(1))); // tau=1 Count + + ((QLabel *)channelBox->children().at(10))->setText(channelAllenResultStr.at(i).at(2)); // tau=10 Allen + ((QLabel *)channelBox->children().at(11))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(3))); // tau=10 Count + + ((QLabel *)channelBox->children().at(13))->setText(channelAllenResultStr.at(i).at(4)); // tau=100 Allen + ((QLabel *)channelBox->children().at(14))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(5))); // tau=100 Count + + ((QLabel *)channelBox->children().at(16))->setText(channelAllenResultStr.at(i).at(6)); // tau=1000 Allen + ((QLabel *)channelBox->children().at(17))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(7))); // tau=1000 Count + + ((QLabel *)channelBox->children().at(19))->setText(channelAllenResultStr.at(i).at(8)); // tau=10000 Allen + ((QLabel *)channelBox->children().at(20))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(9))); // tau=10000 Count + } + +// qDebug() << channelAllenResultStr; +} + void PhaseWindow::generateWidgetForDevice() { // 获取设备数据 @@ -146,42 +184,124 @@ QHBoxLayout * vbox = new QHBoxLayout(group); - QLabel * tmLabel = new QLabel(); - tmLabel->setText("时间"); - tmLabel->setFont(labelFont); - tmLabel->setStyleSheet("margin-left:20;"); - vbox->addWidget(tmLabel); - QLineEdit * tmValue = new QLineEdit(); - tmValue->setFixedWidth(200); - tmValue->setFont(labelFont); - vbox->addWidget(tmValue); - - QLabel * dataLabel = new QLabel(); - dataLabel->setText("测量数据"); - dataLabel->setFont(labelFont); - dataLabel->setStyleSheet("margin-left:20;"); - vbox->addWidget(dataLabel); - QLineEdit * dataValue = new QLineEdit(); - dataValue->setFixedWidth(250); - dataValue->setFont(labelFont); - vbox->addWidget(dataValue); - - QLabel * idLabel = new QLabel(); - idLabel->setText("数据ID"); - idLabel->setFont(labelFont); - idLabel->setStyleSheet("margin-left:20;"); - vbox->addWidget(idLabel); - QLineEdit * idValue = new QLineEdit(); - idValue->setFixedWidth(100); - idValue->setFont(labelFont); - vbox->addWidget(idValue); - + // index = 1 QLabel * validLabel = new QLabel(); validLabel->setText("-"); validLabel->setFont(labelFont); validLabel->setStyleSheet("margin-left:20;"); vbox->addWidget(validLabel); + // index = 2 + QLabel * idLabel = new QLabel(); + idLabel->setText("0000"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + + // index = 3 + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + // index = 4 + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(200); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + // index = 5 + QLabel * perfLabel = new QLabel(); + perfLabel->setText("稳定度"); + perfLabel->setFont(labelFont); + perfLabel->setStyleSheet("margin-left:50;"); + vbox->addWidget(perfLabel); + + // index = 6 + QLabel * oneLabel = new QLabel(); + oneLabel->setText("Tau(s)=1"); + oneLabel->setFont(labelFont); + oneLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(oneLabel); + // index = 7 + QLabel * oneAllen = new QLabel(); + oneAllen->setText("0.00"); + oneAllen->setFont(labelFont); + vbox->addWidget(oneAllen); + // index = 8 + QLabel * oneCount = new QLabel(); + oneCount->setText("0"); + oneCount->setFont(labelFont); + vbox->addWidget(oneCount); + + // index = 9 + QLabel * tenLabel = new QLabel(); + tenLabel->setText("Tau(s)=10"); + tenLabel->setFont(labelFont); + tenLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tenLabel); + // index = 10 + QLabel * tenAllen = new QLabel(); + tenAllen->setText("0.00"); + tenAllen->setFont(labelFont); + vbox->addWidget(tenAllen); + // index = 11 + QLabel * tenCount = new QLabel(); + tenCount->setText("0"); + tenCount->setFont(labelFont); + vbox->addWidget(tenCount); + + // index = 12 + QLabel * hundLabel = new QLabel(); + hundLabel->setText("Tau(s)=100"); + hundLabel->setFont(labelFont); + hundLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(hundLabel); + // index = 13 + QLabel * hundAllen = new QLabel(); + hundAllen->setText("0.00"); + hundAllen->setFont(labelFont); + vbox->addWidget(hundAllen); + // index = 14 + QLabel * hundCount = new QLabel(); + hundCount->setText("0"); + hundCount->setFont(labelFont); + vbox->addWidget(hundCount); + + // index = 15 + QLabel * thouLabel = new QLabel(); + thouLabel->setText("Tau(s)=1000"); + thouLabel->setFont(labelFont); + thouLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(thouLabel); + // index = 16 + QLabel * thouAllen = new QLabel(); + thouAllen->setText("0.00"); + thouAllen->setFont(labelFont); + vbox->addWidget(thouAllen); + // index = 17 + QLabel * thouCount = new QLabel(); + thouCount->setText("0"); + thouCount->setFont(labelFont); + vbox->addWidget(thouCount); + + // index = 18 + QLabel * ttLabel = new QLabel(); + ttLabel->setText("Tau(s)=10000"); + ttLabel->setFont(labelFont); + ttLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(ttLabel); + // index = 19 + QLabel * ttAllen = new QLabel(); + ttAllen->setText("0.00"); + ttAllen->setFont(labelFont); + vbox->addWidget(ttAllen); + // index = 20 + QLabel * ttCount = new QLabel(); + ttCount->setText("0"); + ttCount->setFont(labelFont); + vbox->addWidget(ttCount); + QSpacerItem * hSpace = new QSpacerItem(20, 20); hSpace->changeSize(20, 20, QSizePolicy::Expanding); vbox->addItem(hSpace); @@ -247,9 +367,23 @@ QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); // 赋值,对应的lineEdit/label - ((QLineEdit *)channelBox->children().at(2))->setText(""); - ((QLineEdit *)channelBox->children().at(4))->setText(""); - ((QLineEdit *)channelBox->children().at(6))->setText(""); - ((QLabel *)channelBox->children().at(7))->setText("-"); + ((QLabel *)channelBox->children().at(1))->setText("-"); // 有效性 + ((QLabel *)channelBox->children().at(2))->setText("0000"); // 数据ID + ((QLineEdit *)channelBox->children().at(4))->setText(""); // 测量数据值 + + ((QLabel *)channelBox->children().at(7))->setText("0.00"); // tau=1 Allen + ((QLabel *)channelBox->children().at(8))->setText(QString("采样数(%1)").arg(0)); // tau=1 Count + + ((QLabel *)channelBox->children().at(10))->setText("0.00"); // tau=10 Allen + ((QLabel *)channelBox->children().at(11))->setText(QString("采样数(%1)").arg(0)); // tau=10 Count + + ((QLabel *)channelBox->children().at(13))->setText("0.00"); // tau=100 Allen + ((QLabel *)channelBox->children().at(14))->setText(QString("采样数(%1)").arg(0)); // tau=100 Count + + ((QLabel *)channelBox->children().at(16))->setText("0.00"); // tau=1000 Allen + ((QLabel *)channelBox->children().at(17))->setText(QString("采样数(%1)").arg(0)); // tau=1000 Count + + ((QLabel *)channelBox->children().at(19))->setText("0.00"); // tau=10000 Allen + ((QLabel *)channelBox->children().at(20))->setText(QString("采样数(%1)").arg(0)); // tau=10000 Count } } diff --git a/PhaseCompAcq/PhaseWindow.h b/PhaseCompAcq/PhaseWindow.h index bf1cb57..572bbde 100644 --- a/PhaseCompAcq/PhaseWindow.h +++ b/PhaseCompAcq/PhaseWindow.h @@ -25,6 +25,7 @@ public slots: void drawPhaseDataOnPage(PhaseDataDto * phaseData); + void drawPhaseAllenOnPage(QString devCode, QVector channelAllenResultStr); private slots: void on_minButt_clicked(); diff --git a/PhaseCompAcq/PhaseWindow.ui b/PhaseCompAcq/PhaseWindow.ui index 2df6062..d083fb9 100644 --- a/PhaseCompAcq/PhaseWindow.ui +++ b/PhaseCompAcq/PhaseWindow.ui @@ -182,6 +182,25 @@ 开始 + + + + 750 + 10 + 200 + 40 + + + + + 微软雅黑 + 12 + + + + + + diff --git a/PhaseCompAcq/common/utils/SettingConfig.cpp b/PhaseCompAcq/common/utils/SettingConfig.cpp index 727c841..ed02ac1 100644 --- a/PhaseCompAcq/common/utils/SettingConfig.cpp +++ b/PhaseCompAcq/common/utils/SettingConfig.cpp @@ -11,6 +11,7 @@ KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); KAFKA_STATUS_TOPIC = getProperty("kafka", "statusTopic").toString(); + KAFKA_PERFORM_TOPIC = getProperty("kafka", "performTopic").toString(); NEED_SASL = getProperty("kafka", "needSasl").toInt(); SASL_USERNAME = getProperty("kafka", "saslUsername").toString(); SASL_PASSWORD = getProperty("kafka", "saslPassword").toString(); @@ -22,8 +23,7 @@ WORK_TYPE = getProperty("client", "workMode").toString(); MASTER = getProperty("client", "master").toInt(); SERVER_PORT = getProperty("client", "serverPort").toInt(); - AUTO_STOP_TIME = getProperty("client", "autoStopTime").toInt(); - AUTO_START_TIME = getProperty("client", "autoStartTime").toInt(); + MAX_DATA_SIZE = getProperty("client", "maxDataSize").toUInt(); BASE_URL = getProperty("http", "baseUrl").toString(); diff --git a/PhaseCompAcq/PhaseCompAcq.pro b/PhaseCompAcq/PhaseCompAcq.pro index ebb2309..f51a158 100644 --- a/PhaseCompAcq/PhaseCompAcq.pro +++ b/PhaseCompAcq/PhaseCompAcq.pro @@ -4,8 +4,7 @@ CONFIG += c++11 -FORMS += \ - PhaseWindow.ui +FORMS += PhaseWindow.ui include(common/common.pri) include(protocol/protocol.pri) diff --git a/PhaseCompAcq/PhaseDevice.cpp b/PhaseCompAcq/PhaseDevice.cpp index c5466bb..b5be574 100644 --- a/PhaseCompAcq/PhaseDevice.cpp +++ b/PhaseCompAcq/PhaseDevice.cpp @@ -3,6 +3,8 @@ #include #include #include +#include +#include PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) { @@ -14,6 +16,20 @@ kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); kafkaUtil.createProducer(); } + + QVector> initPhase(PHASE_MESSURE_CHANNEL, QVector(0, 0)); + phaseVector = initPhase; + + QVector> initAllen(PHASE_MESSURE_CHANNEL, QVector(5, 0)); + channelAllen = initAllen; + + QVector> initSigma(PHASE_MESSURE_CHANNEL, QVector(5, 0)); + channelAllenSigma = initSigma; + + QVector initResult(PHASE_MESSURE_CHANNEL); + channelAllenResultStr = initResult; + + connect(this, &PhaseDevice::calculateAllen, this, &PhaseDevice::onCalculateAllen); } PhaseDevice::~PhaseDevice() @@ -134,23 +150,19 @@ QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); QLogUtil::writeRawDataLogByDate(date, filename, content); + // 发送到消息队列里的内容 QJsonArray messageArray; + QJsonArray performArray; QString msgLogFilename = "msg_" + devCode + ".log"; + QString perfLogFilename = "perf_" + devCode + ".log"; // 2.2 各个通道的相差数据 for (int i = 1; i <= phaseData->channelActive.size(); i++) { if (phaseData->channelActive.at(i-1).toUInt() == 1) { - QString chFilename("%1_CH_%2.log"); - chFilename = chFilename.arg(devCode); - if (i < 10) - { - chFilename = chFilename.arg(QString("0%1").arg(i)); - } else - { - chFilename = chFilename.arg(i); - } + // 存日志 + QString chFilename = QString("%1_CH_%2.log").arg(devCode).arg(i, 2, 10, QLatin1Char('0')); QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); @@ -160,6 +172,15 @@ jsonObj.insert("master", SettingConfig::getInstance().MASTER); jsonObj.insert("deviceId", deviceId); messageArray.append(jsonObj); + + // 将相位数据存入数据栈, 用于计算allen方差 + QMutex mutex; + mutex.lock(); + phaseVector[i - 1].append(phaseData->channelData.at(i - 1)); + if (phaseVector[i - 1].size() > SettingConfig::getInstance().MAX_DATA_SIZE) { + phaseVector[i - 1] = phaseVector[i - 1].mid(phaseVector[i - 1].size() - SettingConfig::getInstance().MAX_DATA_SIZE); + } + mutex.unlock(); } } @@ -177,10 +198,107 @@ if (QDateTime::currentDateTime().time().second() % 10 == 0) { kafkaUtil.produceMessage(SettingConfig::getInstance().KAFKA_STATUS_TOPIC, QString(QJsonDocument(statusObj).toJson(QJsonDocument::Compact))); } + + // 模拟发送稳定度计算结果 + // 1s 10s 100s 1000s 10000s + kafkaUtil.produceMessage(SettingConfig::getInstance().KAFKA_PERFORM_TOPIC, QString(QJsonDocument(performArray).toJson(QJsonDocument::Compact))); } QLogUtil::writeChannelDataLogByDate(date, msgLogFilename, QString(QJsonDocument(messageArray).toJson(QJsonDocument::Compact))); + QLogUtil::writeChannelDataLogByDate(date, perfLogFilename, QString(QJsonDocument(performArray).toJson(QJsonDocument::Compact))); // 4. 在界面上简单显示相差数据结果 emit this->sendDataToDraw(phaseData); + + // send signal to calculate allen and produce message to kafka + emit calculateAllen(); +} + +void PhaseDevice::onCalculateAllen() +{ + // 不同维度的稳定度数据 1s - 10000s + for (int i = 0; i < phaseVector.size(); i++) + { + QStringList result; + int size = phaseVector[i].size(); + for (int j = 0; j < 5; j++) + { + if (size >= 5 * pow(10, j)) { + channelAllen[i][j] = calAllan(i, pow(10, j), size); + } else { + channelAllen[i][j] = 0.0; + } + + result << QString::number(channelAllen[i][j], 'e', 4) << QString::number((int)(size / pow(10, j))); + } + + channelAllenResultStr[i] = result; +// qDebug() << result; + } + + emit this->sendAllenToDraw(devCode, channelAllenResultStr); +/* + // 分别计算不同时间维度的稳定度 + int size = phaseVector[i - 1].size(); + if(size >= 5) allen[0] = calAllan(i - 1, 1, size); else allen[0] = 0; + if(size >= 50) allen[1] = calAllan(i - 1, 10, size); else allen[1] = 0; + if(size >= 500) allen[2] = calAllan(i - 1, 100, size); else allen[2] = 0; + if(size >= 5000) allen[3] = calAllan(i - 1, 1000, size); else allen[3] = 0; + if(size >= 50000) allen[4] = calAllan(i - 1, 10000, size); else allen[4] = 0; + + // mock perform data + QJsonObject performData; + performData.insert("channelNo", i); + performData.insert("ts", (phaseData->milisecond / 1000) * 1000); + performData.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + performData.insert("master", SettingConfig::getInstance().MASTER); + performData.insert("deviceId", deviceId); + QJsonArray dataArr; + for (int k = 0; k < 5; k++) { + QJsonObject dataObj; + dataObj.insert("tau", QString::number(qPow(10, k))); + dataObj.insert("allen", QString::number(allen[k], 'e', 4)); + dataObj.insert("count", QString::number((int)(size / qPow(10, k)))); + dataArr.append(dataObj); + + QStringList allenStrList; + allenStrList << QString::number(qPow(10, k)) << QString::number(allen[k], 'e', 4) << QString::number((int)(size / qPow(10, k))); + phaseData->allenDataStr.append(allenStrList); + } + performData.insert("data", dataArr); + performArray.append(performData); + */ +} + +double PhaseDevice::calAllan(int index, int d, int aN) +{ + int i = 0; + double tau0 = 1; //tau0是基本采样间隔,由计数器或比相仪的最小采样间隔决定,最小为1s + double allan[2] = {0.0}; + double *y = new double[3]; + double tau_2 = pow(d * tau0, 2); //pow是计算x的y次幂 + + int logd = log10(d); + + double sum = channelAllenSigma[index][logd]; + + for (int j = 3; j > 0; j--) + { + i = aN - 2*d - j; + double v2 = phaseVector[index][i+2*d]; + double v1 = phaseVector[index][i+d]; + double v0 = phaseVector[index][i]; + y[3 - j] = pow(v2 - 2 * v1 + v0, 2); + + sum += y[3 - j]; + } + + channelAllenSigma[index][logd] += y[0]; + + allan[0] = sum/(2*tau_2*(aN-2*d)); //delta的平方 + allan[1] = sqrt(sum/(2*tau_2*(aN-2*d))); //delta + + delete[] y; + + return allan[1]; } diff --git a/PhaseCompAcq/PhaseDevice.h b/PhaseCompAcq/PhaseDevice.h index 887ed10..13b7c2d 100644 --- a/PhaseCompAcq/PhaseDevice.h +++ b/PhaseCompAcq/PhaseDevice.h @@ -2,6 +2,8 @@ #define PHASEDEVICE_H #include +#include +#include #include "common/utils/QSerialPortUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" @@ -38,11 +40,29 @@ QKafkaUtil kafkaUtil; QByteArray dataBuff; + // 原始数据 - 补偿之前的值 + QVector> phaseVector; + + // 不同维度的稳定度数据 1s - 10000s + QVector> channelAllen; + + // 计算过程中的累计和 + QVector> channelAllenSigma; + + // 各个通道的allen方差结果 + QVector channelAllenResultStr; + + // 计算allen方差 + double calAllan(int index, int d, int aN); + signals: void sendDataToDraw(PhaseDataDto * phaseData); + void calculateAllen(); + void sendAllenToDraw(QString devCode, QVector channelAllenResultStr); public slots: void dataReceivedHandler(QByteArray data); + void onCalculateAllen(); }; diff --git a/PhaseCompAcq/PhaseWindow.cpp b/PhaseCompAcq/PhaseWindow.cpp index 514b271..a082818 100644 --- a/PhaseCompAcq/PhaseWindow.cpp +++ b/PhaseCompAcq/PhaseWindow.cpp @@ -72,8 +72,8 @@ device->setDevCode(devItem.find("deviceNo")->toString()); device->setDeviceId(devItem.find("deviceId")->toString()); - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); + connect(device, &PhaseDevice::sendDataToDraw, this, &PhaseWindow::drawPhaseDataOnPage); + connect(device, &PhaseDevice::sendAllenToDraw, this, &PhaseWindow::drawPhaseAllenOnPage); device->initSerialPort(); @@ -111,6 +111,8 @@ return; } + ui->labTm->setText(phaseData->timestamp.left(19)); + // 更新所有通道BOX的值 for (int i = 0; i < phaseData->channelActive.size(); i++) { @@ -118,13 +120,49 @@ QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); // 赋值,对应的lineEdit/label - ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); - ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); - ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); - ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + ((QLabel *)channelBox->children().at(1))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); // 有效性 + ((QLabel *)channelBox->children().at(2))->setText(phaseData->frameId); // 数据ID + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); // 测量数据值 } } +void PhaseWindow::drawPhaseAllenOnPage(QString devCode, QVector channelAllenResultStr) +{ + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 + if (devCode != currentDevCode) + { + return; + } + + // 更新所有通道BOX的值 + for (int i = 0; i < channelAllenResultStr.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的label + ((QLabel *)channelBox->children().at(7))->setText(channelAllenResultStr.at(i).at(0)); // tau=1 Allen + ((QLabel *)channelBox->children().at(8))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(1))); // tau=1 Count + + ((QLabel *)channelBox->children().at(10))->setText(channelAllenResultStr.at(i).at(2)); // tau=10 Allen + ((QLabel *)channelBox->children().at(11))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(3))); // tau=10 Count + + ((QLabel *)channelBox->children().at(13))->setText(channelAllenResultStr.at(i).at(4)); // tau=100 Allen + ((QLabel *)channelBox->children().at(14))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(5))); // tau=100 Count + + ((QLabel *)channelBox->children().at(16))->setText(channelAllenResultStr.at(i).at(6)); // tau=1000 Allen + ((QLabel *)channelBox->children().at(17))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(7))); // tau=1000 Count + + ((QLabel *)channelBox->children().at(19))->setText(channelAllenResultStr.at(i).at(8)); // tau=10000 Allen + ((QLabel *)channelBox->children().at(20))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(9))); // tau=10000 Count + } + +// qDebug() << channelAllenResultStr; +} + void PhaseWindow::generateWidgetForDevice() { // 获取设备数据 @@ -146,42 +184,124 @@ QHBoxLayout * vbox = new QHBoxLayout(group); - QLabel * tmLabel = new QLabel(); - tmLabel->setText("时间"); - tmLabel->setFont(labelFont); - tmLabel->setStyleSheet("margin-left:20;"); - vbox->addWidget(tmLabel); - QLineEdit * tmValue = new QLineEdit(); - tmValue->setFixedWidth(200); - tmValue->setFont(labelFont); - vbox->addWidget(tmValue); - - QLabel * dataLabel = new QLabel(); - dataLabel->setText("测量数据"); - dataLabel->setFont(labelFont); - dataLabel->setStyleSheet("margin-left:20;"); - vbox->addWidget(dataLabel); - QLineEdit * dataValue = new QLineEdit(); - dataValue->setFixedWidth(250); - dataValue->setFont(labelFont); - vbox->addWidget(dataValue); - - QLabel * idLabel = new QLabel(); - idLabel->setText("数据ID"); - idLabel->setFont(labelFont); - idLabel->setStyleSheet("margin-left:20;"); - vbox->addWidget(idLabel); - QLineEdit * idValue = new QLineEdit(); - idValue->setFixedWidth(100); - idValue->setFont(labelFont); - vbox->addWidget(idValue); - + // index = 1 QLabel * validLabel = new QLabel(); validLabel->setText("-"); validLabel->setFont(labelFont); validLabel->setStyleSheet("margin-left:20;"); vbox->addWidget(validLabel); + // index = 2 + QLabel * idLabel = new QLabel(); + idLabel->setText("0000"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + + // index = 3 + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + // index = 4 + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(200); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + // index = 5 + QLabel * perfLabel = new QLabel(); + perfLabel->setText("稳定度"); + perfLabel->setFont(labelFont); + perfLabel->setStyleSheet("margin-left:50;"); + vbox->addWidget(perfLabel); + + // index = 6 + QLabel * oneLabel = new QLabel(); + oneLabel->setText("Tau(s)=1"); + oneLabel->setFont(labelFont); + oneLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(oneLabel); + // index = 7 + QLabel * oneAllen = new QLabel(); + oneAllen->setText("0.00"); + oneAllen->setFont(labelFont); + vbox->addWidget(oneAllen); + // index = 8 + QLabel * oneCount = new QLabel(); + oneCount->setText("0"); + oneCount->setFont(labelFont); + vbox->addWidget(oneCount); + + // index = 9 + QLabel * tenLabel = new QLabel(); + tenLabel->setText("Tau(s)=10"); + tenLabel->setFont(labelFont); + tenLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tenLabel); + // index = 10 + QLabel * tenAllen = new QLabel(); + tenAllen->setText("0.00"); + tenAllen->setFont(labelFont); + vbox->addWidget(tenAllen); + // index = 11 + QLabel * tenCount = new QLabel(); + tenCount->setText("0"); + tenCount->setFont(labelFont); + vbox->addWidget(tenCount); + + // index = 12 + QLabel * hundLabel = new QLabel(); + hundLabel->setText("Tau(s)=100"); + hundLabel->setFont(labelFont); + hundLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(hundLabel); + // index = 13 + QLabel * hundAllen = new QLabel(); + hundAllen->setText("0.00"); + hundAllen->setFont(labelFont); + vbox->addWidget(hundAllen); + // index = 14 + QLabel * hundCount = new QLabel(); + hundCount->setText("0"); + hundCount->setFont(labelFont); + vbox->addWidget(hundCount); + + // index = 15 + QLabel * thouLabel = new QLabel(); + thouLabel->setText("Tau(s)=1000"); + thouLabel->setFont(labelFont); + thouLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(thouLabel); + // index = 16 + QLabel * thouAllen = new QLabel(); + thouAllen->setText("0.00"); + thouAllen->setFont(labelFont); + vbox->addWidget(thouAllen); + // index = 17 + QLabel * thouCount = new QLabel(); + thouCount->setText("0"); + thouCount->setFont(labelFont); + vbox->addWidget(thouCount); + + // index = 18 + QLabel * ttLabel = new QLabel(); + ttLabel->setText("Tau(s)=10000"); + ttLabel->setFont(labelFont); + ttLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(ttLabel); + // index = 19 + QLabel * ttAllen = new QLabel(); + ttAllen->setText("0.00"); + ttAllen->setFont(labelFont); + vbox->addWidget(ttAllen); + // index = 20 + QLabel * ttCount = new QLabel(); + ttCount->setText("0"); + ttCount->setFont(labelFont); + vbox->addWidget(ttCount); + QSpacerItem * hSpace = new QSpacerItem(20, 20); hSpace->changeSize(20, 20, QSizePolicy::Expanding); vbox->addItem(hSpace); @@ -247,9 +367,23 @@ QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); // 赋值,对应的lineEdit/label - ((QLineEdit *)channelBox->children().at(2))->setText(""); - ((QLineEdit *)channelBox->children().at(4))->setText(""); - ((QLineEdit *)channelBox->children().at(6))->setText(""); - ((QLabel *)channelBox->children().at(7))->setText("-"); + ((QLabel *)channelBox->children().at(1))->setText("-"); // 有效性 + ((QLabel *)channelBox->children().at(2))->setText("0000"); // 数据ID + ((QLineEdit *)channelBox->children().at(4))->setText(""); // 测量数据值 + + ((QLabel *)channelBox->children().at(7))->setText("0.00"); // tau=1 Allen + ((QLabel *)channelBox->children().at(8))->setText(QString("采样数(%1)").arg(0)); // tau=1 Count + + ((QLabel *)channelBox->children().at(10))->setText("0.00"); // tau=10 Allen + ((QLabel *)channelBox->children().at(11))->setText(QString("采样数(%1)").arg(0)); // tau=10 Count + + ((QLabel *)channelBox->children().at(13))->setText("0.00"); // tau=100 Allen + ((QLabel *)channelBox->children().at(14))->setText(QString("采样数(%1)").arg(0)); // tau=100 Count + + ((QLabel *)channelBox->children().at(16))->setText("0.00"); // tau=1000 Allen + ((QLabel *)channelBox->children().at(17))->setText(QString("采样数(%1)").arg(0)); // tau=1000 Count + + ((QLabel *)channelBox->children().at(19))->setText("0.00"); // tau=10000 Allen + ((QLabel *)channelBox->children().at(20))->setText(QString("采样数(%1)").arg(0)); // tau=10000 Count } } diff --git a/PhaseCompAcq/PhaseWindow.h b/PhaseCompAcq/PhaseWindow.h index bf1cb57..572bbde 100644 --- a/PhaseCompAcq/PhaseWindow.h +++ b/PhaseCompAcq/PhaseWindow.h @@ -25,6 +25,7 @@ public slots: void drawPhaseDataOnPage(PhaseDataDto * phaseData); + void drawPhaseAllenOnPage(QString devCode, QVector channelAllenResultStr); private slots: void on_minButt_clicked(); diff --git a/PhaseCompAcq/PhaseWindow.ui b/PhaseCompAcq/PhaseWindow.ui index 2df6062..d083fb9 100644 --- a/PhaseCompAcq/PhaseWindow.ui +++ b/PhaseCompAcq/PhaseWindow.ui @@ -182,6 +182,25 @@ 开始 + + + + 750 + 10 + 200 + 40 + + + + + 微软雅黑 + 12 + + + + + + diff --git a/PhaseCompAcq/common/utils/SettingConfig.cpp b/PhaseCompAcq/common/utils/SettingConfig.cpp index 727c841..ed02ac1 100644 --- a/PhaseCompAcq/common/utils/SettingConfig.cpp +++ b/PhaseCompAcq/common/utils/SettingConfig.cpp @@ -11,6 +11,7 @@ KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); KAFKA_STATUS_TOPIC = getProperty("kafka", "statusTopic").toString(); + KAFKA_PERFORM_TOPIC = getProperty("kafka", "performTopic").toString(); NEED_SASL = getProperty("kafka", "needSasl").toInt(); SASL_USERNAME = getProperty("kafka", "saslUsername").toString(); SASL_PASSWORD = getProperty("kafka", "saslPassword").toString(); @@ -22,8 +23,7 @@ WORK_TYPE = getProperty("client", "workMode").toString(); MASTER = getProperty("client", "master").toInt(); SERVER_PORT = getProperty("client", "serverPort").toInt(); - AUTO_STOP_TIME = getProperty("client", "autoStopTime").toInt(); - AUTO_START_TIME = getProperty("client", "autoStartTime").toInt(); + MAX_DATA_SIZE = getProperty("client", "maxDataSize").toUInt(); BASE_URL = getProperty("http", "baseUrl").toString(); diff --git a/PhaseCompAcq/common/utils/SettingConfig.h b/PhaseCompAcq/common/utils/SettingConfig.h index 1c97f9c..1d2749a 100644 --- a/PhaseCompAcq/common/utils/SettingConfig.h +++ b/PhaseCompAcq/common/utils/SettingConfig.h @@ -33,6 +33,7 @@ QString KAFKA_BROKERS; QString KAFKA_DATA_TOPIC; QString KAFKA_STATUS_TOPIC; + QString KAFKA_PERFORM_TOPIC; int NEED_SASL; QString SASL_USERNAME; QString SASL_PASSWORD; @@ -44,8 +45,7 @@ QString WORK_TYPE; int MASTER; quint16 SERVER_PORT; - qint8 AUTO_STOP_TIME; - qint8 AUTO_START_TIME; + quint32 MAX_DATA_SIZE; QString BASE_URL; diff --git a/PhaseCompAcq/PhaseCompAcq.pro b/PhaseCompAcq/PhaseCompAcq.pro index ebb2309..f51a158 100644 --- a/PhaseCompAcq/PhaseCompAcq.pro +++ b/PhaseCompAcq/PhaseCompAcq.pro @@ -4,8 +4,7 @@ CONFIG += c++11 -FORMS += \ - PhaseWindow.ui +FORMS += PhaseWindow.ui include(common/common.pri) include(protocol/protocol.pri) diff --git a/PhaseCompAcq/PhaseDevice.cpp b/PhaseCompAcq/PhaseDevice.cpp index c5466bb..b5be574 100644 --- a/PhaseCompAcq/PhaseDevice.cpp +++ b/PhaseCompAcq/PhaseDevice.cpp @@ -3,6 +3,8 @@ #include #include #include +#include +#include PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) { @@ -14,6 +16,20 @@ kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); kafkaUtil.createProducer(); } + + QVector> initPhase(PHASE_MESSURE_CHANNEL, QVector(0, 0)); + phaseVector = initPhase; + + QVector> initAllen(PHASE_MESSURE_CHANNEL, QVector(5, 0)); + channelAllen = initAllen; + + QVector> initSigma(PHASE_MESSURE_CHANNEL, QVector(5, 0)); + channelAllenSigma = initSigma; + + QVector initResult(PHASE_MESSURE_CHANNEL); + channelAllenResultStr = initResult; + + connect(this, &PhaseDevice::calculateAllen, this, &PhaseDevice::onCalculateAllen); } PhaseDevice::~PhaseDevice() @@ -134,23 +150,19 @@ QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); QLogUtil::writeRawDataLogByDate(date, filename, content); + // 发送到消息队列里的内容 QJsonArray messageArray; + QJsonArray performArray; QString msgLogFilename = "msg_" + devCode + ".log"; + QString perfLogFilename = "perf_" + devCode + ".log"; // 2.2 各个通道的相差数据 for (int i = 1; i <= phaseData->channelActive.size(); i++) { if (phaseData->channelActive.at(i-1).toUInt() == 1) { - QString chFilename("%1_CH_%2.log"); - chFilename = chFilename.arg(devCode); - if (i < 10) - { - chFilename = chFilename.arg(QString("0%1").arg(i)); - } else - { - chFilename = chFilename.arg(i); - } + // 存日志 + QString chFilename = QString("%1_CH_%2.log").arg(devCode).arg(i, 2, 10, QLatin1Char('0')); QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); @@ -160,6 +172,15 @@ jsonObj.insert("master", SettingConfig::getInstance().MASTER); jsonObj.insert("deviceId", deviceId); messageArray.append(jsonObj); + + // 将相位数据存入数据栈, 用于计算allen方差 + QMutex mutex; + mutex.lock(); + phaseVector[i - 1].append(phaseData->channelData.at(i - 1)); + if (phaseVector[i - 1].size() > SettingConfig::getInstance().MAX_DATA_SIZE) { + phaseVector[i - 1] = phaseVector[i - 1].mid(phaseVector[i - 1].size() - SettingConfig::getInstance().MAX_DATA_SIZE); + } + mutex.unlock(); } } @@ -177,10 +198,107 @@ if (QDateTime::currentDateTime().time().second() % 10 == 0) { kafkaUtil.produceMessage(SettingConfig::getInstance().KAFKA_STATUS_TOPIC, QString(QJsonDocument(statusObj).toJson(QJsonDocument::Compact))); } + + // 模拟发送稳定度计算结果 + // 1s 10s 100s 1000s 10000s + kafkaUtil.produceMessage(SettingConfig::getInstance().KAFKA_PERFORM_TOPIC, QString(QJsonDocument(performArray).toJson(QJsonDocument::Compact))); } QLogUtil::writeChannelDataLogByDate(date, msgLogFilename, QString(QJsonDocument(messageArray).toJson(QJsonDocument::Compact))); + QLogUtil::writeChannelDataLogByDate(date, perfLogFilename, QString(QJsonDocument(performArray).toJson(QJsonDocument::Compact))); // 4. 在界面上简单显示相差数据结果 emit this->sendDataToDraw(phaseData); + + // send signal to calculate allen and produce message to kafka + emit calculateAllen(); +} + +void PhaseDevice::onCalculateAllen() +{ + // 不同维度的稳定度数据 1s - 10000s + for (int i = 0; i < phaseVector.size(); i++) + { + QStringList result; + int size = phaseVector[i].size(); + for (int j = 0; j < 5; j++) + { + if (size >= 5 * pow(10, j)) { + channelAllen[i][j] = calAllan(i, pow(10, j), size); + } else { + channelAllen[i][j] = 0.0; + } + + result << QString::number(channelAllen[i][j], 'e', 4) << QString::number((int)(size / pow(10, j))); + } + + channelAllenResultStr[i] = result; +// qDebug() << result; + } + + emit this->sendAllenToDraw(devCode, channelAllenResultStr); +/* + // 分别计算不同时间维度的稳定度 + int size = phaseVector[i - 1].size(); + if(size >= 5) allen[0] = calAllan(i - 1, 1, size); else allen[0] = 0; + if(size >= 50) allen[1] = calAllan(i - 1, 10, size); else allen[1] = 0; + if(size >= 500) allen[2] = calAllan(i - 1, 100, size); else allen[2] = 0; + if(size >= 5000) allen[3] = calAllan(i - 1, 1000, size); else allen[3] = 0; + if(size >= 50000) allen[4] = calAllan(i - 1, 10000, size); else allen[4] = 0; + + // mock perform data + QJsonObject performData; + performData.insert("channelNo", i); + performData.insert("ts", (phaseData->milisecond / 1000) * 1000); + performData.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + performData.insert("master", SettingConfig::getInstance().MASTER); + performData.insert("deviceId", deviceId); + QJsonArray dataArr; + for (int k = 0; k < 5; k++) { + QJsonObject dataObj; + dataObj.insert("tau", QString::number(qPow(10, k))); + dataObj.insert("allen", QString::number(allen[k], 'e', 4)); + dataObj.insert("count", QString::number((int)(size / qPow(10, k)))); + dataArr.append(dataObj); + + QStringList allenStrList; + allenStrList << QString::number(qPow(10, k)) << QString::number(allen[k], 'e', 4) << QString::number((int)(size / qPow(10, k))); + phaseData->allenDataStr.append(allenStrList); + } + performData.insert("data", dataArr); + performArray.append(performData); + */ +} + +double PhaseDevice::calAllan(int index, int d, int aN) +{ + int i = 0; + double tau0 = 1; //tau0是基本采样间隔,由计数器或比相仪的最小采样间隔决定,最小为1s + double allan[2] = {0.0}; + double *y = new double[3]; + double tau_2 = pow(d * tau0, 2); //pow是计算x的y次幂 + + int logd = log10(d); + + double sum = channelAllenSigma[index][logd]; + + for (int j = 3; j > 0; j--) + { + i = aN - 2*d - j; + double v2 = phaseVector[index][i+2*d]; + double v1 = phaseVector[index][i+d]; + double v0 = phaseVector[index][i]; + y[3 - j] = pow(v2 - 2 * v1 + v0, 2); + + sum += y[3 - j]; + } + + channelAllenSigma[index][logd] += y[0]; + + allan[0] = sum/(2*tau_2*(aN-2*d)); //delta的平方 + allan[1] = sqrt(sum/(2*tau_2*(aN-2*d))); //delta + + delete[] y; + + return allan[1]; } diff --git a/PhaseCompAcq/PhaseDevice.h b/PhaseCompAcq/PhaseDevice.h index 887ed10..13b7c2d 100644 --- a/PhaseCompAcq/PhaseDevice.h +++ b/PhaseCompAcq/PhaseDevice.h @@ -2,6 +2,8 @@ #define PHASEDEVICE_H #include +#include +#include #include "common/utils/QSerialPortUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" @@ -38,11 +40,29 @@ QKafkaUtil kafkaUtil; QByteArray dataBuff; + // 原始数据 - 补偿之前的值 + QVector> phaseVector; + + // 不同维度的稳定度数据 1s - 10000s + QVector> channelAllen; + + // 计算过程中的累计和 + QVector> channelAllenSigma; + + // 各个通道的allen方差结果 + QVector channelAllenResultStr; + + // 计算allen方差 + double calAllan(int index, int d, int aN); + signals: void sendDataToDraw(PhaseDataDto * phaseData); + void calculateAllen(); + void sendAllenToDraw(QString devCode, QVector channelAllenResultStr); public slots: void dataReceivedHandler(QByteArray data); + void onCalculateAllen(); }; diff --git a/PhaseCompAcq/PhaseWindow.cpp b/PhaseCompAcq/PhaseWindow.cpp index 514b271..a082818 100644 --- a/PhaseCompAcq/PhaseWindow.cpp +++ b/PhaseCompAcq/PhaseWindow.cpp @@ -72,8 +72,8 @@ device->setDevCode(devItem.find("deviceNo")->toString()); device->setDeviceId(devItem.find("deviceId")->toString()); - connect(device, &PhaseDevice::sendDataToDraw, - this, &PhaseWindow::drawPhaseDataOnPage); + connect(device, &PhaseDevice::sendDataToDraw, this, &PhaseWindow::drawPhaseDataOnPage); + connect(device, &PhaseDevice::sendAllenToDraw, this, &PhaseWindow::drawPhaseAllenOnPage); device->initSerialPort(); @@ -111,6 +111,8 @@ return; } + ui->labTm->setText(phaseData->timestamp.left(19)); + // 更新所有通道BOX的值 for (int i = 0; i < phaseData->channelActive.size(); i++) { @@ -118,13 +120,49 @@ QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); // 赋值,对应的lineEdit/label - ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); - ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); - ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); - ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + ((QLabel *)channelBox->children().at(1))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); // 有效性 + ((QLabel *)channelBox->children().at(2))->setText(phaseData->frameId); // 数据ID + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); // 测量数据值 } } +void PhaseWindow::drawPhaseAllenOnPage(QString devCode, QVector channelAllenResultStr) +{ + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 + if (devCode != currentDevCode) + { + return; + } + + // 更新所有通道BOX的值 + for (int i = 0; i < channelAllenResultStr.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的label + ((QLabel *)channelBox->children().at(7))->setText(channelAllenResultStr.at(i).at(0)); // tau=1 Allen + ((QLabel *)channelBox->children().at(8))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(1))); // tau=1 Count + + ((QLabel *)channelBox->children().at(10))->setText(channelAllenResultStr.at(i).at(2)); // tau=10 Allen + ((QLabel *)channelBox->children().at(11))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(3))); // tau=10 Count + + ((QLabel *)channelBox->children().at(13))->setText(channelAllenResultStr.at(i).at(4)); // tau=100 Allen + ((QLabel *)channelBox->children().at(14))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(5))); // tau=100 Count + + ((QLabel *)channelBox->children().at(16))->setText(channelAllenResultStr.at(i).at(6)); // tau=1000 Allen + ((QLabel *)channelBox->children().at(17))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(7))); // tau=1000 Count + + ((QLabel *)channelBox->children().at(19))->setText(channelAllenResultStr.at(i).at(8)); // tau=10000 Allen + ((QLabel *)channelBox->children().at(20))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(9))); // tau=10000 Count + } + +// qDebug() << channelAllenResultStr; +} + void PhaseWindow::generateWidgetForDevice() { // 获取设备数据 @@ -146,42 +184,124 @@ QHBoxLayout * vbox = new QHBoxLayout(group); - QLabel * tmLabel = new QLabel(); - tmLabel->setText("时间"); - tmLabel->setFont(labelFont); - tmLabel->setStyleSheet("margin-left:20;"); - vbox->addWidget(tmLabel); - QLineEdit * tmValue = new QLineEdit(); - tmValue->setFixedWidth(200); - tmValue->setFont(labelFont); - vbox->addWidget(tmValue); - - QLabel * dataLabel = new QLabel(); - dataLabel->setText("测量数据"); - dataLabel->setFont(labelFont); - dataLabel->setStyleSheet("margin-left:20;"); - vbox->addWidget(dataLabel); - QLineEdit * dataValue = new QLineEdit(); - dataValue->setFixedWidth(250); - dataValue->setFont(labelFont); - vbox->addWidget(dataValue); - - QLabel * idLabel = new QLabel(); - idLabel->setText("数据ID"); - idLabel->setFont(labelFont); - idLabel->setStyleSheet("margin-left:20;"); - vbox->addWidget(idLabel); - QLineEdit * idValue = new QLineEdit(); - idValue->setFixedWidth(100); - idValue->setFont(labelFont); - vbox->addWidget(idValue); - + // index = 1 QLabel * validLabel = new QLabel(); validLabel->setText("-"); validLabel->setFont(labelFont); validLabel->setStyleSheet("margin-left:20;"); vbox->addWidget(validLabel); + // index = 2 + QLabel * idLabel = new QLabel(); + idLabel->setText("0000"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + + // index = 3 + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + // index = 4 + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(200); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + // index = 5 + QLabel * perfLabel = new QLabel(); + perfLabel->setText("稳定度"); + perfLabel->setFont(labelFont); + perfLabel->setStyleSheet("margin-left:50;"); + vbox->addWidget(perfLabel); + + // index = 6 + QLabel * oneLabel = new QLabel(); + oneLabel->setText("Tau(s)=1"); + oneLabel->setFont(labelFont); + oneLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(oneLabel); + // index = 7 + QLabel * oneAllen = new QLabel(); + oneAllen->setText("0.00"); + oneAllen->setFont(labelFont); + vbox->addWidget(oneAllen); + // index = 8 + QLabel * oneCount = new QLabel(); + oneCount->setText("0"); + oneCount->setFont(labelFont); + vbox->addWidget(oneCount); + + // index = 9 + QLabel * tenLabel = new QLabel(); + tenLabel->setText("Tau(s)=10"); + tenLabel->setFont(labelFont); + tenLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tenLabel); + // index = 10 + QLabel * tenAllen = new QLabel(); + tenAllen->setText("0.00"); + tenAllen->setFont(labelFont); + vbox->addWidget(tenAllen); + // index = 11 + QLabel * tenCount = new QLabel(); + tenCount->setText("0"); + tenCount->setFont(labelFont); + vbox->addWidget(tenCount); + + // index = 12 + QLabel * hundLabel = new QLabel(); + hundLabel->setText("Tau(s)=100"); + hundLabel->setFont(labelFont); + hundLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(hundLabel); + // index = 13 + QLabel * hundAllen = new QLabel(); + hundAllen->setText("0.00"); + hundAllen->setFont(labelFont); + vbox->addWidget(hundAllen); + // index = 14 + QLabel * hundCount = new QLabel(); + hundCount->setText("0"); + hundCount->setFont(labelFont); + vbox->addWidget(hundCount); + + // index = 15 + QLabel * thouLabel = new QLabel(); + thouLabel->setText("Tau(s)=1000"); + thouLabel->setFont(labelFont); + thouLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(thouLabel); + // index = 16 + QLabel * thouAllen = new QLabel(); + thouAllen->setText("0.00"); + thouAllen->setFont(labelFont); + vbox->addWidget(thouAllen); + // index = 17 + QLabel * thouCount = new QLabel(); + thouCount->setText("0"); + thouCount->setFont(labelFont); + vbox->addWidget(thouCount); + + // index = 18 + QLabel * ttLabel = new QLabel(); + ttLabel->setText("Tau(s)=10000"); + ttLabel->setFont(labelFont); + ttLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(ttLabel); + // index = 19 + QLabel * ttAllen = new QLabel(); + ttAllen->setText("0.00"); + ttAllen->setFont(labelFont); + vbox->addWidget(ttAllen); + // index = 20 + QLabel * ttCount = new QLabel(); + ttCount->setText("0"); + ttCount->setFont(labelFont); + vbox->addWidget(ttCount); + QSpacerItem * hSpace = new QSpacerItem(20, 20); hSpace->changeSize(20, 20, QSizePolicy::Expanding); vbox->addItem(hSpace); @@ -247,9 +367,23 @@ QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); // 赋值,对应的lineEdit/label - ((QLineEdit *)channelBox->children().at(2))->setText(""); - ((QLineEdit *)channelBox->children().at(4))->setText(""); - ((QLineEdit *)channelBox->children().at(6))->setText(""); - ((QLabel *)channelBox->children().at(7))->setText("-"); + ((QLabel *)channelBox->children().at(1))->setText("-"); // 有效性 + ((QLabel *)channelBox->children().at(2))->setText("0000"); // 数据ID + ((QLineEdit *)channelBox->children().at(4))->setText(""); // 测量数据值 + + ((QLabel *)channelBox->children().at(7))->setText("0.00"); // tau=1 Allen + ((QLabel *)channelBox->children().at(8))->setText(QString("采样数(%1)").arg(0)); // tau=1 Count + + ((QLabel *)channelBox->children().at(10))->setText("0.00"); // tau=10 Allen + ((QLabel *)channelBox->children().at(11))->setText(QString("采样数(%1)").arg(0)); // tau=10 Count + + ((QLabel *)channelBox->children().at(13))->setText("0.00"); // tau=100 Allen + ((QLabel *)channelBox->children().at(14))->setText(QString("采样数(%1)").arg(0)); // tau=100 Count + + ((QLabel *)channelBox->children().at(16))->setText("0.00"); // tau=1000 Allen + ((QLabel *)channelBox->children().at(17))->setText(QString("采样数(%1)").arg(0)); // tau=1000 Count + + ((QLabel *)channelBox->children().at(19))->setText("0.00"); // tau=10000 Allen + ((QLabel *)channelBox->children().at(20))->setText(QString("采样数(%1)").arg(0)); // tau=10000 Count } } diff --git a/PhaseCompAcq/PhaseWindow.h b/PhaseCompAcq/PhaseWindow.h index bf1cb57..572bbde 100644 --- a/PhaseCompAcq/PhaseWindow.h +++ b/PhaseCompAcq/PhaseWindow.h @@ -25,6 +25,7 @@ public slots: void drawPhaseDataOnPage(PhaseDataDto * phaseData); + void drawPhaseAllenOnPage(QString devCode, QVector channelAllenResultStr); private slots: void on_minButt_clicked(); diff --git a/PhaseCompAcq/PhaseWindow.ui b/PhaseCompAcq/PhaseWindow.ui index 2df6062..d083fb9 100644 --- a/PhaseCompAcq/PhaseWindow.ui +++ b/PhaseCompAcq/PhaseWindow.ui @@ -182,6 +182,25 @@ 开始 + + + + 750 + 10 + 200 + 40 + + + + + 微软雅黑 + 12 + + + + + + diff --git a/PhaseCompAcq/common/utils/SettingConfig.cpp b/PhaseCompAcq/common/utils/SettingConfig.cpp index 727c841..ed02ac1 100644 --- a/PhaseCompAcq/common/utils/SettingConfig.cpp +++ b/PhaseCompAcq/common/utils/SettingConfig.cpp @@ -11,6 +11,7 @@ KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); KAFKA_STATUS_TOPIC = getProperty("kafka", "statusTopic").toString(); + KAFKA_PERFORM_TOPIC = getProperty("kafka", "performTopic").toString(); NEED_SASL = getProperty("kafka", "needSasl").toInt(); SASL_USERNAME = getProperty("kafka", "saslUsername").toString(); SASL_PASSWORD = getProperty("kafka", "saslPassword").toString(); @@ -22,8 +23,7 @@ WORK_TYPE = getProperty("client", "workMode").toString(); MASTER = getProperty("client", "master").toInt(); SERVER_PORT = getProperty("client", "serverPort").toInt(); - AUTO_STOP_TIME = getProperty("client", "autoStopTime").toInt(); - AUTO_START_TIME = getProperty("client", "autoStartTime").toInt(); + MAX_DATA_SIZE = getProperty("client", "maxDataSize").toUInt(); BASE_URL = getProperty("http", "baseUrl").toString(); diff --git a/PhaseCompAcq/common/utils/SettingConfig.h b/PhaseCompAcq/common/utils/SettingConfig.h index 1c97f9c..1d2749a 100644 --- a/PhaseCompAcq/common/utils/SettingConfig.h +++ b/PhaseCompAcq/common/utils/SettingConfig.h @@ -33,6 +33,7 @@ QString KAFKA_BROKERS; QString KAFKA_DATA_TOPIC; QString KAFKA_STATUS_TOPIC; + QString KAFKA_PERFORM_TOPIC; int NEED_SASL; QString SASL_USERNAME; QString SASL_PASSWORD; @@ -44,8 +45,7 @@ QString WORK_TYPE; int MASTER; quint16 SERVER_PORT; - qint8 AUTO_STOP_TIME; - qint8 AUTO_START_TIME; + quint32 MAX_DATA_SIZE; QString BASE_URL; diff --git a/PhaseCompAcq/conf/config.ini b/PhaseCompAcq/conf/config.ini index a8c70de..e7dc133 100644 --- a/PhaseCompAcq/conf/config.ini +++ b/PhaseCompAcq/conf/config.ini @@ -6,6 +6,7 @@ brokers="111.198.10.15:20104" dataTopic="phase-data" statusTopic="dev-status" +performTopic="perform-data" needSasl=1 saslUsername="admin" saslPassword="casicss" @@ -18,8 +19,7 @@ workMode="mock" master=1 serverPort=5905 -autoStopTime=5 -autoStartTime=20 +maxDataSize=172800 [http] baseUrl="http://192.168.20.135:11410"