diff --git a/CounterRealTime/CounterDevice.cpp b/CounterRealTime/CounterDevice.cpp index 4ff6565..f656746 100644 --- a/CounterRealTime/CounterDevice.cpp +++ b/CounterRealTime/CounterDevice.cpp @@ -9,11 +9,13 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &CounterDevice::dataReceivedHandler); +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); kafkaUtil.createProducer(); } +#endif } CounterDevice::~CounterDevice() @@ -78,6 +80,15 @@ this->refChannelCode = refChannelCode; } +int CounterDevice::getRefChannelNo() +{ + return this->refChannelNo; +} +void CounterDevice::setRefChannelNo(int refChannelNo) +{ + this->refChannelNo = refChannelNo; +} + bool CounterDevice::isSerialOpen() { return this->serialUtil.isOpen(); @@ -156,7 +167,7 @@ msgLogFilename = msgLogFilename.arg((hour / 6) * 6, 2, 10, QLatin1Char('0')); msgLogFilename = msgLogFilename.arg((hour / 6) * 6 + 5, 2, 10, QLatin1Char('0')); - CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(counterData->channelRefId)); + CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(counterData->channelRefId, 2, 10, QLatin1Char('0'))); this->refChannelNo = counterData->channelRefId; double refDelay = 0.0; if (refChanPtr != nullptr && refChanPtr->getDelays().isEmpty() == false) { @@ -186,7 +197,7 @@ } // 加到hisDataList中 用于绘制图表 - CounterChannel * channelPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i)); + CounterChannel * channelPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i, 2, 10, QLatin1Char('0'))); if (channelPtr != nullptr && channelPtr->isActive() == true) { // 通道时延值 并计算 减去时延值的测量值 @@ -210,6 +221,7 @@ statusObj.insert("master", SettingConfig::getInstance().MASTER); statusObj.insert("deviceId", deviceId); +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { if (SettingConfig::getInstance().MASTER == 0) @@ -227,6 +239,7 @@ kafkaUtil.produceMessage(SettingConfig::getInstance().KAFKA_STATUS_TOPIC, QString(QJsonDocument(statusObj).toJson(QJsonDocument::Compact))); } } +#endif QLogUtil::writeMessageLogByDate(date, msgLogFilename, QString(QJsonDocument(messageArray).toJson(QJsonDocument::Compact))); diff --git a/CounterRealTime/CounterDevice.cpp b/CounterRealTime/CounterDevice.cpp index 4ff6565..f656746 100644 --- a/CounterRealTime/CounterDevice.cpp +++ b/CounterRealTime/CounterDevice.cpp @@ -9,11 +9,13 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &CounterDevice::dataReceivedHandler); +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); kafkaUtil.createProducer(); } +#endif } CounterDevice::~CounterDevice() @@ -78,6 +80,15 @@ this->refChannelCode = refChannelCode; } +int CounterDevice::getRefChannelNo() +{ + return this->refChannelNo; +} +void CounterDevice::setRefChannelNo(int refChannelNo) +{ + this->refChannelNo = refChannelNo; +} + bool CounterDevice::isSerialOpen() { return this->serialUtil.isOpen(); @@ -156,7 +167,7 @@ msgLogFilename = msgLogFilename.arg((hour / 6) * 6, 2, 10, QLatin1Char('0')); msgLogFilename = msgLogFilename.arg((hour / 6) * 6 + 5, 2, 10, QLatin1Char('0')); - CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(counterData->channelRefId)); + CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(counterData->channelRefId, 2, 10, QLatin1Char('0'))); this->refChannelNo = counterData->channelRefId; double refDelay = 0.0; if (refChanPtr != nullptr && refChanPtr->getDelays().isEmpty() == false) { @@ -186,7 +197,7 @@ } // 加到hisDataList中 用于绘制图表 - CounterChannel * channelPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i)); + CounterChannel * channelPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i, 2, 10, QLatin1Char('0'))); if (channelPtr != nullptr && channelPtr->isActive() == true) { // 通道时延值 并计算 减去时延值的测量值 @@ -210,6 +221,7 @@ statusObj.insert("master", SettingConfig::getInstance().MASTER); statusObj.insert("deviceId", deviceId); +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { if (SettingConfig::getInstance().MASTER == 0) @@ -227,6 +239,7 @@ kafkaUtil.produceMessage(SettingConfig::getInstance().KAFKA_STATUS_TOPIC, QString(QJsonDocument(statusObj).toJson(QJsonDocument::Compact))); } } +#endif QLogUtil::writeMessageLogByDate(date, msgLogFilename, QString(QJsonDocument(messageArray).toJson(QJsonDocument::Compact))); diff --git a/CounterRealTime/CounterDevice.h b/CounterRealTime/CounterDevice.h index c4d003d..68390c8 100644 --- a/CounterRealTime/CounterDevice.h +++ b/CounterRealTime/CounterDevice.h @@ -6,7 +6,6 @@ #include "CounterChannel.h" #include "common/utils/QSerialPortUtil.h" -#include "common/utils/QKafkaUtil.h" #include "common/utils/QByteUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" @@ -14,6 +13,10 @@ #include "common/LinearRegression.h" #include "protocol/CounterProtocolXH.h" +#ifdef unix +#include "common/utils/QKafkaUtil.h" +#endif + class CounterDevice : public QObject { Q_OBJECT @@ -37,6 +40,9 @@ int getIsUse(); void setIsUse(int isUse); + int getRefChannelNo(); + void setRefChannelNo(int refChannelNo); + QString getRefChannelCode(); void setRefChannelCode(QString refChannelCode); @@ -56,9 +62,12 @@ int formColIndex; QSerialPortUtil serialUtil; - QKafkaUtil kafkaUtil; QByteArray dataBuff; +#ifdef unix + QKafkaUtil kafkaUtil; +#endif + void afterFramePhase(CounterDataDto * counterData); void calcResidualClockData(qlonglong tm); diff --git a/CounterRealTime/CounterDevice.cpp b/CounterRealTime/CounterDevice.cpp index 4ff6565..f656746 100644 --- a/CounterRealTime/CounterDevice.cpp +++ b/CounterRealTime/CounterDevice.cpp @@ -9,11 +9,13 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &CounterDevice::dataReceivedHandler); +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); kafkaUtil.createProducer(); } +#endif } CounterDevice::~CounterDevice() @@ -78,6 +80,15 @@ this->refChannelCode = refChannelCode; } +int CounterDevice::getRefChannelNo() +{ + return this->refChannelNo; +} +void CounterDevice::setRefChannelNo(int refChannelNo) +{ + this->refChannelNo = refChannelNo; +} + bool CounterDevice::isSerialOpen() { return this->serialUtil.isOpen(); @@ -156,7 +167,7 @@ msgLogFilename = msgLogFilename.arg((hour / 6) * 6, 2, 10, QLatin1Char('0')); msgLogFilename = msgLogFilename.arg((hour / 6) * 6 + 5, 2, 10, QLatin1Char('0')); - CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(counterData->channelRefId)); + CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(counterData->channelRefId, 2, 10, QLatin1Char('0'))); this->refChannelNo = counterData->channelRefId; double refDelay = 0.0; if (refChanPtr != nullptr && refChanPtr->getDelays().isEmpty() == false) { @@ -186,7 +197,7 @@ } // 加到hisDataList中 用于绘制图表 - CounterChannel * channelPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i)); + CounterChannel * channelPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i, 2, 10, QLatin1Char('0'))); if (channelPtr != nullptr && channelPtr->isActive() == true) { // 通道时延值 并计算 减去时延值的测量值 @@ -210,6 +221,7 @@ statusObj.insert("master", SettingConfig::getInstance().MASTER); statusObj.insert("deviceId", deviceId); +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { if (SettingConfig::getInstance().MASTER == 0) @@ -227,6 +239,7 @@ kafkaUtil.produceMessage(SettingConfig::getInstance().KAFKA_STATUS_TOPIC, QString(QJsonDocument(statusObj).toJson(QJsonDocument::Compact))); } } +#endif QLogUtil::writeMessageLogByDate(date, msgLogFilename, QString(QJsonDocument(messageArray).toJson(QJsonDocument::Compact))); diff --git a/CounterRealTime/CounterDevice.h b/CounterRealTime/CounterDevice.h index c4d003d..68390c8 100644 --- a/CounterRealTime/CounterDevice.h +++ b/CounterRealTime/CounterDevice.h @@ -6,7 +6,6 @@ #include "CounterChannel.h" #include "common/utils/QSerialPortUtil.h" -#include "common/utils/QKafkaUtil.h" #include "common/utils/QByteUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" @@ -14,6 +13,10 @@ #include "common/LinearRegression.h" #include "protocol/CounterProtocolXH.h" +#ifdef unix +#include "common/utils/QKafkaUtil.h" +#endif + class CounterDevice : public QObject { Q_OBJECT @@ -37,6 +40,9 @@ int getIsUse(); void setIsUse(int isUse); + int getRefChannelNo(); + void setRefChannelNo(int refChannelNo); + QString getRefChannelCode(); void setRefChannelCode(QString refChannelCode); @@ -56,9 +62,12 @@ int formColIndex; QSerialPortUtil serialUtil; - QKafkaUtil kafkaUtil; QByteArray dataBuff; +#ifdef unix + QKafkaUtil kafkaUtil; +#endif + void afterFramePhase(CounterDataDto * counterData); void calcResidualClockData(qlonglong tm); diff --git a/CounterRealTime/CounterRealTime.pro b/CounterRealTime/CounterRealTime.pro index c323f04..f990ff3 100644 --- a/CounterRealTime/CounterRealTime.pro +++ b/CounterRealTime/CounterRealTime.pro @@ -49,7 +49,8 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka++ -lrdkafka +win32: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka++ -lrdkafka INCLUDEPATH += $$PWD/include/librdkafka DEPENDPATH += $$PWD/include/librdkafka diff --git a/CounterRealTime/CounterDevice.cpp b/CounterRealTime/CounterDevice.cpp index 4ff6565..f656746 100644 --- a/CounterRealTime/CounterDevice.cpp +++ b/CounterRealTime/CounterDevice.cpp @@ -9,11 +9,13 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &CounterDevice::dataReceivedHandler); +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); kafkaUtil.createProducer(); } +#endif } CounterDevice::~CounterDevice() @@ -78,6 +80,15 @@ this->refChannelCode = refChannelCode; } +int CounterDevice::getRefChannelNo() +{ + return this->refChannelNo; +} +void CounterDevice::setRefChannelNo(int refChannelNo) +{ + this->refChannelNo = refChannelNo; +} + bool CounterDevice::isSerialOpen() { return this->serialUtil.isOpen(); @@ -156,7 +167,7 @@ msgLogFilename = msgLogFilename.arg((hour / 6) * 6, 2, 10, QLatin1Char('0')); msgLogFilename = msgLogFilename.arg((hour / 6) * 6 + 5, 2, 10, QLatin1Char('0')); - CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(counterData->channelRefId)); + CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(counterData->channelRefId, 2, 10, QLatin1Char('0'))); this->refChannelNo = counterData->channelRefId; double refDelay = 0.0; if (refChanPtr != nullptr && refChanPtr->getDelays().isEmpty() == false) { @@ -186,7 +197,7 @@ } // 加到hisDataList中 用于绘制图表 - CounterChannel * channelPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i)); + CounterChannel * channelPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i, 2, 10, QLatin1Char('0'))); if (channelPtr != nullptr && channelPtr->isActive() == true) { // 通道时延值 并计算 减去时延值的测量值 @@ -210,6 +221,7 @@ statusObj.insert("master", SettingConfig::getInstance().MASTER); statusObj.insert("deviceId", deviceId); +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { if (SettingConfig::getInstance().MASTER == 0) @@ -227,6 +239,7 @@ kafkaUtil.produceMessage(SettingConfig::getInstance().KAFKA_STATUS_TOPIC, QString(QJsonDocument(statusObj).toJson(QJsonDocument::Compact))); } } +#endif QLogUtil::writeMessageLogByDate(date, msgLogFilename, QString(QJsonDocument(messageArray).toJson(QJsonDocument::Compact))); diff --git a/CounterRealTime/CounterDevice.h b/CounterRealTime/CounterDevice.h index c4d003d..68390c8 100644 --- a/CounterRealTime/CounterDevice.h +++ b/CounterRealTime/CounterDevice.h @@ -6,7 +6,6 @@ #include "CounterChannel.h" #include "common/utils/QSerialPortUtil.h" -#include "common/utils/QKafkaUtil.h" #include "common/utils/QByteUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" @@ -14,6 +13,10 @@ #include "common/LinearRegression.h" #include "protocol/CounterProtocolXH.h" +#ifdef unix +#include "common/utils/QKafkaUtil.h" +#endif + class CounterDevice : public QObject { Q_OBJECT @@ -37,6 +40,9 @@ int getIsUse(); void setIsUse(int isUse); + int getRefChannelNo(); + void setRefChannelNo(int refChannelNo); + QString getRefChannelCode(); void setRefChannelCode(QString refChannelCode); @@ -56,9 +62,12 @@ int formColIndex; QSerialPortUtil serialUtil; - QKafkaUtil kafkaUtil; QByteArray dataBuff; +#ifdef unix + QKafkaUtil kafkaUtil; +#endif + void afterFramePhase(CounterDataDto * counterData); void calcResidualClockData(qlonglong tm); diff --git a/CounterRealTime/CounterRealTime.pro b/CounterRealTime/CounterRealTime.pro index c323f04..f990ff3 100644 --- a/CounterRealTime/CounterRealTime.pro +++ b/CounterRealTime/CounterRealTime.pro @@ -49,7 +49,8 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka++ -lrdkafka +win32: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka++ -lrdkafka INCLUDEPATH += $$PWD/include/librdkafka DEPENDPATH += $$PWD/include/librdkafka diff --git a/CounterRealTime/CounterSettingForm.cpp b/CounterRealTime/CounterSettingForm.cpp index c1945d1..bc43ac7 100644 --- a/CounterRealTime/CounterSettingForm.cpp +++ b/CounterRealTime/CounterSettingForm.cpp @@ -335,7 +335,7 @@ active = activeListRight.at(i - 8)->isChecked(); } - CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1)); + CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1, 2, 10, QLatin1Char('0'))); if (channelPrt != nullptr) { bool isUpdated = isChannelSettingUpdated(i, channelPrt); @@ -362,7 +362,7 @@ newChannel->setChannelCode(channelCode); newChannel->setDelays(QString::number(delay)); - ConstCache::getInstance().channelMap.insert(QString("%1-%2").arg(deviceId).arg(i+1), newChannel); + ConstCache::getInstance().channelMap.insert(QString("%1-%2").arg(deviceId).arg(i+1, 2, 10, QLatin1Char('0')), newChannel); QJsonObject channelObj; channelObj.insert("id", ""); @@ -412,7 +412,7 @@ activeListLeft.at(i)->setCheckable(true); activeListRight.at(i)->setCheckable(true); - CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1)); + CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1, 2, 10, QLatin1Char('0'))); if (channelPrt != nullptr) { QString channelCode = channelPrt->getChannelCode(); // 通道钟号 @@ -429,7 +429,7 @@ } } - CounterChannel * channelRightPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1+8)); + CounterChannel * channelRightPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1+8, 2, 10, QLatin1Char('0'))); if (channelRightPrt != nullptr) { QString channelCode = channelRightPrt->getChannelCode(); // 通道钟号 diff --git a/CounterRealTime/CounterDevice.cpp b/CounterRealTime/CounterDevice.cpp index 4ff6565..f656746 100644 --- a/CounterRealTime/CounterDevice.cpp +++ b/CounterRealTime/CounterDevice.cpp @@ -9,11 +9,13 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &CounterDevice::dataReceivedHandler); +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); kafkaUtil.createProducer(); } +#endif } CounterDevice::~CounterDevice() @@ -78,6 +80,15 @@ this->refChannelCode = refChannelCode; } +int CounterDevice::getRefChannelNo() +{ + return this->refChannelNo; +} +void CounterDevice::setRefChannelNo(int refChannelNo) +{ + this->refChannelNo = refChannelNo; +} + bool CounterDevice::isSerialOpen() { return this->serialUtil.isOpen(); @@ -156,7 +167,7 @@ msgLogFilename = msgLogFilename.arg((hour / 6) * 6, 2, 10, QLatin1Char('0')); msgLogFilename = msgLogFilename.arg((hour / 6) * 6 + 5, 2, 10, QLatin1Char('0')); - CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(counterData->channelRefId)); + CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(counterData->channelRefId, 2, 10, QLatin1Char('0'))); this->refChannelNo = counterData->channelRefId; double refDelay = 0.0; if (refChanPtr != nullptr && refChanPtr->getDelays().isEmpty() == false) { @@ -186,7 +197,7 @@ } // 加到hisDataList中 用于绘制图表 - CounterChannel * channelPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i)); + CounterChannel * channelPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i, 2, 10, QLatin1Char('0'))); if (channelPtr != nullptr && channelPtr->isActive() == true) { // 通道时延值 并计算 减去时延值的测量值 @@ -210,6 +221,7 @@ statusObj.insert("master", SettingConfig::getInstance().MASTER); statusObj.insert("deviceId", deviceId); +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { if (SettingConfig::getInstance().MASTER == 0) @@ -227,6 +239,7 @@ kafkaUtil.produceMessage(SettingConfig::getInstance().KAFKA_STATUS_TOPIC, QString(QJsonDocument(statusObj).toJson(QJsonDocument::Compact))); } } +#endif QLogUtil::writeMessageLogByDate(date, msgLogFilename, QString(QJsonDocument(messageArray).toJson(QJsonDocument::Compact))); diff --git a/CounterRealTime/CounterDevice.h b/CounterRealTime/CounterDevice.h index c4d003d..68390c8 100644 --- a/CounterRealTime/CounterDevice.h +++ b/CounterRealTime/CounterDevice.h @@ -6,7 +6,6 @@ #include "CounterChannel.h" #include "common/utils/QSerialPortUtil.h" -#include "common/utils/QKafkaUtil.h" #include "common/utils/QByteUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" @@ -14,6 +13,10 @@ #include "common/LinearRegression.h" #include "protocol/CounterProtocolXH.h" +#ifdef unix +#include "common/utils/QKafkaUtil.h" +#endif + class CounterDevice : public QObject { Q_OBJECT @@ -37,6 +40,9 @@ int getIsUse(); void setIsUse(int isUse); + int getRefChannelNo(); + void setRefChannelNo(int refChannelNo); + QString getRefChannelCode(); void setRefChannelCode(QString refChannelCode); @@ -56,9 +62,12 @@ int formColIndex; QSerialPortUtil serialUtil; - QKafkaUtil kafkaUtil; QByteArray dataBuff; +#ifdef unix + QKafkaUtil kafkaUtil; +#endif + void afterFramePhase(CounterDataDto * counterData); void calcResidualClockData(qlonglong tm); diff --git a/CounterRealTime/CounterRealTime.pro b/CounterRealTime/CounterRealTime.pro index c323f04..f990ff3 100644 --- a/CounterRealTime/CounterRealTime.pro +++ b/CounterRealTime/CounterRealTime.pro @@ -49,7 +49,8 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka++ -lrdkafka +win32: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka++ -lrdkafka INCLUDEPATH += $$PWD/include/librdkafka DEPENDPATH += $$PWD/include/librdkafka diff --git a/CounterRealTime/CounterSettingForm.cpp b/CounterRealTime/CounterSettingForm.cpp index c1945d1..bc43ac7 100644 --- a/CounterRealTime/CounterSettingForm.cpp +++ b/CounterRealTime/CounterSettingForm.cpp @@ -335,7 +335,7 @@ active = activeListRight.at(i - 8)->isChecked(); } - CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1)); + CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1, 2, 10, QLatin1Char('0'))); if (channelPrt != nullptr) { bool isUpdated = isChannelSettingUpdated(i, channelPrt); @@ -362,7 +362,7 @@ newChannel->setChannelCode(channelCode); newChannel->setDelays(QString::number(delay)); - ConstCache::getInstance().channelMap.insert(QString("%1-%2").arg(deviceId).arg(i+1), newChannel); + ConstCache::getInstance().channelMap.insert(QString("%1-%2").arg(deviceId).arg(i+1, 2, 10, QLatin1Char('0')), newChannel); QJsonObject channelObj; channelObj.insert("id", ""); @@ -412,7 +412,7 @@ activeListLeft.at(i)->setCheckable(true); activeListRight.at(i)->setCheckable(true); - CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1)); + CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1, 2, 10, QLatin1Char('0'))); if (channelPrt != nullptr) { QString channelCode = channelPrt->getChannelCode(); // 通道钟号 @@ -429,7 +429,7 @@ } } - CounterChannel * channelRightPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1+8)); + CounterChannel * channelRightPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1+8, 2, 10, QLatin1Char('0'))); if (channelRightPrt != nullptr) { QString channelCode = channelRightPrt->getChannelCode(); // 通道钟号 diff --git a/CounterRealTime/CounterWindowRT.cpp b/CounterRealTime/CounterWindowRT.cpp index 30adf9b..78815d7 100644 --- a/CounterRealTime/CounterWindowRT.cpp +++ b/CounterRealTime/CounterWindowRT.cpp @@ -76,6 +76,7 @@ file.close(); } +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { // kafka consumer kafkaConsumer = new QKafkaConsumer(this); @@ -93,6 +94,7 @@ alarmMsgConsumer->start(); connect(alarmMsgConsumer, &QKafkaConsumer::messageRecieved, this, &CounterWindowRT::onAlarmMessageReceived); } +#endif // 绘制界面上的表格 initChannelForm(); @@ -100,6 +102,10 @@ // 显示时钟 每秒更新 connect(TimerCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &CounterWindowRT::updateDateAndTime); TimerCounterUtil::getInstance().clockCounter->start(1000); + QTimer::singleShot(30000, [=](){ + // 定时执行主备一致性监测 + connect(TimerCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &CounterWindowRT::watchStandbyConsistency); + }); // 重新选择显示多少个计数器 connect(settingForm, &CounterSettingForm::swiftDisplayLoop, this, &CounterWindowRT::updateDeviceWidget); @@ -182,7 +188,7 @@ } for (int i = 0; i < devSet.size(); i++) { - getChannelList(devSet.toList().at(i)); + getChannelList(devSet.values().at(i)); } } } @@ -233,6 +239,13 @@ } updateDeviceWidget(); + +// qDebug() << "loop A: " << ConstCache::getInstance().deviceIdLoopA; +// qDebug() << "loop B: " << ConstCache::getInstance().deviceIdLoopB; + + // 查找主路参考钟在备路计数器的测量通道 + // 查找备路参考钟在主路计数器的测量通道 + findRefAndMeasureChannel(); } } QList CounterWindowRT::getClockNumList() @@ -262,7 +275,8 @@ { // for (int i = 0; i <= 16; i++) { - ConstCache::getInstance().channelMap.remove(QString("%1-%2").arg(deviceId).arg(i)); + QString channelKey = QString("%1-%2").arg(deviceId).arg(i); + ConstCache::getInstance().channelMap.remove(channelKey); } // 将通道绘制在界面上 @@ -273,7 +287,7 @@ QJsonObject channelItem = channelArray.at(i).toObject(); QString channelId = channelItem.value("id").toString(); // 通道ID QString channelCode = channelItem.value("channelCode").toString(); // 通道钟号 - QString channelNo = QString::number(channelItem.value("channelNo").toInt()); // 通道序号 + QString channelNo = QString("%1").arg(channelItem.value("channelNo").toInt(), 2, 10, QLatin1Char('0')); // 通道序号 QString delays = channelItem.value("delays").toString(); // 通道时延值 QString isUse = channelItem.value("isUse").toString(); QString name = channelItem.value("name").toString(); @@ -292,6 +306,14 @@ // 添加到通道的集合中 key=deviceId-channelNo ConstCache::getInstance().channelMap.insert(deviceId + "-" + channelNo, channel); + + if (channelCode.isEmpty() == false && active == true) { + CounterDevice * counterDev = ConstCache::getInstance().deviceMap.value(deviceId); + if (counterDev != nullptr) { + QStringList channelBase; + channelBase << QString::number(counterDev->getIsUse()) << channelCode; + } + } } } } @@ -314,10 +336,12 @@ layoutChannelPage->setMargin(3); // 留出边框的位置 // 左右布局中是垂直布局,用于显示通道 - QVBoxLayout * layoutChannelLeft = new QVBoxLayout(); - QVBoxLayout * layoutChannelRight = new QVBoxLayout(); + QVBoxLayout * layoutChannelLeft = new QVBoxLayout(); // 最左侧显示设备简称 + QVBoxLayout * layoutChannelMain = new QVBoxLayout(); // 中间显示参考通道 + QVBoxLayout * layoutChannelRight = new QVBoxLayout(); // 最右侧显示归算参考通道 字号小一号 layoutChannelLeft->setSpacing(0); + layoutChannelMain->setSpacing(0); layoutChannelRight->setSpacing(0); // 设备标题的Label @@ -330,55 +354,76 @@ // 设备参考通道的Label QLabel * labDevRef = new QLabel(widgetDev); labDevRef->setProperty("labType", QString("devRef%1").arg(count)); // 样式表属性 - labDevRef->setText(QString("REF: %1").arg("1000")); + labDevRef->setText(QString("REF: %1").arg("10000")); labDevRef->setAlignment(Qt::AlignCenter); // 文字居中显示 devRefList.append(labDevRef); + // 设置归算使用的参考通道Label + QLabel * labCompDevRef = new QLabel(widgetDev); + labCompDevRef->setProperty("labType", QString("devCompRef%1").arg(count)); // 样式表属性 + labCompDevRef->setText(QString("%1").arg("主备时差")); + labCompDevRef->setAlignment(Qt::AlignCenter); // 文字居中显示 + devCompRefList.append(labCompDevRef); + if (count == 4) { labDevTitle->setMaximumHeight(80); // 设置固定高度 labDevTitle->setMinimumHeight(80); labDevRef->setMaximumHeight(80); // 设置固定高度 labDevRef->setMinimumHeight(80); + + labCompDevRef->setMaximumHeight(80); // 设置固定高度 + labCompDevRef->setMinimumHeight(80); } else { labDevTitle->setMaximumHeight(60); // 设置固定高度 labDevTitle->setMinimumHeight(60); labDevRef->setMaximumHeight(60); // 设置固定高度 labDevRef->setMinimumHeight(60); + + labCompDevRef->setMaximumHeight(60); // 设置固定高度 + labCompDevRef->setMinimumHeight(60); } // 左侧显示设备简称,右侧显示参考通道名 layoutChannelLeft->addWidget(labDevTitle); - layoutChannelRight->addWidget(labDevRef); + layoutChannelMain->addWidget(labDevRef); + layoutChannelRight->addWidget(labCompDevRef); // 每个计数器显示16个通道 for ( int i = 0; i < 16; i++ ) { QLabelDblClick * labChannelName = new QLabelDblClick(widgetDev); // 通道名 QLabelDblClick * labChannelValue = new QLabelDblClick(widgetDev); // 通道测量值 + QLabelDblClick * labComputeValue = new QLabelDblClick(widgetDev); // 通道归算值 // 默认显示内容 - labChannelName->setText(QString("CH%1").arg(i+1, 2, 10, QLatin1Char('0'))); + labChannelName->setText(QString("%1: 10000").arg(i+1, 2, 10, QLatin1Char('0'))); labChannelValue->setText("0.000000000000"); + labComputeValue->setText(""); // css不支持的样式用代码实现 - labChannelName->setMargin(10); - labChannelValue->setMargin(10); + labChannelName->setMargin(5); + labChannelValue->setMargin(5); labChannelValue->setAlignment(Qt::AlignRight | Qt::AlignVCenter); + labComputeValue->setMargin(5); + labComputeValue->setAlignment(Qt::AlignRight | Qt::AlignVCenter); // 奇偶显示不同的背景色 if (i % 2 == 0) { labChannelName->setProperty("labType", QString("channelNameEven%1").arg(count)); labChannelValue->setProperty("labType", QString("channelValueEven%1").arg(count)); + labComputeValue->setProperty("labType", QString("computeValueEven%1").arg(count)); } else { labChannelName->setProperty("labType", QString("channelNameOdd%1").arg(count)); labChannelValue->setProperty("labType", QString("channelValueOdd%1").arg(count)); + labComputeValue->setProperty("labType", QString("computeValueOdd%1").arg(count)); } layoutChannelLeft->addWidget(labChannelName); - layoutChannelRight->addWidget(labChannelValue); + layoutChannelMain->addWidget(labChannelValue); + layoutChannelRight->addWidget(labComputeValue); // 添加通道名称的双击事件,显示数据和残差图表 connect(labChannelName, &QLabelDblClick::doubleClicked, this, &CounterWindowRT::onChannelNameLabelDblClicked); @@ -386,16 +431,21 @@ channelNameList.append(labChannelName); channelValueList.append(labChannelValue); + computeValueList.append(labComputeValue); // 左下角和右下角的圆角处理 if (i == 15) { labChannelName->setStyleSheet("border-bottom-left-radius: 10px;"); - labChannelValue->setStyleSheet("border-bottom-right-radius: 10px;"); + labComputeValue->setStyleSheet("border-bottom-right-radius: 10px;"); } } layoutChannelPage->addLayout(layoutChannelLeft); + layoutChannelPage->addLayout(layoutChannelMain); layoutChannelPage->addLayout(layoutChannelRight); + layoutChannelPage->setStretch(0, 35); + layoutChannelPage->setStretch(1, 50); + layoutChannelPage->setStretch(2, 15); widgetDev->setLayout(layoutChannelPage); } } @@ -407,13 +457,19 @@ // 参考通道号 int refChNo = messageArray.at(0).toObject().value("data").toObject().value("channelRefNo").toInt(); + CounterDevice * counter = ConstCache::getInstance().deviceMap.value(deviceId); + if (counter == nullptr) { + return; + } + counter->setRefChannelNo(refChNo); + // 根据设备id 从map中取出列索引的值 - int devIdx = ConstCache::getInstance().deviceMap.value(deviceId)->getFormColIndex(); + int devIdx = counter->getFormColIndex(); if (devIdx < devRefList.size()) { // 参考通道的显示 QString refText = devRefList.at(devIdx)->text(); - channelNameList.at(devIdx * 16 + refChNo - 1)->setText(QString("CH%1:%2").arg(refChNo, 2, 10, QLatin1Char('0')).arg(refText.right(refText.length() - 4))); + channelNameList.at(devIdx * 16 + refChNo - 1)->setText(QString("%1:%2").arg(refChNo, 2, 10, QLatin1Char('0')).arg(refText.right(refText.length() - 4))); if (alarmDev.contains(deviceId) == true) { @@ -433,11 +489,11 @@ for (int i = 0; i < messageArray.size(); i++) { QJsonObject channelDataItem = messageArray.at(i).toObject(); - QString channelNo = QString::number(channelDataItem.value("channelNo").toInt()); // 通道序号 + QString channelNo = QString("%1").arg(channelDataItem.value("channelNo").toInt(), 2, 10, QLatin1Char('0')); // 通道序号 channelDataJsonMap.insert(channelNo, channelDataItem); } - CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo)); + CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo, 2, 10, QLatin1Char('0'))); double refDelay = 0.0; if (refChanPtr != nullptr && refChanPtr->getDelays().isEmpty() == false) { refDelay = refChanPtr->getDelays().toDouble(); @@ -454,11 +510,10 @@ continue; } - CounterChannel * channel = ConstCache::getInstance().channelMap.value(deviceId + "-" + channelNo); // 从map中找到对应的通道 - - if (channelDataJsonMap.contains(channelNo) == true) + CounterChannel * channel = ConstCache::getInstance().channelMap.value(deviceId + "-" + channelNoStr); // 从map中找到对应的通道 + if (channelDataJsonMap.contains(channelNoStr) == true) { - QJsonObject channelDataItem = channelDataJsonMap.value(channelNo); + QJsonObject channelDataItem = channelDataJsonMap.value(channelNoStr); // 通道Label的序号 int channelIdx = devIdx * 16 + channelDataItem.value("channelNo").toInt() - 1; @@ -483,19 +538,20 @@ double valueMinusDelay = channelDataItem.value("data").toObject().value("dataValue").toString().toDouble() - delay * 1E-9 + refDelay * 1E-9; // 设置通道名和测量值的QLabel - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); channelValueList.at(channelIdx)->setText(QString::number(valueMinusDelay, 'f', 12)); channelNameList.at(channelIdx)->setProperty("channelId", channel->getChannelId()); channelNameList.at(channelIdx)->setProperty("deviceId", deviceId); - channelNameList.at(channelIdx)->setProperty("channelNo", channelNo); + channelNameList.at(channelIdx)->setProperty("channelNo", channelNoStr); channelValueList.at(channelIdx)->setProperty("channelId", channel->getChannelId()); channelValueList.at(channelIdx)->setProperty("deviceId", deviceId); - channelValueList.at(channelIdx)->setProperty("channelNo", channelNo); + channelValueList.at(channelIdx)->setProperty("channelNo", channelNoStr); } else { - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg("-")); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg("-")); channelValueList.at(channelIdx)->setText(""); + computeValueList.at(channelIdx)->setText(""); } } else { // 计数器返回的无测量值的通道处理逻辑 @@ -503,6 +559,7 @@ // 没有测量值的通道清空 channelValueList.at(channelIdx)->setText(""); + computeValueList.at(channelIdx)->setText(""); // 当通道启用时显示通道离线 不再判断后台传回来的状态 // 当通道未启用时显示正常状态 @@ -510,12 +567,12 @@ channelNameList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value("channelOffline")); channelValueList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value("channelOffline")); - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); } else { channelNameList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value(channelNameList.at(channelIdx)->property("labType").toString())); channelValueList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value(channelValueList.at(channelIdx)->property("labType").toString())); - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg("-")); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg("-")); } } } @@ -523,7 +580,7 @@ void CounterWindowRT::updateDeviceAlarm(QJsonArray alarmList) { - qDebug() << alarmList; +// qDebug() << alarmList; for (int i = 0; i < alarmList.size(); i++) { QJsonObject alarmData = alarmList.at(i).toObject(); @@ -532,7 +589,7 @@ QString alarmCode = alarmData.value("alarmCode").toString(); QString status = alarmData.value("status").toString(); - qDebug() << alarmCode << deviceId << channelId; +// qDebug() << alarmCode << deviceId << channelId; // 如果报警状态不是正在报警 status==0 或者报警设备不是计数器 则不处理 if (status != "0" || ConstCache::getInstance().deviceMap.contains(deviceId) == false) @@ -560,6 +617,92 @@ } } +void CounterWindowRT::findRefAndMeasureChannel() +{ + // 查询主路的参考通道的钟编号 + QString masterKey = QString("%1-%2").arg(ConstCache::getInstance().deviceIdLoopA.at(0)).arg("01"); // 暂时固定为01通道 + CounterChannel * refChannelMaster = ConstCache::getInstance().channelMap.value(masterKey); // 主路参考的钟编号 + + // 查询主路参考通道在备路的测量通道 + for (QString channelKey : ConstCache::getInstance().channelMap.keys()) { + QString deviceId = channelKey.split("-")[0]; + if (ConstCache::getInstance().deviceIdLoopB.contains(deviceId)) { + CounterChannel * channel = ConstCache::getInstance().channelMap.value(channelKey); + if (channel->getChannelCode() == refChannelMaster->getChannelCode()) { + QStringList masterInfo; + masterInfo << refChannelMaster->getChannelCode() << deviceId << channel->getChannelId() << channel->getChannelNo(); + ConstCache::getInstance().loopInfos.append(masterInfo); + + break; + } + } + } + + // 查询备路的参考通道钟编号 + QString slaveKey = QString("%1-%2").arg(ConstCache::getInstance().deviceIdLoopB.at(0)).arg("01"); // 暂时固定为01通道 + CounterChannel * refChannelSlave = ConstCache::getInstance().channelMap.value(slaveKey); // 备路参考的钟编号 + + // 查询备路参考通道在主路的测量通道 + for (QString channelKey : ConstCache::getInstance().channelMap.keys()) { + QString deviceId = channelKey.split("-")[0]; + if (ConstCache::getInstance().deviceIdLoopA.contains(deviceId)) { + CounterChannel * channel = ConstCache::getInstance().channelMap.value(channelKey); + if (channel->getChannelCode() == refChannelSlave->getChannelCode()) { + QStringList slaveInfo; + slaveInfo << refChannelSlave->getChannelCode() << deviceId << channel->getChannelId() << channel->getChannelNo(); + ConstCache::getInstance().loopInfos.append(slaveInfo); + + break; + } + } + } + +// qDebug() << ConstCache::getInstance().loopInfos.at(0); +// qDebug() << ConstCache::getInstance().loopInfos.at(1); +// qDebug() << ConstCache::getInstance().channelMap; +} + +double CounterWindowRT::calculateAvgStandbyTimeDiff(QList thisChannel, + QList refChannel, + QList standbyChannel) +{ + double avgTimeDiff = 0.0; + + if (thisChannel.isEmpty() || refChannel.isEmpty() || standbyChannel.isEmpty()) { + return avgTimeDiff; + } + + double sumThis = 0.0; + double avgThis = 0.0; + int countThis = 0; + for (QStringList thisData : thisChannel) { + sumThis += thisData.at(1).toDouble(); + countThis++; + } + avgThis = sumThis / countThis * 1.0; + + double sumRef = 0.0; + double avgRef = 0.0; + int countRef = 0; + for (QStringList refData : refChannel) { + sumRef += refData.at(1).toDouble(); + countRef++; + } + avgRef = sumRef / countRef * 1.0; + + double sumStandby = 0.0; + double avgStandby = 0.0; + int countStandby = 0; + for (QStringList standbyData : standbyChannel) { + sumStandby += standbyData.at(1).toDouble(); + countStandby++; + } + avgStandby = sumStandby / countStandby * 1.0; + + avgTimeDiff = avgThis - avgRef - avgStandby; + return avgTimeDiff; +} + void CounterWindowRT::updateDateAndTime() { QString date = QDate::currentDate().toString("yyyy-MM-dd"); @@ -567,6 +710,171 @@ ui->labTime->setText(date + " " + time); } +void CounterWindowRT::watchStandbyConsistency() +{ + quint8 second = QTime::currentTime().second(); + if (second % SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND == 0) { + qDebug() << "watchStandbyConsistency: " << QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"); + // 1. 遍历所有的主路计数器 + for (QString devAId : ConstCache::getInstance().deviceIdLoopA) { + // 2. 遍历主路计数器的每一个通道(除参考通道外) + for (QString key : ConstCache::getInstance().channelMap.keys()) { + if (key.contains(devAId) == false) { + continue; + } else { + // A当前通道 + CounterChannel * channel = ConstCache::getInstance().channelMap.value(key); + QString channelCode = channel->getChannelCode(); // 钟编号 + QString channelNo = channel->getChannelNo(); // 通道号 + + if (channelNo == "00" || channelNo == "01" || channelCode.isEmpty()) { + continue; + } + + // B备路参考通道在主路的测量通道 + CounterChannel * standbyRefChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(ConstCache::getInstance().loopInfos.at(1).at(1)).arg(ConstCache::getInstance().loopInfos.at(1).at(3))); + + // 3. 获得通道的钟编号、通道号,找到对应钟编号、通道号在备路对应的通道 + // C对应的备路测量通道 + QString standbyKey = ""; + CounterChannel * standbyChannel = nullptr; + if (ConstCache::getInstance().standbyMap.contains(key) == false) { + // 在对路计数器中找 并存入standbyMap + for (QString standbyDevId : ConstCache::getInstance().deviceIdLoopB) { + // 通道号和钟编号都匹配 + standbyChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(standbyDevId).arg(channelNo)); + if (standbyChannel != nullptr && standbyChannel->getChannelCode() == channelCode) { + standbyKey = QString("%1-%2").arg(standbyDevId).arg(channelNo); + ConstCache::getInstance().standbyMap.insert(key, standbyKey); + } + } + } else { + standbyKey = ConstCache::getInstance().standbyMap.value(key); + standbyChannel = ConstCache::getInstance().channelMap.value(standbyKey); + } + + // 4. 取当前通道的最后10个历史数据 channel + QList thisChannelDataList; + if (channel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + thisChannelDataList = channel->getHisData().mid(channel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 5. 取备路参考通道最后10个历史数据 standbyRefChannel + QList standbyRefChannelDataList; + if (standbyRefChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyRefChannelDataList = standbyRefChannel->getHisData().mid(standbyRefChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 6. 取备路计数器对应通道的最后10个历史数据 standbyChannel + QList standbyChannelDataList; + if (standbyChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyChannelDataList = standbyChannel->getHisData().mid(standbyChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 7. 计算当前通道相对备路参考钟的时差 与备路对应通道的时差做差 + if (thisChannelDataList.isEmpty() || standbyChannelDataList.isEmpty()) { + continue; + } + double avgTimeDiff = calculateAvgStandbyTimeDiff(thisChannelDataList, standbyRefChannelDataList, standbyChannelDataList); + + // 8. 显示在界面上 + CounterDevice * devicePtr = ConstCache::getInstance().deviceMap.value(devAId); + if (devicePtr != nullptr && SettingConfig::getInstance().MASTER == devicePtr->getIsUse()) + { + int devIdx = devicePtr->getFormColIndex(); + + // 通道Label的序号 + int channelIdx = devIdx * 16 + channelNo.toInt() - 1; + computeValueList.at(channelIdx)->setText(QString::number(avgTimeDiff * 1E9, 'f', 3)); + } + } + } + } + + // 8. 遍历所有的备路计数器 + for (QString devBId : ConstCache::getInstance().deviceIdLoopB) { + // 2. 遍历主路计数器的每一个通道(除参考通道外) + for (QString key : ConstCache::getInstance().channelMap.keys()) { + if (key.contains(devBId) == false) { + continue; + } else { + // A当前通道 + CounterChannel * channel = ConstCache::getInstance().channelMap.value(key); + QString channelCode = channel->getChannelCode(); // 钟编号 + QString channelNo = channel->getChannelNo(); // 通道号 + + if (channelNo == "00" || channelNo == "01" || channelCode.isEmpty()) { + continue; + } + + // B主路参考通道在主路的测量通道 + CounterChannel * standbyRefChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(ConstCache::getInstance().loopInfos.at(0).at(1)).arg(ConstCache::getInstance().loopInfos.at(0).at(3))); + + // 3. 获得通道的钟编号、通道号,找到对应钟编号、通道号在备路对应的通道 + // C对应的主路测量通道 + QString standbyKey = ""; + CounterChannel * standbyChannel = nullptr; + if (ConstCache::getInstance().standbyMap.contains(key) == false) { + // 在对路计数器中找 并存入standbyMap + for (QString standbyDevId : ConstCache::getInstance().deviceIdLoopA) { + // 通道号和钟编号都匹配 + standbyChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(standbyDevId).arg(channelNo)); + if (standbyChannel != nullptr && standbyChannel->getChannelCode() == channelCode) { + standbyKey = QString("%1-%2").arg(standbyDevId).arg(channelNo); + ConstCache::getInstance().standbyMap.insert(key, standbyKey); + } + } + } else { + standbyKey = ConstCache::getInstance().standbyMap.value(key); + standbyChannel = ConstCache::getInstance().channelMap.value(standbyKey); + } + + // 4. 取当前通道的最后10个历史数据 channel + QList thisChannelDataList; + if (channel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + thisChannelDataList = channel->getHisData().mid(channel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 5. 取主路参考通道最后10个历史数据 standbyRefChannel + QList standbyRefChannelDataList; + if (standbyRefChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyRefChannelDataList = standbyRefChannel->getHisData().mid(standbyRefChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 6. 取主路计数器对应通道的最后10个历史数据 standbyChannel + QList standbyChannelDataList; + if (standbyChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyChannelDataList = standbyChannel->getHisData().mid(standbyChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 7. 计算当前通道相对主路参考钟的时差 与主路对应通道的时差做差 + if (thisChannelDataList.isEmpty() || standbyChannelDataList.isEmpty()) { + continue; + } + double avgTimeDiff = calculateAvgStandbyTimeDiff(thisChannelDataList, standbyRefChannelDataList, standbyChannelDataList); + + // 8. 显示在界面上 + CounterDevice * devicePtr = ConstCache::getInstance().deviceMap.value(devBId); + if (devicePtr != nullptr && SettingConfig::getInstance().MASTER == devicePtr->getIsUse()) + { + int devIdx = devicePtr->getFormColIndex(); + + // 通道Label的序号 + int channelIdx = devIdx * 16 + channelNo.toInt() - 1; + computeValueList.at(channelIdx)->setText(QString::number(avgTimeDiff * 1E9, 'f', 3)); + } + } + } + } + } +} + void CounterWindowRT::on_btnMenuSetting_clicked() { settingForm->setWindowModality(Qt::ApplicationModal); @@ -600,8 +908,10 @@ // 将lab列表的数量置0 devTitleList.resize(0); devRefList.resize(0); + devCompRefList.resize(0); channelNameList.resize(0); channelValueList.resize(0); + computeValueList.resize(0); initDevAndChannelForm(SettingConfig::getInstance().DISPLAY_COUNT); } @@ -620,14 +930,20 @@ devTitleList.at(i)->setText(dev->getDeviceName()); // 设备名称 dev->setFormColIndex(i); } + for (int j = 1; j < 16; j++) + { + computeValueList.at(i * 16 + j)->setText("-"); + } } else { devTitleList.at(i)->setText(""); devRefList.at(i)->setText(""); + devCompRefList.at(i)->setText(""); for (int j = 0; j < 16; j++) { channelNameList.at(i * 16 + j)->setText(""); channelValueList.at(i * 16 + j)->setText(""); + computeValueList.at(i * 16 + j)->setText(""); } } } @@ -685,7 +1001,7 @@ // 参考通道 int refChNo = messageArray.at(0).toObject().value("data").toObject().value("channelRefNo").toInt(); - CounterChannel * refChann = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo)); + CounterChannel * refChann = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo, 2, 10, QLatin1Char('0'))); if (refChann != nullptr) { if (devIdx < devRefList.size()) { @@ -704,7 +1020,7 @@ void CounterWindowRT::onKafkaMessageReceived(QJsonObject message) { qDebug() << message; - std::cout << QString(QJsonDocument(message).toJson(QJsonDocument::Compact)).toStdString() << std::endl; + std::cout << "kafka message received: " << std::endl << QString(QJsonDocument(message).toJson(QJsonDocument::Compact)).toStdString() << std::endl; // 找不到deviceId deviceType operation三个必填项 直接返回 if (message.contains("deviceId") == false || message.contains("operation") == false || message.contains("deviceType") == false) { @@ -732,7 +1048,7 @@ void CounterWindowRT::onAlarmMessageReceived(QJsonObject alarmMsg) { qDebug() << alarmMsg; - std::cout << QString(QJsonDocument(alarmMsg).toJson(QJsonDocument::Compact)).toStdString() << std::endl; + std::cout << "alarm message received: " << std::endl << QString(QJsonDocument(alarmMsg).toJson(QJsonDocument::Compact)).toStdString() << std::endl; QString deviceId = alarmMsg.value("deviceId").toString(); QString channelId = alarmMsg.value("channelId").toString(); diff --git a/CounterRealTime/CounterDevice.cpp b/CounterRealTime/CounterDevice.cpp index 4ff6565..f656746 100644 --- a/CounterRealTime/CounterDevice.cpp +++ b/CounterRealTime/CounterDevice.cpp @@ -9,11 +9,13 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &CounterDevice::dataReceivedHandler); +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); kafkaUtil.createProducer(); } +#endif } CounterDevice::~CounterDevice() @@ -78,6 +80,15 @@ this->refChannelCode = refChannelCode; } +int CounterDevice::getRefChannelNo() +{ + return this->refChannelNo; +} +void CounterDevice::setRefChannelNo(int refChannelNo) +{ + this->refChannelNo = refChannelNo; +} + bool CounterDevice::isSerialOpen() { return this->serialUtil.isOpen(); @@ -156,7 +167,7 @@ msgLogFilename = msgLogFilename.arg((hour / 6) * 6, 2, 10, QLatin1Char('0')); msgLogFilename = msgLogFilename.arg((hour / 6) * 6 + 5, 2, 10, QLatin1Char('0')); - CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(counterData->channelRefId)); + CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(counterData->channelRefId, 2, 10, QLatin1Char('0'))); this->refChannelNo = counterData->channelRefId; double refDelay = 0.0; if (refChanPtr != nullptr && refChanPtr->getDelays().isEmpty() == false) { @@ -186,7 +197,7 @@ } // 加到hisDataList中 用于绘制图表 - CounterChannel * channelPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i)); + CounterChannel * channelPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i, 2, 10, QLatin1Char('0'))); if (channelPtr != nullptr && channelPtr->isActive() == true) { // 通道时延值 并计算 减去时延值的测量值 @@ -210,6 +221,7 @@ statusObj.insert("master", SettingConfig::getInstance().MASTER); statusObj.insert("deviceId", deviceId); +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { if (SettingConfig::getInstance().MASTER == 0) @@ -227,6 +239,7 @@ kafkaUtil.produceMessage(SettingConfig::getInstance().KAFKA_STATUS_TOPIC, QString(QJsonDocument(statusObj).toJson(QJsonDocument::Compact))); } } +#endif QLogUtil::writeMessageLogByDate(date, msgLogFilename, QString(QJsonDocument(messageArray).toJson(QJsonDocument::Compact))); diff --git a/CounterRealTime/CounterDevice.h b/CounterRealTime/CounterDevice.h index c4d003d..68390c8 100644 --- a/CounterRealTime/CounterDevice.h +++ b/CounterRealTime/CounterDevice.h @@ -6,7 +6,6 @@ #include "CounterChannel.h" #include "common/utils/QSerialPortUtil.h" -#include "common/utils/QKafkaUtil.h" #include "common/utils/QByteUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" @@ -14,6 +13,10 @@ #include "common/LinearRegression.h" #include "protocol/CounterProtocolXH.h" +#ifdef unix +#include "common/utils/QKafkaUtil.h" +#endif + class CounterDevice : public QObject { Q_OBJECT @@ -37,6 +40,9 @@ int getIsUse(); void setIsUse(int isUse); + int getRefChannelNo(); + void setRefChannelNo(int refChannelNo); + QString getRefChannelCode(); void setRefChannelCode(QString refChannelCode); @@ -56,9 +62,12 @@ int formColIndex; QSerialPortUtil serialUtil; - QKafkaUtil kafkaUtil; QByteArray dataBuff; +#ifdef unix + QKafkaUtil kafkaUtil; +#endif + void afterFramePhase(CounterDataDto * counterData); void calcResidualClockData(qlonglong tm); diff --git a/CounterRealTime/CounterRealTime.pro b/CounterRealTime/CounterRealTime.pro index c323f04..f990ff3 100644 --- a/CounterRealTime/CounterRealTime.pro +++ b/CounterRealTime/CounterRealTime.pro @@ -49,7 +49,8 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka++ -lrdkafka +win32: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka++ -lrdkafka INCLUDEPATH += $$PWD/include/librdkafka DEPENDPATH += $$PWD/include/librdkafka diff --git a/CounterRealTime/CounterSettingForm.cpp b/CounterRealTime/CounterSettingForm.cpp index c1945d1..bc43ac7 100644 --- a/CounterRealTime/CounterSettingForm.cpp +++ b/CounterRealTime/CounterSettingForm.cpp @@ -335,7 +335,7 @@ active = activeListRight.at(i - 8)->isChecked(); } - CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1)); + CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1, 2, 10, QLatin1Char('0'))); if (channelPrt != nullptr) { bool isUpdated = isChannelSettingUpdated(i, channelPrt); @@ -362,7 +362,7 @@ newChannel->setChannelCode(channelCode); newChannel->setDelays(QString::number(delay)); - ConstCache::getInstance().channelMap.insert(QString("%1-%2").arg(deviceId).arg(i+1), newChannel); + ConstCache::getInstance().channelMap.insert(QString("%1-%2").arg(deviceId).arg(i+1, 2, 10, QLatin1Char('0')), newChannel); QJsonObject channelObj; channelObj.insert("id", ""); @@ -412,7 +412,7 @@ activeListLeft.at(i)->setCheckable(true); activeListRight.at(i)->setCheckable(true); - CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1)); + CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1, 2, 10, QLatin1Char('0'))); if (channelPrt != nullptr) { QString channelCode = channelPrt->getChannelCode(); // 通道钟号 @@ -429,7 +429,7 @@ } } - CounterChannel * channelRightPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1+8)); + CounterChannel * channelRightPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1+8, 2, 10, QLatin1Char('0'))); if (channelRightPrt != nullptr) { QString channelCode = channelRightPrt->getChannelCode(); // 通道钟号 diff --git a/CounterRealTime/CounterWindowRT.cpp b/CounterRealTime/CounterWindowRT.cpp index 30adf9b..78815d7 100644 --- a/CounterRealTime/CounterWindowRT.cpp +++ b/CounterRealTime/CounterWindowRT.cpp @@ -76,6 +76,7 @@ file.close(); } +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { // kafka consumer kafkaConsumer = new QKafkaConsumer(this); @@ -93,6 +94,7 @@ alarmMsgConsumer->start(); connect(alarmMsgConsumer, &QKafkaConsumer::messageRecieved, this, &CounterWindowRT::onAlarmMessageReceived); } +#endif // 绘制界面上的表格 initChannelForm(); @@ -100,6 +102,10 @@ // 显示时钟 每秒更新 connect(TimerCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &CounterWindowRT::updateDateAndTime); TimerCounterUtil::getInstance().clockCounter->start(1000); + QTimer::singleShot(30000, [=](){ + // 定时执行主备一致性监测 + connect(TimerCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &CounterWindowRT::watchStandbyConsistency); + }); // 重新选择显示多少个计数器 connect(settingForm, &CounterSettingForm::swiftDisplayLoop, this, &CounterWindowRT::updateDeviceWidget); @@ -182,7 +188,7 @@ } for (int i = 0; i < devSet.size(); i++) { - getChannelList(devSet.toList().at(i)); + getChannelList(devSet.values().at(i)); } } } @@ -233,6 +239,13 @@ } updateDeviceWidget(); + +// qDebug() << "loop A: " << ConstCache::getInstance().deviceIdLoopA; +// qDebug() << "loop B: " << ConstCache::getInstance().deviceIdLoopB; + + // 查找主路参考钟在备路计数器的测量通道 + // 查找备路参考钟在主路计数器的测量通道 + findRefAndMeasureChannel(); } } QList CounterWindowRT::getClockNumList() @@ -262,7 +275,8 @@ { // for (int i = 0; i <= 16; i++) { - ConstCache::getInstance().channelMap.remove(QString("%1-%2").arg(deviceId).arg(i)); + QString channelKey = QString("%1-%2").arg(deviceId).arg(i); + ConstCache::getInstance().channelMap.remove(channelKey); } // 将通道绘制在界面上 @@ -273,7 +287,7 @@ QJsonObject channelItem = channelArray.at(i).toObject(); QString channelId = channelItem.value("id").toString(); // 通道ID QString channelCode = channelItem.value("channelCode").toString(); // 通道钟号 - QString channelNo = QString::number(channelItem.value("channelNo").toInt()); // 通道序号 + QString channelNo = QString("%1").arg(channelItem.value("channelNo").toInt(), 2, 10, QLatin1Char('0')); // 通道序号 QString delays = channelItem.value("delays").toString(); // 通道时延值 QString isUse = channelItem.value("isUse").toString(); QString name = channelItem.value("name").toString(); @@ -292,6 +306,14 @@ // 添加到通道的集合中 key=deviceId-channelNo ConstCache::getInstance().channelMap.insert(deviceId + "-" + channelNo, channel); + + if (channelCode.isEmpty() == false && active == true) { + CounterDevice * counterDev = ConstCache::getInstance().deviceMap.value(deviceId); + if (counterDev != nullptr) { + QStringList channelBase; + channelBase << QString::number(counterDev->getIsUse()) << channelCode; + } + } } } } @@ -314,10 +336,12 @@ layoutChannelPage->setMargin(3); // 留出边框的位置 // 左右布局中是垂直布局,用于显示通道 - QVBoxLayout * layoutChannelLeft = new QVBoxLayout(); - QVBoxLayout * layoutChannelRight = new QVBoxLayout(); + QVBoxLayout * layoutChannelLeft = new QVBoxLayout(); // 最左侧显示设备简称 + QVBoxLayout * layoutChannelMain = new QVBoxLayout(); // 中间显示参考通道 + QVBoxLayout * layoutChannelRight = new QVBoxLayout(); // 最右侧显示归算参考通道 字号小一号 layoutChannelLeft->setSpacing(0); + layoutChannelMain->setSpacing(0); layoutChannelRight->setSpacing(0); // 设备标题的Label @@ -330,55 +354,76 @@ // 设备参考通道的Label QLabel * labDevRef = new QLabel(widgetDev); labDevRef->setProperty("labType", QString("devRef%1").arg(count)); // 样式表属性 - labDevRef->setText(QString("REF: %1").arg("1000")); + labDevRef->setText(QString("REF: %1").arg("10000")); labDevRef->setAlignment(Qt::AlignCenter); // 文字居中显示 devRefList.append(labDevRef); + // 设置归算使用的参考通道Label + QLabel * labCompDevRef = new QLabel(widgetDev); + labCompDevRef->setProperty("labType", QString("devCompRef%1").arg(count)); // 样式表属性 + labCompDevRef->setText(QString("%1").arg("主备时差")); + labCompDevRef->setAlignment(Qt::AlignCenter); // 文字居中显示 + devCompRefList.append(labCompDevRef); + if (count == 4) { labDevTitle->setMaximumHeight(80); // 设置固定高度 labDevTitle->setMinimumHeight(80); labDevRef->setMaximumHeight(80); // 设置固定高度 labDevRef->setMinimumHeight(80); + + labCompDevRef->setMaximumHeight(80); // 设置固定高度 + labCompDevRef->setMinimumHeight(80); } else { labDevTitle->setMaximumHeight(60); // 设置固定高度 labDevTitle->setMinimumHeight(60); labDevRef->setMaximumHeight(60); // 设置固定高度 labDevRef->setMinimumHeight(60); + + labCompDevRef->setMaximumHeight(60); // 设置固定高度 + labCompDevRef->setMinimumHeight(60); } // 左侧显示设备简称,右侧显示参考通道名 layoutChannelLeft->addWidget(labDevTitle); - layoutChannelRight->addWidget(labDevRef); + layoutChannelMain->addWidget(labDevRef); + layoutChannelRight->addWidget(labCompDevRef); // 每个计数器显示16个通道 for ( int i = 0; i < 16; i++ ) { QLabelDblClick * labChannelName = new QLabelDblClick(widgetDev); // 通道名 QLabelDblClick * labChannelValue = new QLabelDblClick(widgetDev); // 通道测量值 + QLabelDblClick * labComputeValue = new QLabelDblClick(widgetDev); // 通道归算值 // 默认显示内容 - labChannelName->setText(QString("CH%1").arg(i+1, 2, 10, QLatin1Char('0'))); + labChannelName->setText(QString("%1: 10000").arg(i+1, 2, 10, QLatin1Char('0'))); labChannelValue->setText("0.000000000000"); + labComputeValue->setText(""); // css不支持的样式用代码实现 - labChannelName->setMargin(10); - labChannelValue->setMargin(10); + labChannelName->setMargin(5); + labChannelValue->setMargin(5); labChannelValue->setAlignment(Qt::AlignRight | Qt::AlignVCenter); + labComputeValue->setMargin(5); + labComputeValue->setAlignment(Qt::AlignRight | Qt::AlignVCenter); // 奇偶显示不同的背景色 if (i % 2 == 0) { labChannelName->setProperty("labType", QString("channelNameEven%1").arg(count)); labChannelValue->setProperty("labType", QString("channelValueEven%1").arg(count)); + labComputeValue->setProperty("labType", QString("computeValueEven%1").arg(count)); } else { labChannelName->setProperty("labType", QString("channelNameOdd%1").arg(count)); labChannelValue->setProperty("labType", QString("channelValueOdd%1").arg(count)); + labComputeValue->setProperty("labType", QString("computeValueOdd%1").arg(count)); } layoutChannelLeft->addWidget(labChannelName); - layoutChannelRight->addWidget(labChannelValue); + layoutChannelMain->addWidget(labChannelValue); + layoutChannelRight->addWidget(labComputeValue); // 添加通道名称的双击事件,显示数据和残差图表 connect(labChannelName, &QLabelDblClick::doubleClicked, this, &CounterWindowRT::onChannelNameLabelDblClicked); @@ -386,16 +431,21 @@ channelNameList.append(labChannelName); channelValueList.append(labChannelValue); + computeValueList.append(labComputeValue); // 左下角和右下角的圆角处理 if (i == 15) { labChannelName->setStyleSheet("border-bottom-left-radius: 10px;"); - labChannelValue->setStyleSheet("border-bottom-right-radius: 10px;"); + labComputeValue->setStyleSheet("border-bottom-right-radius: 10px;"); } } layoutChannelPage->addLayout(layoutChannelLeft); + layoutChannelPage->addLayout(layoutChannelMain); layoutChannelPage->addLayout(layoutChannelRight); + layoutChannelPage->setStretch(0, 35); + layoutChannelPage->setStretch(1, 50); + layoutChannelPage->setStretch(2, 15); widgetDev->setLayout(layoutChannelPage); } } @@ -407,13 +457,19 @@ // 参考通道号 int refChNo = messageArray.at(0).toObject().value("data").toObject().value("channelRefNo").toInt(); + CounterDevice * counter = ConstCache::getInstance().deviceMap.value(deviceId); + if (counter == nullptr) { + return; + } + counter->setRefChannelNo(refChNo); + // 根据设备id 从map中取出列索引的值 - int devIdx = ConstCache::getInstance().deviceMap.value(deviceId)->getFormColIndex(); + int devIdx = counter->getFormColIndex(); if (devIdx < devRefList.size()) { // 参考通道的显示 QString refText = devRefList.at(devIdx)->text(); - channelNameList.at(devIdx * 16 + refChNo - 1)->setText(QString("CH%1:%2").arg(refChNo, 2, 10, QLatin1Char('0')).arg(refText.right(refText.length() - 4))); + channelNameList.at(devIdx * 16 + refChNo - 1)->setText(QString("%1:%2").arg(refChNo, 2, 10, QLatin1Char('0')).arg(refText.right(refText.length() - 4))); if (alarmDev.contains(deviceId) == true) { @@ -433,11 +489,11 @@ for (int i = 0; i < messageArray.size(); i++) { QJsonObject channelDataItem = messageArray.at(i).toObject(); - QString channelNo = QString::number(channelDataItem.value("channelNo").toInt()); // 通道序号 + QString channelNo = QString("%1").arg(channelDataItem.value("channelNo").toInt(), 2, 10, QLatin1Char('0')); // 通道序号 channelDataJsonMap.insert(channelNo, channelDataItem); } - CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo)); + CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo, 2, 10, QLatin1Char('0'))); double refDelay = 0.0; if (refChanPtr != nullptr && refChanPtr->getDelays().isEmpty() == false) { refDelay = refChanPtr->getDelays().toDouble(); @@ -454,11 +510,10 @@ continue; } - CounterChannel * channel = ConstCache::getInstance().channelMap.value(deviceId + "-" + channelNo); // 从map中找到对应的通道 - - if (channelDataJsonMap.contains(channelNo) == true) + CounterChannel * channel = ConstCache::getInstance().channelMap.value(deviceId + "-" + channelNoStr); // 从map中找到对应的通道 + if (channelDataJsonMap.contains(channelNoStr) == true) { - QJsonObject channelDataItem = channelDataJsonMap.value(channelNo); + QJsonObject channelDataItem = channelDataJsonMap.value(channelNoStr); // 通道Label的序号 int channelIdx = devIdx * 16 + channelDataItem.value("channelNo").toInt() - 1; @@ -483,19 +538,20 @@ double valueMinusDelay = channelDataItem.value("data").toObject().value("dataValue").toString().toDouble() - delay * 1E-9 + refDelay * 1E-9; // 设置通道名和测量值的QLabel - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); channelValueList.at(channelIdx)->setText(QString::number(valueMinusDelay, 'f', 12)); channelNameList.at(channelIdx)->setProperty("channelId", channel->getChannelId()); channelNameList.at(channelIdx)->setProperty("deviceId", deviceId); - channelNameList.at(channelIdx)->setProperty("channelNo", channelNo); + channelNameList.at(channelIdx)->setProperty("channelNo", channelNoStr); channelValueList.at(channelIdx)->setProperty("channelId", channel->getChannelId()); channelValueList.at(channelIdx)->setProperty("deviceId", deviceId); - channelValueList.at(channelIdx)->setProperty("channelNo", channelNo); + channelValueList.at(channelIdx)->setProperty("channelNo", channelNoStr); } else { - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg("-")); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg("-")); channelValueList.at(channelIdx)->setText(""); + computeValueList.at(channelIdx)->setText(""); } } else { // 计数器返回的无测量值的通道处理逻辑 @@ -503,6 +559,7 @@ // 没有测量值的通道清空 channelValueList.at(channelIdx)->setText(""); + computeValueList.at(channelIdx)->setText(""); // 当通道启用时显示通道离线 不再判断后台传回来的状态 // 当通道未启用时显示正常状态 @@ -510,12 +567,12 @@ channelNameList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value("channelOffline")); channelValueList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value("channelOffline")); - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); } else { channelNameList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value(channelNameList.at(channelIdx)->property("labType").toString())); channelValueList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value(channelValueList.at(channelIdx)->property("labType").toString())); - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg("-")); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg("-")); } } } @@ -523,7 +580,7 @@ void CounterWindowRT::updateDeviceAlarm(QJsonArray alarmList) { - qDebug() << alarmList; +// qDebug() << alarmList; for (int i = 0; i < alarmList.size(); i++) { QJsonObject alarmData = alarmList.at(i).toObject(); @@ -532,7 +589,7 @@ QString alarmCode = alarmData.value("alarmCode").toString(); QString status = alarmData.value("status").toString(); - qDebug() << alarmCode << deviceId << channelId; +// qDebug() << alarmCode << deviceId << channelId; // 如果报警状态不是正在报警 status==0 或者报警设备不是计数器 则不处理 if (status != "0" || ConstCache::getInstance().deviceMap.contains(deviceId) == false) @@ -560,6 +617,92 @@ } } +void CounterWindowRT::findRefAndMeasureChannel() +{ + // 查询主路的参考通道的钟编号 + QString masterKey = QString("%1-%2").arg(ConstCache::getInstance().deviceIdLoopA.at(0)).arg("01"); // 暂时固定为01通道 + CounterChannel * refChannelMaster = ConstCache::getInstance().channelMap.value(masterKey); // 主路参考的钟编号 + + // 查询主路参考通道在备路的测量通道 + for (QString channelKey : ConstCache::getInstance().channelMap.keys()) { + QString deviceId = channelKey.split("-")[0]; + if (ConstCache::getInstance().deviceIdLoopB.contains(deviceId)) { + CounterChannel * channel = ConstCache::getInstance().channelMap.value(channelKey); + if (channel->getChannelCode() == refChannelMaster->getChannelCode()) { + QStringList masterInfo; + masterInfo << refChannelMaster->getChannelCode() << deviceId << channel->getChannelId() << channel->getChannelNo(); + ConstCache::getInstance().loopInfos.append(masterInfo); + + break; + } + } + } + + // 查询备路的参考通道钟编号 + QString slaveKey = QString("%1-%2").arg(ConstCache::getInstance().deviceIdLoopB.at(0)).arg("01"); // 暂时固定为01通道 + CounterChannel * refChannelSlave = ConstCache::getInstance().channelMap.value(slaveKey); // 备路参考的钟编号 + + // 查询备路参考通道在主路的测量通道 + for (QString channelKey : ConstCache::getInstance().channelMap.keys()) { + QString deviceId = channelKey.split("-")[0]; + if (ConstCache::getInstance().deviceIdLoopA.contains(deviceId)) { + CounterChannel * channel = ConstCache::getInstance().channelMap.value(channelKey); + if (channel->getChannelCode() == refChannelSlave->getChannelCode()) { + QStringList slaveInfo; + slaveInfo << refChannelSlave->getChannelCode() << deviceId << channel->getChannelId() << channel->getChannelNo(); + ConstCache::getInstance().loopInfos.append(slaveInfo); + + break; + } + } + } + +// qDebug() << ConstCache::getInstance().loopInfos.at(0); +// qDebug() << ConstCache::getInstance().loopInfos.at(1); +// qDebug() << ConstCache::getInstance().channelMap; +} + +double CounterWindowRT::calculateAvgStandbyTimeDiff(QList thisChannel, + QList refChannel, + QList standbyChannel) +{ + double avgTimeDiff = 0.0; + + if (thisChannel.isEmpty() || refChannel.isEmpty() || standbyChannel.isEmpty()) { + return avgTimeDiff; + } + + double sumThis = 0.0; + double avgThis = 0.0; + int countThis = 0; + for (QStringList thisData : thisChannel) { + sumThis += thisData.at(1).toDouble(); + countThis++; + } + avgThis = sumThis / countThis * 1.0; + + double sumRef = 0.0; + double avgRef = 0.0; + int countRef = 0; + for (QStringList refData : refChannel) { + sumRef += refData.at(1).toDouble(); + countRef++; + } + avgRef = sumRef / countRef * 1.0; + + double sumStandby = 0.0; + double avgStandby = 0.0; + int countStandby = 0; + for (QStringList standbyData : standbyChannel) { + sumStandby += standbyData.at(1).toDouble(); + countStandby++; + } + avgStandby = sumStandby / countStandby * 1.0; + + avgTimeDiff = avgThis - avgRef - avgStandby; + return avgTimeDiff; +} + void CounterWindowRT::updateDateAndTime() { QString date = QDate::currentDate().toString("yyyy-MM-dd"); @@ -567,6 +710,171 @@ ui->labTime->setText(date + " " + time); } +void CounterWindowRT::watchStandbyConsistency() +{ + quint8 second = QTime::currentTime().second(); + if (second % SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND == 0) { + qDebug() << "watchStandbyConsistency: " << QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"); + // 1. 遍历所有的主路计数器 + for (QString devAId : ConstCache::getInstance().deviceIdLoopA) { + // 2. 遍历主路计数器的每一个通道(除参考通道外) + for (QString key : ConstCache::getInstance().channelMap.keys()) { + if (key.contains(devAId) == false) { + continue; + } else { + // A当前通道 + CounterChannel * channel = ConstCache::getInstance().channelMap.value(key); + QString channelCode = channel->getChannelCode(); // 钟编号 + QString channelNo = channel->getChannelNo(); // 通道号 + + if (channelNo == "00" || channelNo == "01" || channelCode.isEmpty()) { + continue; + } + + // B备路参考通道在主路的测量通道 + CounterChannel * standbyRefChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(ConstCache::getInstance().loopInfos.at(1).at(1)).arg(ConstCache::getInstance().loopInfos.at(1).at(3))); + + // 3. 获得通道的钟编号、通道号,找到对应钟编号、通道号在备路对应的通道 + // C对应的备路测量通道 + QString standbyKey = ""; + CounterChannel * standbyChannel = nullptr; + if (ConstCache::getInstance().standbyMap.contains(key) == false) { + // 在对路计数器中找 并存入standbyMap + for (QString standbyDevId : ConstCache::getInstance().deviceIdLoopB) { + // 通道号和钟编号都匹配 + standbyChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(standbyDevId).arg(channelNo)); + if (standbyChannel != nullptr && standbyChannel->getChannelCode() == channelCode) { + standbyKey = QString("%1-%2").arg(standbyDevId).arg(channelNo); + ConstCache::getInstance().standbyMap.insert(key, standbyKey); + } + } + } else { + standbyKey = ConstCache::getInstance().standbyMap.value(key); + standbyChannel = ConstCache::getInstance().channelMap.value(standbyKey); + } + + // 4. 取当前通道的最后10个历史数据 channel + QList thisChannelDataList; + if (channel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + thisChannelDataList = channel->getHisData().mid(channel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 5. 取备路参考通道最后10个历史数据 standbyRefChannel + QList standbyRefChannelDataList; + if (standbyRefChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyRefChannelDataList = standbyRefChannel->getHisData().mid(standbyRefChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 6. 取备路计数器对应通道的最后10个历史数据 standbyChannel + QList standbyChannelDataList; + if (standbyChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyChannelDataList = standbyChannel->getHisData().mid(standbyChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 7. 计算当前通道相对备路参考钟的时差 与备路对应通道的时差做差 + if (thisChannelDataList.isEmpty() || standbyChannelDataList.isEmpty()) { + continue; + } + double avgTimeDiff = calculateAvgStandbyTimeDiff(thisChannelDataList, standbyRefChannelDataList, standbyChannelDataList); + + // 8. 显示在界面上 + CounterDevice * devicePtr = ConstCache::getInstance().deviceMap.value(devAId); + if (devicePtr != nullptr && SettingConfig::getInstance().MASTER == devicePtr->getIsUse()) + { + int devIdx = devicePtr->getFormColIndex(); + + // 通道Label的序号 + int channelIdx = devIdx * 16 + channelNo.toInt() - 1; + computeValueList.at(channelIdx)->setText(QString::number(avgTimeDiff * 1E9, 'f', 3)); + } + } + } + } + + // 8. 遍历所有的备路计数器 + for (QString devBId : ConstCache::getInstance().deviceIdLoopB) { + // 2. 遍历主路计数器的每一个通道(除参考通道外) + for (QString key : ConstCache::getInstance().channelMap.keys()) { + if (key.contains(devBId) == false) { + continue; + } else { + // A当前通道 + CounterChannel * channel = ConstCache::getInstance().channelMap.value(key); + QString channelCode = channel->getChannelCode(); // 钟编号 + QString channelNo = channel->getChannelNo(); // 通道号 + + if (channelNo == "00" || channelNo == "01" || channelCode.isEmpty()) { + continue; + } + + // B主路参考通道在主路的测量通道 + CounterChannel * standbyRefChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(ConstCache::getInstance().loopInfos.at(0).at(1)).arg(ConstCache::getInstance().loopInfos.at(0).at(3))); + + // 3. 获得通道的钟编号、通道号,找到对应钟编号、通道号在备路对应的通道 + // C对应的主路测量通道 + QString standbyKey = ""; + CounterChannel * standbyChannel = nullptr; + if (ConstCache::getInstance().standbyMap.contains(key) == false) { + // 在对路计数器中找 并存入standbyMap + for (QString standbyDevId : ConstCache::getInstance().deviceIdLoopA) { + // 通道号和钟编号都匹配 + standbyChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(standbyDevId).arg(channelNo)); + if (standbyChannel != nullptr && standbyChannel->getChannelCode() == channelCode) { + standbyKey = QString("%1-%2").arg(standbyDevId).arg(channelNo); + ConstCache::getInstance().standbyMap.insert(key, standbyKey); + } + } + } else { + standbyKey = ConstCache::getInstance().standbyMap.value(key); + standbyChannel = ConstCache::getInstance().channelMap.value(standbyKey); + } + + // 4. 取当前通道的最后10个历史数据 channel + QList thisChannelDataList; + if (channel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + thisChannelDataList = channel->getHisData().mid(channel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 5. 取主路参考通道最后10个历史数据 standbyRefChannel + QList standbyRefChannelDataList; + if (standbyRefChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyRefChannelDataList = standbyRefChannel->getHisData().mid(standbyRefChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 6. 取主路计数器对应通道的最后10个历史数据 standbyChannel + QList standbyChannelDataList; + if (standbyChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyChannelDataList = standbyChannel->getHisData().mid(standbyChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 7. 计算当前通道相对主路参考钟的时差 与主路对应通道的时差做差 + if (thisChannelDataList.isEmpty() || standbyChannelDataList.isEmpty()) { + continue; + } + double avgTimeDiff = calculateAvgStandbyTimeDiff(thisChannelDataList, standbyRefChannelDataList, standbyChannelDataList); + + // 8. 显示在界面上 + CounterDevice * devicePtr = ConstCache::getInstance().deviceMap.value(devBId); + if (devicePtr != nullptr && SettingConfig::getInstance().MASTER == devicePtr->getIsUse()) + { + int devIdx = devicePtr->getFormColIndex(); + + // 通道Label的序号 + int channelIdx = devIdx * 16 + channelNo.toInt() - 1; + computeValueList.at(channelIdx)->setText(QString::number(avgTimeDiff * 1E9, 'f', 3)); + } + } + } + } + } +} + void CounterWindowRT::on_btnMenuSetting_clicked() { settingForm->setWindowModality(Qt::ApplicationModal); @@ -600,8 +908,10 @@ // 将lab列表的数量置0 devTitleList.resize(0); devRefList.resize(0); + devCompRefList.resize(0); channelNameList.resize(0); channelValueList.resize(0); + computeValueList.resize(0); initDevAndChannelForm(SettingConfig::getInstance().DISPLAY_COUNT); } @@ -620,14 +930,20 @@ devTitleList.at(i)->setText(dev->getDeviceName()); // 设备名称 dev->setFormColIndex(i); } + for (int j = 1; j < 16; j++) + { + computeValueList.at(i * 16 + j)->setText("-"); + } } else { devTitleList.at(i)->setText(""); devRefList.at(i)->setText(""); + devCompRefList.at(i)->setText(""); for (int j = 0; j < 16; j++) { channelNameList.at(i * 16 + j)->setText(""); channelValueList.at(i * 16 + j)->setText(""); + computeValueList.at(i * 16 + j)->setText(""); } } } @@ -685,7 +1001,7 @@ // 参考通道 int refChNo = messageArray.at(0).toObject().value("data").toObject().value("channelRefNo").toInt(); - CounterChannel * refChann = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo)); + CounterChannel * refChann = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo, 2, 10, QLatin1Char('0'))); if (refChann != nullptr) { if (devIdx < devRefList.size()) { @@ -704,7 +1020,7 @@ void CounterWindowRT::onKafkaMessageReceived(QJsonObject message) { qDebug() << message; - std::cout << QString(QJsonDocument(message).toJson(QJsonDocument::Compact)).toStdString() << std::endl; + std::cout << "kafka message received: " << std::endl << QString(QJsonDocument(message).toJson(QJsonDocument::Compact)).toStdString() << std::endl; // 找不到deviceId deviceType operation三个必填项 直接返回 if (message.contains("deviceId") == false || message.contains("operation") == false || message.contains("deviceType") == false) { @@ -732,7 +1048,7 @@ void CounterWindowRT::onAlarmMessageReceived(QJsonObject alarmMsg) { qDebug() << alarmMsg; - std::cout << QString(QJsonDocument(alarmMsg).toJson(QJsonDocument::Compact)).toStdString() << std::endl; + std::cout << "alarm message received: " << std::endl << QString(QJsonDocument(alarmMsg).toJson(QJsonDocument::Compact)).toStdString() << std::endl; QString deviceId = alarmMsg.value("deviceId").toString(); QString channelId = alarmMsg.value("channelId").toString(); diff --git a/CounterRealTime/CounterWindowRT.h b/CounterRealTime/CounterWindowRT.h index b672cfc..b4eea96 100644 --- a/CounterRealTime/CounterWindowRT.h +++ b/CounterRealTime/CounterWindowRT.h @@ -17,10 +17,13 @@ #include "CounterSettingForm.h" #include "common/utils/SettingConfig.h" #include "common/utils/TimerCounterUtil.h" -#include "common/utils/QKafkaConsumer.h" #include "common/HttpRequestController.h" #include "common/HttpServer.h" +#ifdef unix +#include "common/utils/QKafkaConsumer.h" +#endif + QT_BEGIN_NAMESPACE namespace Ui { class CounterWindowRT; } QT_END_NAMESPACE @@ -47,12 +50,17 @@ QVector devTitleList; // 计数器设备标题的QLabel集合 QVector devRefList; // Ref通道 + QVector devCompRefList; // 归算Ref通道 QVector channelNameList; // 通道名的QLabel集合 QVector channelValueList; // 通道测量值的QLabel集合 + QVector computeValueList; // 通道归算值的QLabel集合 HttpRequestController * httpReq; + +#ifdef unix QKafkaConsumer * kafkaConsumer; QKafkaConsumer * alarmMsgConsumer; +#endif QVector alarmDev; QVector offlineDev; @@ -67,9 +75,13 @@ void initDevAndChannelForm(int count); void updateChannelDataForm(QJsonArray messageArray); void updateDeviceAlarm(QJsonArray alarmList); + void findRefAndMeasureChannel(); // 查找主备路的测量参考通道以及各自的测量通道 + double calculateAvgStandbyTimeDiff(QList thisChannel, QList refChannel, QList standbyChannel); + private slots: void updateDateAndTime(); + void watchStandbyConsistency(); int initHttpToken(); diff --git a/CounterRealTime/CounterDevice.cpp b/CounterRealTime/CounterDevice.cpp index 4ff6565..f656746 100644 --- a/CounterRealTime/CounterDevice.cpp +++ b/CounterRealTime/CounterDevice.cpp @@ -9,11 +9,13 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &CounterDevice::dataReceivedHandler); +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); kafkaUtil.createProducer(); } +#endif } CounterDevice::~CounterDevice() @@ -78,6 +80,15 @@ this->refChannelCode = refChannelCode; } +int CounterDevice::getRefChannelNo() +{ + return this->refChannelNo; +} +void CounterDevice::setRefChannelNo(int refChannelNo) +{ + this->refChannelNo = refChannelNo; +} + bool CounterDevice::isSerialOpen() { return this->serialUtil.isOpen(); @@ -156,7 +167,7 @@ msgLogFilename = msgLogFilename.arg((hour / 6) * 6, 2, 10, QLatin1Char('0')); msgLogFilename = msgLogFilename.arg((hour / 6) * 6 + 5, 2, 10, QLatin1Char('0')); - CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(counterData->channelRefId)); + CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(counterData->channelRefId, 2, 10, QLatin1Char('0'))); this->refChannelNo = counterData->channelRefId; double refDelay = 0.0; if (refChanPtr != nullptr && refChanPtr->getDelays().isEmpty() == false) { @@ -186,7 +197,7 @@ } // 加到hisDataList中 用于绘制图表 - CounterChannel * channelPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i)); + CounterChannel * channelPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i, 2, 10, QLatin1Char('0'))); if (channelPtr != nullptr && channelPtr->isActive() == true) { // 通道时延值 并计算 减去时延值的测量值 @@ -210,6 +221,7 @@ statusObj.insert("master", SettingConfig::getInstance().MASTER); statusObj.insert("deviceId", deviceId); +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { if (SettingConfig::getInstance().MASTER == 0) @@ -227,6 +239,7 @@ kafkaUtil.produceMessage(SettingConfig::getInstance().KAFKA_STATUS_TOPIC, QString(QJsonDocument(statusObj).toJson(QJsonDocument::Compact))); } } +#endif QLogUtil::writeMessageLogByDate(date, msgLogFilename, QString(QJsonDocument(messageArray).toJson(QJsonDocument::Compact))); diff --git a/CounterRealTime/CounterDevice.h b/CounterRealTime/CounterDevice.h index c4d003d..68390c8 100644 --- a/CounterRealTime/CounterDevice.h +++ b/CounterRealTime/CounterDevice.h @@ -6,7 +6,6 @@ #include "CounterChannel.h" #include "common/utils/QSerialPortUtil.h" -#include "common/utils/QKafkaUtil.h" #include "common/utils/QByteUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" @@ -14,6 +13,10 @@ #include "common/LinearRegression.h" #include "protocol/CounterProtocolXH.h" +#ifdef unix +#include "common/utils/QKafkaUtil.h" +#endif + class CounterDevice : public QObject { Q_OBJECT @@ -37,6 +40,9 @@ int getIsUse(); void setIsUse(int isUse); + int getRefChannelNo(); + void setRefChannelNo(int refChannelNo); + QString getRefChannelCode(); void setRefChannelCode(QString refChannelCode); @@ -56,9 +62,12 @@ int formColIndex; QSerialPortUtil serialUtil; - QKafkaUtil kafkaUtil; QByteArray dataBuff; +#ifdef unix + QKafkaUtil kafkaUtil; +#endif + void afterFramePhase(CounterDataDto * counterData); void calcResidualClockData(qlonglong tm); diff --git a/CounterRealTime/CounterRealTime.pro b/CounterRealTime/CounterRealTime.pro index c323f04..f990ff3 100644 --- a/CounterRealTime/CounterRealTime.pro +++ b/CounterRealTime/CounterRealTime.pro @@ -49,7 +49,8 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka++ -lrdkafka +win32: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka++ -lrdkafka INCLUDEPATH += $$PWD/include/librdkafka DEPENDPATH += $$PWD/include/librdkafka diff --git a/CounterRealTime/CounterSettingForm.cpp b/CounterRealTime/CounterSettingForm.cpp index c1945d1..bc43ac7 100644 --- a/CounterRealTime/CounterSettingForm.cpp +++ b/CounterRealTime/CounterSettingForm.cpp @@ -335,7 +335,7 @@ active = activeListRight.at(i - 8)->isChecked(); } - CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1)); + CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1, 2, 10, QLatin1Char('0'))); if (channelPrt != nullptr) { bool isUpdated = isChannelSettingUpdated(i, channelPrt); @@ -362,7 +362,7 @@ newChannel->setChannelCode(channelCode); newChannel->setDelays(QString::number(delay)); - ConstCache::getInstance().channelMap.insert(QString("%1-%2").arg(deviceId).arg(i+1), newChannel); + ConstCache::getInstance().channelMap.insert(QString("%1-%2").arg(deviceId).arg(i+1, 2, 10, QLatin1Char('0')), newChannel); QJsonObject channelObj; channelObj.insert("id", ""); @@ -412,7 +412,7 @@ activeListLeft.at(i)->setCheckable(true); activeListRight.at(i)->setCheckable(true); - CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1)); + CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1, 2, 10, QLatin1Char('0'))); if (channelPrt != nullptr) { QString channelCode = channelPrt->getChannelCode(); // 通道钟号 @@ -429,7 +429,7 @@ } } - CounterChannel * channelRightPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1+8)); + CounterChannel * channelRightPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1+8, 2, 10, QLatin1Char('0'))); if (channelRightPrt != nullptr) { QString channelCode = channelRightPrt->getChannelCode(); // 通道钟号 diff --git a/CounterRealTime/CounterWindowRT.cpp b/CounterRealTime/CounterWindowRT.cpp index 30adf9b..78815d7 100644 --- a/CounterRealTime/CounterWindowRT.cpp +++ b/CounterRealTime/CounterWindowRT.cpp @@ -76,6 +76,7 @@ file.close(); } +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { // kafka consumer kafkaConsumer = new QKafkaConsumer(this); @@ -93,6 +94,7 @@ alarmMsgConsumer->start(); connect(alarmMsgConsumer, &QKafkaConsumer::messageRecieved, this, &CounterWindowRT::onAlarmMessageReceived); } +#endif // 绘制界面上的表格 initChannelForm(); @@ -100,6 +102,10 @@ // 显示时钟 每秒更新 connect(TimerCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &CounterWindowRT::updateDateAndTime); TimerCounterUtil::getInstance().clockCounter->start(1000); + QTimer::singleShot(30000, [=](){ + // 定时执行主备一致性监测 + connect(TimerCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &CounterWindowRT::watchStandbyConsistency); + }); // 重新选择显示多少个计数器 connect(settingForm, &CounterSettingForm::swiftDisplayLoop, this, &CounterWindowRT::updateDeviceWidget); @@ -182,7 +188,7 @@ } for (int i = 0; i < devSet.size(); i++) { - getChannelList(devSet.toList().at(i)); + getChannelList(devSet.values().at(i)); } } } @@ -233,6 +239,13 @@ } updateDeviceWidget(); + +// qDebug() << "loop A: " << ConstCache::getInstance().deviceIdLoopA; +// qDebug() << "loop B: " << ConstCache::getInstance().deviceIdLoopB; + + // 查找主路参考钟在备路计数器的测量通道 + // 查找备路参考钟在主路计数器的测量通道 + findRefAndMeasureChannel(); } } QList CounterWindowRT::getClockNumList() @@ -262,7 +275,8 @@ { // for (int i = 0; i <= 16; i++) { - ConstCache::getInstance().channelMap.remove(QString("%1-%2").arg(deviceId).arg(i)); + QString channelKey = QString("%1-%2").arg(deviceId).arg(i); + ConstCache::getInstance().channelMap.remove(channelKey); } // 将通道绘制在界面上 @@ -273,7 +287,7 @@ QJsonObject channelItem = channelArray.at(i).toObject(); QString channelId = channelItem.value("id").toString(); // 通道ID QString channelCode = channelItem.value("channelCode").toString(); // 通道钟号 - QString channelNo = QString::number(channelItem.value("channelNo").toInt()); // 通道序号 + QString channelNo = QString("%1").arg(channelItem.value("channelNo").toInt(), 2, 10, QLatin1Char('0')); // 通道序号 QString delays = channelItem.value("delays").toString(); // 通道时延值 QString isUse = channelItem.value("isUse").toString(); QString name = channelItem.value("name").toString(); @@ -292,6 +306,14 @@ // 添加到通道的集合中 key=deviceId-channelNo ConstCache::getInstance().channelMap.insert(deviceId + "-" + channelNo, channel); + + if (channelCode.isEmpty() == false && active == true) { + CounterDevice * counterDev = ConstCache::getInstance().deviceMap.value(deviceId); + if (counterDev != nullptr) { + QStringList channelBase; + channelBase << QString::number(counterDev->getIsUse()) << channelCode; + } + } } } } @@ -314,10 +336,12 @@ layoutChannelPage->setMargin(3); // 留出边框的位置 // 左右布局中是垂直布局,用于显示通道 - QVBoxLayout * layoutChannelLeft = new QVBoxLayout(); - QVBoxLayout * layoutChannelRight = new QVBoxLayout(); + QVBoxLayout * layoutChannelLeft = new QVBoxLayout(); // 最左侧显示设备简称 + QVBoxLayout * layoutChannelMain = new QVBoxLayout(); // 中间显示参考通道 + QVBoxLayout * layoutChannelRight = new QVBoxLayout(); // 最右侧显示归算参考通道 字号小一号 layoutChannelLeft->setSpacing(0); + layoutChannelMain->setSpacing(0); layoutChannelRight->setSpacing(0); // 设备标题的Label @@ -330,55 +354,76 @@ // 设备参考通道的Label QLabel * labDevRef = new QLabel(widgetDev); labDevRef->setProperty("labType", QString("devRef%1").arg(count)); // 样式表属性 - labDevRef->setText(QString("REF: %1").arg("1000")); + labDevRef->setText(QString("REF: %1").arg("10000")); labDevRef->setAlignment(Qt::AlignCenter); // 文字居中显示 devRefList.append(labDevRef); + // 设置归算使用的参考通道Label + QLabel * labCompDevRef = new QLabel(widgetDev); + labCompDevRef->setProperty("labType", QString("devCompRef%1").arg(count)); // 样式表属性 + labCompDevRef->setText(QString("%1").arg("主备时差")); + labCompDevRef->setAlignment(Qt::AlignCenter); // 文字居中显示 + devCompRefList.append(labCompDevRef); + if (count == 4) { labDevTitle->setMaximumHeight(80); // 设置固定高度 labDevTitle->setMinimumHeight(80); labDevRef->setMaximumHeight(80); // 设置固定高度 labDevRef->setMinimumHeight(80); + + labCompDevRef->setMaximumHeight(80); // 设置固定高度 + labCompDevRef->setMinimumHeight(80); } else { labDevTitle->setMaximumHeight(60); // 设置固定高度 labDevTitle->setMinimumHeight(60); labDevRef->setMaximumHeight(60); // 设置固定高度 labDevRef->setMinimumHeight(60); + + labCompDevRef->setMaximumHeight(60); // 设置固定高度 + labCompDevRef->setMinimumHeight(60); } // 左侧显示设备简称,右侧显示参考通道名 layoutChannelLeft->addWidget(labDevTitle); - layoutChannelRight->addWidget(labDevRef); + layoutChannelMain->addWidget(labDevRef); + layoutChannelRight->addWidget(labCompDevRef); // 每个计数器显示16个通道 for ( int i = 0; i < 16; i++ ) { QLabelDblClick * labChannelName = new QLabelDblClick(widgetDev); // 通道名 QLabelDblClick * labChannelValue = new QLabelDblClick(widgetDev); // 通道测量值 + QLabelDblClick * labComputeValue = new QLabelDblClick(widgetDev); // 通道归算值 // 默认显示内容 - labChannelName->setText(QString("CH%1").arg(i+1, 2, 10, QLatin1Char('0'))); + labChannelName->setText(QString("%1: 10000").arg(i+1, 2, 10, QLatin1Char('0'))); labChannelValue->setText("0.000000000000"); + labComputeValue->setText(""); // css不支持的样式用代码实现 - labChannelName->setMargin(10); - labChannelValue->setMargin(10); + labChannelName->setMargin(5); + labChannelValue->setMargin(5); labChannelValue->setAlignment(Qt::AlignRight | Qt::AlignVCenter); + labComputeValue->setMargin(5); + labComputeValue->setAlignment(Qt::AlignRight | Qt::AlignVCenter); // 奇偶显示不同的背景色 if (i % 2 == 0) { labChannelName->setProperty("labType", QString("channelNameEven%1").arg(count)); labChannelValue->setProperty("labType", QString("channelValueEven%1").arg(count)); + labComputeValue->setProperty("labType", QString("computeValueEven%1").arg(count)); } else { labChannelName->setProperty("labType", QString("channelNameOdd%1").arg(count)); labChannelValue->setProperty("labType", QString("channelValueOdd%1").arg(count)); + labComputeValue->setProperty("labType", QString("computeValueOdd%1").arg(count)); } layoutChannelLeft->addWidget(labChannelName); - layoutChannelRight->addWidget(labChannelValue); + layoutChannelMain->addWidget(labChannelValue); + layoutChannelRight->addWidget(labComputeValue); // 添加通道名称的双击事件,显示数据和残差图表 connect(labChannelName, &QLabelDblClick::doubleClicked, this, &CounterWindowRT::onChannelNameLabelDblClicked); @@ -386,16 +431,21 @@ channelNameList.append(labChannelName); channelValueList.append(labChannelValue); + computeValueList.append(labComputeValue); // 左下角和右下角的圆角处理 if (i == 15) { labChannelName->setStyleSheet("border-bottom-left-radius: 10px;"); - labChannelValue->setStyleSheet("border-bottom-right-radius: 10px;"); + labComputeValue->setStyleSheet("border-bottom-right-radius: 10px;"); } } layoutChannelPage->addLayout(layoutChannelLeft); + layoutChannelPage->addLayout(layoutChannelMain); layoutChannelPage->addLayout(layoutChannelRight); + layoutChannelPage->setStretch(0, 35); + layoutChannelPage->setStretch(1, 50); + layoutChannelPage->setStretch(2, 15); widgetDev->setLayout(layoutChannelPage); } } @@ -407,13 +457,19 @@ // 参考通道号 int refChNo = messageArray.at(0).toObject().value("data").toObject().value("channelRefNo").toInt(); + CounterDevice * counter = ConstCache::getInstance().deviceMap.value(deviceId); + if (counter == nullptr) { + return; + } + counter->setRefChannelNo(refChNo); + // 根据设备id 从map中取出列索引的值 - int devIdx = ConstCache::getInstance().deviceMap.value(deviceId)->getFormColIndex(); + int devIdx = counter->getFormColIndex(); if (devIdx < devRefList.size()) { // 参考通道的显示 QString refText = devRefList.at(devIdx)->text(); - channelNameList.at(devIdx * 16 + refChNo - 1)->setText(QString("CH%1:%2").arg(refChNo, 2, 10, QLatin1Char('0')).arg(refText.right(refText.length() - 4))); + channelNameList.at(devIdx * 16 + refChNo - 1)->setText(QString("%1:%2").arg(refChNo, 2, 10, QLatin1Char('0')).arg(refText.right(refText.length() - 4))); if (alarmDev.contains(deviceId) == true) { @@ -433,11 +489,11 @@ for (int i = 0; i < messageArray.size(); i++) { QJsonObject channelDataItem = messageArray.at(i).toObject(); - QString channelNo = QString::number(channelDataItem.value("channelNo").toInt()); // 通道序号 + QString channelNo = QString("%1").arg(channelDataItem.value("channelNo").toInt(), 2, 10, QLatin1Char('0')); // 通道序号 channelDataJsonMap.insert(channelNo, channelDataItem); } - CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo)); + CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo, 2, 10, QLatin1Char('0'))); double refDelay = 0.0; if (refChanPtr != nullptr && refChanPtr->getDelays().isEmpty() == false) { refDelay = refChanPtr->getDelays().toDouble(); @@ -454,11 +510,10 @@ continue; } - CounterChannel * channel = ConstCache::getInstance().channelMap.value(deviceId + "-" + channelNo); // 从map中找到对应的通道 - - if (channelDataJsonMap.contains(channelNo) == true) + CounterChannel * channel = ConstCache::getInstance().channelMap.value(deviceId + "-" + channelNoStr); // 从map中找到对应的通道 + if (channelDataJsonMap.contains(channelNoStr) == true) { - QJsonObject channelDataItem = channelDataJsonMap.value(channelNo); + QJsonObject channelDataItem = channelDataJsonMap.value(channelNoStr); // 通道Label的序号 int channelIdx = devIdx * 16 + channelDataItem.value("channelNo").toInt() - 1; @@ -483,19 +538,20 @@ double valueMinusDelay = channelDataItem.value("data").toObject().value("dataValue").toString().toDouble() - delay * 1E-9 + refDelay * 1E-9; // 设置通道名和测量值的QLabel - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); channelValueList.at(channelIdx)->setText(QString::number(valueMinusDelay, 'f', 12)); channelNameList.at(channelIdx)->setProperty("channelId", channel->getChannelId()); channelNameList.at(channelIdx)->setProperty("deviceId", deviceId); - channelNameList.at(channelIdx)->setProperty("channelNo", channelNo); + channelNameList.at(channelIdx)->setProperty("channelNo", channelNoStr); channelValueList.at(channelIdx)->setProperty("channelId", channel->getChannelId()); channelValueList.at(channelIdx)->setProperty("deviceId", deviceId); - channelValueList.at(channelIdx)->setProperty("channelNo", channelNo); + channelValueList.at(channelIdx)->setProperty("channelNo", channelNoStr); } else { - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg("-")); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg("-")); channelValueList.at(channelIdx)->setText(""); + computeValueList.at(channelIdx)->setText(""); } } else { // 计数器返回的无测量值的通道处理逻辑 @@ -503,6 +559,7 @@ // 没有测量值的通道清空 channelValueList.at(channelIdx)->setText(""); + computeValueList.at(channelIdx)->setText(""); // 当通道启用时显示通道离线 不再判断后台传回来的状态 // 当通道未启用时显示正常状态 @@ -510,12 +567,12 @@ channelNameList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value("channelOffline")); channelValueList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value("channelOffline")); - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); } else { channelNameList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value(channelNameList.at(channelIdx)->property("labType").toString())); channelValueList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value(channelValueList.at(channelIdx)->property("labType").toString())); - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg("-")); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg("-")); } } } @@ -523,7 +580,7 @@ void CounterWindowRT::updateDeviceAlarm(QJsonArray alarmList) { - qDebug() << alarmList; +// qDebug() << alarmList; for (int i = 0; i < alarmList.size(); i++) { QJsonObject alarmData = alarmList.at(i).toObject(); @@ -532,7 +589,7 @@ QString alarmCode = alarmData.value("alarmCode").toString(); QString status = alarmData.value("status").toString(); - qDebug() << alarmCode << deviceId << channelId; +// qDebug() << alarmCode << deviceId << channelId; // 如果报警状态不是正在报警 status==0 或者报警设备不是计数器 则不处理 if (status != "0" || ConstCache::getInstance().deviceMap.contains(deviceId) == false) @@ -560,6 +617,92 @@ } } +void CounterWindowRT::findRefAndMeasureChannel() +{ + // 查询主路的参考通道的钟编号 + QString masterKey = QString("%1-%2").arg(ConstCache::getInstance().deviceIdLoopA.at(0)).arg("01"); // 暂时固定为01通道 + CounterChannel * refChannelMaster = ConstCache::getInstance().channelMap.value(masterKey); // 主路参考的钟编号 + + // 查询主路参考通道在备路的测量通道 + for (QString channelKey : ConstCache::getInstance().channelMap.keys()) { + QString deviceId = channelKey.split("-")[0]; + if (ConstCache::getInstance().deviceIdLoopB.contains(deviceId)) { + CounterChannel * channel = ConstCache::getInstance().channelMap.value(channelKey); + if (channel->getChannelCode() == refChannelMaster->getChannelCode()) { + QStringList masterInfo; + masterInfo << refChannelMaster->getChannelCode() << deviceId << channel->getChannelId() << channel->getChannelNo(); + ConstCache::getInstance().loopInfos.append(masterInfo); + + break; + } + } + } + + // 查询备路的参考通道钟编号 + QString slaveKey = QString("%1-%2").arg(ConstCache::getInstance().deviceIdLoopB.at(0)).arg("01"); // 暂时固定为01通道 + CounterChannel * refChannelSlave = ConstCache::getInstance().channelMap.value(slaveKey); // 备路参考的钟编号 + + // 查询备路参考通道在主路的测量通道 + for (QString channelKey : ConstCache::getInstance().channelMap.keys()) { + QString deviceId = channelKey.split("-")[0]; + if (ConstCache::getInstance().deviceIdLoopA.contains(deviceId)) { + CounterChannel * channel = ConstCache::getInstance().channelMap.value(channelKey); + if (channel->getChannelCode() == refChannelSlave->getChannelCode()) { + QStringList slaveInfo; + slaveInfo << refChannelSlave->getChannelCode() << deviceId << channel->getChannelId() << channel->getChannelNo(); + ConstCache::getInstance().loopInfos.append(slaveInfo); + + break; + } + } + } + +// qDebug() << ConstCache::getInstance().loopInfos.at(0); +// qDebug() << ConstCache::getInstance().loopInfos.at(1); +// qDebug() << ConstCache::getInstance().channelMap; +} + +double CounterWindowRT::calculateAvgStandbyTimeDiff(QList thisChannel, + QList refChannel, + QList standbyChannel) +{ + double avgTimeDiff = 0.0; + + if (thisChannel.isEmpty() || refChannel.isEmpty() || standbyChannel.isEmpty()) { + return avgTimeDiff; + } + + double sumThis = 0.0; + double avgThis = 0.0; + int countThis = 0; + for (QStringList thisData : thisChannel) { + sumThis += thisData.at(1).toDouble(); + countThis++; + } + avgThis = sumThis / countThis * 1.0; + + double sumRef = 0.0; + double avgRef = 0.0; + int countRef = 0; + for (QStringList refData : refChannel) { + sumRef += refData.at(1).toDouble(); + countRef++; + } + avgRef = sumRef / countRef * 1.0; + + double sumStandby = 0.0; + double avgStandby = 0.0; + int countStandby = 0; + for (QStringList standbyData : standbyChannel) { + sumStandby += standbyData.at(1).toDouble(); + countStandby++; + } + avgStandby = sumStandby / countStandby * 1.0; + + avgTimeDiff = avgThis - avgRef - avgStandby; + return avgTimeDiff; +} + void CounterWindowRT::updateDateAndTime() { QString date = QDate::currentDate().toString("yyyy-MM-dd"); @@ -567,6 +710,171 @@ ui->labTime->setText(date + " " + time); } +void CounterWindowRT::watchStandbyConsistency() +{ + quint8 second = QTime::currentTime().second(); + if (second % SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND == 0) { + qDebug() << "watchStandbyConsistency: " << QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"); + // 1. 遍历所有的主路计数器 + for (QString devAId : ConstCache::getInstance().deviceIdLoopA) { + // 2. 遍历主路计数器的每一个通道(除参考通道外) + for (QString key : ConstCache::getInstance().channelMap.keys()) { + if (key.contains(devAId) == false) { + continue; + } else { + // A当前通道 + CounterChannel * channel = ConstCache::getInstance().channelMap.value(key); + QString channelCode = channel->getChannelCode(); // 钟编号 + QString channelNo = channel->getChannelNo(); // 通道号 + + if (channelNo == "00" || channelNo == "01" || channelCode.isEmpty()) { + continue; + } + + // B备路参考通道在主路的测量通道 + CounterChannel * standbyRefChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(ConstCache::getInstance().loopInfos.at(1).at(1)).arg(ConstCache::getInstance().loopInfos.at(1).at(3))); + + // 3. 获得通道的钟编号、通道号,找到对应钟编号、通道号在备路对应的通道 + // C对应的备路测量通道 + QString standbyKey = ""; + CounterChannel * standbyChannel = nullptr; + if (ConstCache::getInstance().standbyMap.contains(key) == false) { + // 在对路计数器中找 并存入standbyMap + for (QString standbyDevId : ConstCache::getInstance().deviceIdLoopB) { + // 通道号和钟编号都匹配 + standbyChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(standbyDevId).arg(channelNo)); + if (standbyChannel != nullptr && standbyChannel->getChannelCode() == channelCode) { + standbyKey = QString("%1-%2").arg(standbyDevId).arg(channelNo); + ConstCache::getInstance().standbyMap.insert(key, standbyKey); + } + } + } else { + standbyKey = ConstCache::getInstance().standbyMap.value(key); + standbyChannel = ConstCache::getInstance().channelMap.value(standbyKey); + } + + // 4. 取当前通道的最后10个历史数据 channel + QList thisChannelDataList; + if (channel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + thisChannelDataList = channel->getHisData().mid(channel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 5. 取备路参考通道最后10个历史数据 standbyRefChannel + QList standbyRefChannelDataList; + if (standbyRefChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyRefChannelDataList = standbyRefChannel->getHisData().mid(standbyRefChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 6. 取备路计数器对应通道的最后10个历史数据 standbyChannel + QList standbyChannelDataList; + if (standbyChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyChannelDataList = standbyChannel->getHisData().mid(standbyChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 7. 计算当前通道相对备路参考钟的时差 与备路对应通道的时差做差 + if (thisChannelDataList.isEmpty() || standbyChannelDataList.isEmpty()) { + continue; + } + double avgTimeDiff = calculateAvgStandbyTimeDiff(thisChannelDataList, standbyRefChannelDataList, standbyChannelDataList); + + // 8. 显示在界面上 + CounterDevice * devicePtr = ConstCache::getInstance().deviceMap.value(devAId); + if (devicePtr != nullptr && SettingConfig::getInstance().MASTER == devicePtr->getIsUse()) + { + int devIdx = devicePtr->getFormColIndex(); + + // 通道Label的序号 + int channelIdx = devIdx * 16 + channelNo.toInt() - 1; + computeValueList.at(channelIdx)->setText(QString::number(avgTimeDiff * 1E9, 'f', 3)); + } + } + } + } + + // 8. 遍历所有的备路计数器 + for (QString devBId : ConstCache::getInstance().deviceIdLoopB) { + // 2. 遍历主路计数器的每一个通道(除参考通道外) + for (QString key : ConstCache::getInstance().channelMap.keys()) { + if (key.contains(devBId) == false) { + continue; + } else { + // A当前通道 + CounterChannel * channel = ConstCache::getInstance().channelMap.value(key); + QString channelCode = channel->getChannelCode(); // 钟编号 + QString channelNo = channel->getChannelNo(); // 通道号 + + if (channelNo == "00" || channelNo == "01" || channelCode.isEmpty()) { + continue; + } + + // B主路参考通道在主路的测量通道 + CounterChannel * standbyRefChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(ConstCache::getInstance().loopInfos.at(0).at(1)).arg(ConstCache::getInstance().loopInfos.at(0).at(3))); + + // 3. 获得通道的钟编号、通道号,找到对应钟编号、通道号在备路对应的通道 + // C对应的主路测量通道 + QString standbyKey = ""; + CounterChannel * standbyChannel = nullptr; + if (ConstCache::getInstance().standbyMap.contains(key) == false) { + // 在对路计数器中找 并存入standbyMap + for (QString standbyDevId : ConstCache::getInstance().deviceIdLoopA) { + // 通道号和钟编号都匹配 + standbyChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(standbyDevId).arg(channelNo)); + if (standbyChannel != nullptr && standbyChannel->getChannelCode() == channelCode) { + standbyKey = QString("%1-%2").arg(standbyDevId).arg(channelNo); + ConstCache::getInstance().standbyMap.insert(key, standbyKey); + } + } + } else { + standbyKey = ConstCache::getInstance().standbyMap.value(key); + standbyChannel = ConstCache::getInstance().channelMap.value(standbyKey); + } + + // 4. 取当前通道的最后10个历史数据 channel + QList thisChannelDataList; + if (channel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + thisChannelDataList = channel->getHisData().mid(channel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 5. 取主路参考通道最后10个历史数据 standbyRefChannel + QList standbyRefChannelDataList; + if (standbyRefChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyRefChannelDataList = standbyRefChannel->getHisData().mid(standbyRefChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 6. 取主路计数器对应通道的最后10个历史数据 standbyChannel + QList standbyChannelDataList; + if (standbyChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyChannelDataList = standbyChannel->getHisData().mid(standbyChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 7. 计算当前通道相对主路参考钟的时差 与主路对应通道的时差做差 + if (thisChannelDataList.isEmpty() || standbyChannelDataList.isEmpty()) { + continue; + } + double avgTimeDiff = calculateAvgStandbyTimeDiff(thisChannelDataList, standbyRefChannelDataList, standbyChannelDataList); + + // 8. 显示在界面上 + CounterDevice * devicePtr = ConstCache::getInstance().deviceMap.value(devBId); + if (devicePtr != nullptr && SettingConfig::getInstance().MASTER == devicePtr->getIsUse()) + { + int devIdx = devicePtr->getFormColIndex(); + + // 通道Label的序号 + int channelIdx = devIdx * 16 + channelNo.toInt() - 1; + computeValueList.at(channelIdx)->setText(QString::number(avgTimeDiff * 1E9, 'f', 3)); + } + } + } + } + } +} + void CounterWindowRT::on_btnMenuSetting_clicked() { settingForm->setWindowModality(Qt::ApplicationModal); @@ -600,8 +908,10 @@ // 将lab列表的数量置0 devTitleList.resize(0); devRefList.resize(0); + devCompRefList.resize(0); channelNameList.resize(0); channelValueList.resize(0); + computeValueList.resize(0); initDevAndChannelForm(SettingConfig::getInstance().DISPLAY_COUNT); } @@ -620,14 +930,20 @@ devTitleList.at(i)->setText(dev->getDeviceName()); // 设备名称 dev->setFormColIndex(i); } + for (int j = 1; j < 16; j++) + { + computeValueList.at(i * 16 + j)->setText("-"); + } } else { devTitleList.at(i)->setText(""); devRefList.at(i)->setText(""); + devCompRefList.at(i)->setText(""); for (int j = 0; j < 16; j++) { channelNameList.at(i * 16 + j)->setText(""); channelValueList.at(i * 16 + j)->setText(""); + computeValueList.at(i * 16 + j)->setText(""); } } } @@ -685,7 +1001,7 @@ // 参考通道 int refChNo = messageArray.at(0).toObject().value("data").toObject().value("channelRefNo").toInt(); - CounterChannel * refChann = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo)); + CounterChannel * refChann = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo, 2, 10, QLatin1Char('0'))); if (refChann != nullptr) { if (devIdx < devRefList.size()) { @@ -704,7 +1020,7 @@ void CounterWindowRT::onKafkaMessageReceived(QJsonObject message) { qDebug() << message; - std::cout << QString(QJsonDocument(message).toJson(QJsonDocument::Compact)).toStdString() << std::endl; + std::cout << "kafka message received: " << std::endl << QString(QJsonDocument(message).toJson(QJsonDocument::Compact)).toStdString() << std::endl; // 找不到deviceId deviceType operation三个必填项 直接返回 if (message.contains("deviceId") == false || message.contains("operation") == false || message.contains("deviceType") == false) { @@ -732,7 +1048,7 @@ void CounterWindowRT::onAlarmMessageReceived(QJsonObject alarmMsg) { qDebug() << alarmMsg; - std::cout << QString(QJsonDocument(alarmMsg).toJson(QJsonDocument::Compact)).toStdString() << std::endl; + std::cout << "alarm message received: " << std::endl << QString(QJsonDocument(alarmMsg).toJson(QJsonDocument::Compact)).toStdString() << std::endl; QString deviceId = alarmMsg.value("deviceId").toString(); QString channelId = alarmMsg.value("channelId").toString(); diff --git a/CounterRealTime/CounterWindowRT.h b/CounterRealTime/CounterWindowRT.h index b672cfc..b4eea96 100644 --- a/CounterRealTime/CounterWindowRT.h +++ b/CounterRealTime/CounterWindowRT.h @@ -17,10 +17,13 @@ #include "CounterSettingForm.h" #include "common/utils/SettingConfig.h" #include "common/utils/TimerCounterUtil.h" -#include "common/utils/QKafkaConsumer.h" #include "common/HttpRequestController.h" #include "common/HttpServer.h" +#ifdef unix +#include "common/utils/QKafkaConsumer.h" +#endif + QT_BEGIN_NAMESPACE namespace Ui { class CounterWindowRT; } QT_END_NAMESPACE @@ -47,12 +50,17 @@ QVector devTitleList; // 计数器设备标题的QLabel集合 QVector devRefList; // Ref通道 + QVector devCompRefList; // 归算Ref通道 QVector channelNameList; // 通道名的QLabel集合 QVector channelValueList; // 通道测量值的QLabel集合 + QVector computeValueList; // 通道归算值的QLabel集合 HttpRequestController * httpReq; + +#ifdef unix QKafkaConsumer * kafkaConsumer; QKafkaConsumer * alarmMsgConsumer; +#endif QVector alarmDev; QVector offlineDev; @@ -67,9 +75,13 @@ void initDevAndChannelForm(int count); void updateChannelDataForm(QJsonArray messageArray); void updateDeviceAlarm(QJsonArray alarmList); + void findRefAndMeasureChannel(); // 查找主备路的测量参考通道以及各自的测量通道 + double calculateAvgStandbyTimeDiff(QList thisChannel, QList refChannel, QList standbyChannel); + private slots: void updateDateAndTime(); + void watchStandbyConsistency(); int initHttpToken(); diff --git a/CounterRealTime/common/ConstCache.h b/CounterRealTime/common/ConstCache.h index 25a97d4..c5af508 100644 --- a/CounterRealTime/common/ConstCache.h +++ b/CounterRealTime/common/ConstCache.h @@ -31,6 +31,9 @@ QList deviceIdLoopB; // B路计数器对象集合 key=deviceId QMap channelMap; // 通道对象集合 key=deviceId-channelNo + QList loopInfos; // 存储主备路关键信息 参考钟编号;在对路的测量计数器ID;在对路的测量计数器所在通道ID;对路计数器所在的通道号 + QMap standbyMap; // 主路/备路通道的备路/主路对应通道key key=deviceId-channelNo value=deviceId-channelNo + QMap alarmDeviceMap; // 报警设备 QMap alarmChannelMap; // 报警通道 diff --git a/CounterRealTime/CounterDevice.cpp b/CounterRealTime/CounterDevice.cpp index 4ff6565..f656746 100644 --- a/CounterRealTime/CounterDevice.cpp +++ b/CounterRealTime/CounterDevice.cpp @@ -9,11 +9,13 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &CounterDevice::dataReceivedHandler); +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); kafkaUtil.createProducer(); } +#endif } CounterDevice::~CounterDevice() @@ -78,6 +80,15 @@ this->refChannelCode = refChannelCode; } +int CounterDevice::getRefChannelNo() +{ + return this->refChannelNo; +} +void CounterDevice::setRefChannelNo(int refChannelNo) +{ + this->refChannelNo = refChannelNo; +} + bool CounterDevice::isSerialOpen() { return this->serialUtil.isOpen(); @@ -156,7 +167,7 @@ msgLogFilename = msgLogFilename.arg((hour / 6) * 6, 2, 10, QLatin1Char('0')); msgLogFilename = msgLogFilename.arg((hour / 6) * 6 + 5, 2, 10, QLatin1Char('0')); - CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(counterData->channelRefId)); + CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(counterData->channelRefId, 2, 10, QLatin1Char('0'))); this->refChannelNo = counterData->channelRefId; double refDelay = 0.0; if (refChanPtr != nullptr && refChanPtr->getDelays().isEmpty() == false) { @@ -186,7 +197,7 @@ } // 加到hisDataList中 用于绘制图表 - CounterChannel * channelPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i)); + CounterChannel * channelPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i, 2, 10, QLatin1Char('0'))); if (channelPtr != nullptr && channelPtr->isActive() == true) { // 通道时延值 并计算 减去时延值的测量值 @@ -210,6 +221,7 @@ statusObj.insert("master", SettingConfig::getInstance().MASTER); statusObj.insert("deviceId", deviceId); +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { if (SettingConfig::getInstance().MASTER == 0) @@ -227,6 +239,7 @@ kafkaUtil.produceMessage(SettingConfig::getInstance().KAFKA_STATUS_TOPIC, QString(QJsonDocument(statusObj).toJson(QJsonDocument::Compact))); } } +#endif QLogUtil::writeMessageLogByDate(date, msgLogFilename, QString(QJsonDocument(messageArray).toJson(QJsonDocument::Compact))); diff --git a/CounterRealTime/CounterDevice.h b/CounterRealTime/CounterDevice.h index c4d003d..68390c8 100644 --- a/CounterRealTime/CounterDevice.h +++ b/CounterRealTime/CounterDevice.h @@ -6,7 +6,6 @@ #include "CounterChannel.h" #include "common/utils/QSerialPortUtil.h" -#include "common/utils/QKafkaUtil.h" #include "common/utils/QByteUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" @@ -14,6 +13,10 @@ #include "common/LinearRegression.h" #include "protocol/CounterProtocolXH.h" +#ifdef unix +#include "common/utils/QKafkaUtil.h" +#endif + class CounterDevice : public QObject { Q_OBJECT @@ -37,6 +40,9 @@ int getIsUse(); void setIsUse(int isUse); + int getRefChannelNo(); + void setRefChannelNo(int refChannelNo); + QString getRefChannelCode(); void setRefChannelCode(QString refChannelCode); @@ -56,9 +62,12 @@ int formColIndex; QSerialPortUtil serialUtil; - QKafkaUtil kafkaUtil; QByteArray dataBuff; +#ifdef unix + QKafkaUtil kafkaUtil; +#endif + void afterFramePhase(CounterDataDto * counterData); void calcResidualClockData(qlonglong tm); diff --git a/CounterRealTime/CounterRealTime.pro b/CounterRealTime/CounterRealTime.pro index c323f04..f990ff3 100644 --- a/CounterRealTime/CounterRealTime.pro +++ b/CounterRealTime/CounterRealTime.pro @@ -49,7 +49,8 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka++ -lrdkafka +win32: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka++ -lrdkafka INCLUDEPATH += $$PWD/include/librdkafka DEPENDPATH += $$PWD/include/librdkafka diff --git a/CounterRealTime/CounterSettingForm.cpp b/CounterRealTime/CounterSettingForm.cpp index c1945d1..bc43ac7 100644 --- a/CounterRealTime/CounterSettingForm.cpp +++ b/CounterRealTime/CounterSettingForm.cpp @@ -335,7 +335,7 @@ active = activeListRight.at(i - 8)->isChecked(); } - CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1)); + CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1, 2, 10, QLatin1Char('0'))); if (channelPrt != nullptr) { bool isUpdated = isChannelSettingUpdated(i, channelPrt); @@ -362,7 +362,7 @@ newChannel->setChannelCode(channelCode); newChannel->setDelays(QString::number(delay)); - ConstCache::getInstance().channelMap.insert(QString("%1-%2").arg(deviceId).arg(i+1), newChannel); + ConstCache::getInstance().channelMap.insert(QString("%1-%2").arg(deviceId).arg(i+1, 2, 10, QLatin1Char('0')), newChannel); QJsonObject channelObj; channelObj.insert("id", ""); @@ -412,7 +412,7 @@ activeListLeft.at(i)->setCheckable(true); activeListRight.at(i)->setCheckable(true); - CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1)); + CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1, 2, 10, QLatin1Char('0'))); if (channelPrt != nullptr) { QString channelCode = channelPrt->getChannelCode(); // 通道钟号 @@ -429,7 +429,7 @@ } } - CounterChannel * channelRightPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1+8)); + CounterChannel * channelRightPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1+8, 2, 10, QLatin1Char('0'))); if (channelRightPrt != nullptr) { QString channelCode = channelRightPrt->getChannelCode(); // 通道钟号 diff --git a/CounterRealTime/CounterWindowRT.cpp b/CounterRealTime/CounterWindowRT.cpp index 30adf9b..78815d7 100644 --- a/CounterRealTime/CounterWindowRT.cpp +++ b/CounterRealTime/CounterWindowRT.cpp @@ -76,6 +76,7 @@ file.close(); } +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { // kafka consumer kafkaConsumer = new QKafkaConsumer(this); @@ -93,6 +94,7 @@ alarmMsgConsumer->start(); connect(alarmMsgConsumer, &QKafkaConsumer::messageRecieved, this, &CounterWindowRT::onAlarmMessageReceived); } +#endif // 绘制界面上的表格 initChannelForm(); @@ -100,6 +102,10 @@ // 显示时钟 每秒更新 connect(TimerCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &CounterWindowRT::updateDateAndTime); TimerCounterUtil::getInstance().clockCounter->start(1000); + QTimer::singleShot(30000, [=](){ + // 定时执行主备一致性监测 + connect(TimerCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &CounterWindowRT::watchStandbyConsistency); + }); // 重新选择显示多少个计数器 connect(settingForm, &CounterSettingForm::swiftDisplayLoop, this, &CounterWindowRT::updateDeviceWidget); @@ -182,7 +188,7 @@ } for (int i = 0; i < devSet.size(); i++) { - getChannelList(devSet.toList().at(i)); + getChannelList(devSet.values().at(i)); } } } @@ -233,6 +239,13 @@ } updateDeviceWidget(); + +// qDebug() << "loop A: " << ConstCache::getInstance().deviceIdLoopA; +// qDebug() << "loop B: " << ConstCache::getInstance().deviceIdLoopB; + + // 查找主路参考钟在备路计数器的测量通道 + // 查找备路参考钟在主路计数器的测量通道 + findRefAndMeasureChannel(); } } QList CounterWindowRT::getClockNumList() @@ -262,7 +275,8 @@ { // for (int i = 0; i <= 16; i++) { - ConstCache::getInstance().channelMap.remove(QString("%1-%2").arg(deviceId).arg(i)); + QString channelKey = QString("%1-%2").arg(deviceId).arg(i); + ConstCache::getInstance().channelMap.remove(channelKey); } // 将通道绘制在界面上 @@ -273,7 +287,7 @@ QJsonObject channelItem = channelArray.at(i).toObject(); QString channelId = channelItem.value("id").toString(); // 通道ID QString channelCode = channelItem.value("channelCode").toString(); // 通道钟号 - QString channelNo = QString::number(channelItem.value("channelNo").toInt()); // 通道序号 + QString channelNo = QString("%1").arg(channelItem.value("channelNo").toInt(), 2, 10, QLatin1Char('0')); // 通道序号 QString delays = channelItem.value("delays").toString(); // 通道时延值 QString isUse = channelItem.value("isUse").toString(); QString name = channelItem.value("name").toString(); @@ -292,6 +306,14 @@ // 添加到通道的集合中 key=deviceId-channelNo ConstCache::getInstance().channelMap.insert(deviceId + "-" + channelNo, channel); + + if (channelCode.isEmpty() == false && active == true) { + CounterDevice * counterDev = ConstCache::getInstance().deviceMap.value(deviceId); + if (counterDev != nullptr) { + QStringList channelBase; + channelBase << QString::number(counterDev->getIsUse()) << channelCode; + } + } } } } @@ -314,10 +336,12 @@ layoutChannelPage->setMargin(3); // 留出边框的位置 // 左右布局中是垂直布局,用于显示通道 - QVBoxLayout * layoutChannelLeft = new QVBoxLayout(); - QVBoxLayout * layoutChannelRight = new QVBoxLayout(); + QVBoxLayout * layoutChannelLeft = new QVBoxLayout(); // 最左侧显示设备简称 + QVBoxLayout * layoutChannelMain = new QVBoxLayout(); // 中间显示参考通道 + QVBoxLayout * layoutChannelRight = new QVBoxLayout(); // 最右侧显示归算参考通道 字号小一号 layoutChannelLeft->setSpacing(0); + layoutChannelMain->setSpacing(0); layoutChannelRight->setSpacing(0); // 设备标题的Label @@ -330,55 +354,76 @@ // 设备参考通道的Label QLabel * labDevRef = new QLabel(widgetDev); labDevRef->setProperty("labType", QString("devRef%1").arg(count)); // 样式表属性 - labDevRef->setText(QString("REF: %1").arg("1000")); + labDevRef->setText(QString("REF: %1").arg("10000")); labDevRef->setAlignment(Qt::AlignCenter); // 文字居中显示 devRefList.append(labDevRef); + // 设置归算使用的参考通道Label + QLabel * labCompDevRef = new QLabel(widgetDev); + labCompDevRef->setProperty("labType", QString("devCompRef%1").arg(count)); // 样式表属性 + labCompDevRef->setText(QString("%1").arg("主备时差")); + labCompDevRef->setAlignment(Qt::AlignCenter); // 文字居中显示 + devCompRefList.append(labCompDevRef); + if (count == 4) { labDevTitle->setMaximumHeight(80); // 设置固定高度 labDevTitle->setMinimumHeight(80); labDevRef->setMaximumHeight(80); // 设置固定高度 labDevRef->setMinimumHeight(80); + + labCompDevRef->setMaximumHeight(80); // 设置固定高度 + labCompDevRef->setMinimumHeight(80); } else { labDevTitle->setMaximumHeight(60); // 设置固定高度 labDevTitle->setMinimumHeight(60); labDevRef->setMaximumHeight(60); // 设置固定高度 labDevRef->setMinimumHeight(60); + + labCompDevRef->setMaximumHeight(60); // 设置固定高度 + labCompDevRef->setMinimumHeight(60); } // 左侧显示设备简称,右侧显示参考通道名 layoutChannelLeft->addWidget(labDevTitle); - layoutChannelRight->addWidget(labDevRef); + layoutChannelMain->addWidget(labDevRef); + layoutChannelRight->addWidget(labCompDevRef); // 每个计数器显示16个通道 for ( int i = 0; i < 16; i++ ) { QLabelDblClick * labChannelName = new QLabelDblClick(widgetDev); // 通道名 QLabelDblClick * labChannelValue = new QLabelDblClick(widgetDev); // 通道测量值 + QLabelDblClick * labComputeValue = new QLabelDblClick(widgetDev); // 通道归算值 // 默认显示内容 - labChannelName->setText(QString("CH%1").arg(i+1, 2, 10, QLatin1Char('0'))); + labChannelName->setText(QString("%1: 10000").arg(i+1, 2, 10, QLatin1Char('0'))); labChannelValue->setText("0.000000000000"); + labComputeValue->setText(""); // css不支持的样式用代码实现 - labChannelName->setMargin(10); - labChannelValue->setMargin(10); + labChannelName->setMargin(5); + labChannelValue->setMargin(5); labChannelValue->setAlignment(Qt::AlignRight | Qt::AlignVCenter); + labComputeValue->setMargin(5); + labComputeValue->setAlignment(Qt::AlignRight | Qt::AlignVCenter); // 奇偶显示不同的背景色 if (i % 2 == 0) { labChannelName->setProperty("labType", QString("channelNameEven%1").arg(count)); labChannelValue->setProperty("labType", QString("channelValueEven%1").arg(count)); + labComputeValue->setProperty("labType", QString("computeValueEven%1").arg(count)); } else { labChannelName->setProperty("labType", QString("channelNameOdd%1").arg(count)); labChannelValue->setProperty("labType", QString("channelValueOdd%1").arg(count)); + labComputeValue->setProperty("labType", QString("computeValueOdd%1").arg(count)); } layoutChannelLeft->addWidget(labChannelName); - layoutChannelRight->addWidget(labChannelValue); + layoutChannelMain->addWidget(labChannelValue); + layoutChannelRight->addWidget(labComputeValue); // 添加通道名称的双击事件,显示数据和残差图表 connect(labChannelName, &QLabelDblClick::doubleClicked, this, &CounterWindowRT::onChannelNameLabelDblClicked); @@ -386,16 +431,21 @@ channelNameList.append(labChannelName); channelValueList.append(labChannelValue); + computeValueList.append(labComputeValue); // 左下角和右下角的圆角处理 if (i == 15) { labChannelName->setStyleSheet("border-bottom-left-radius: 10px;"); - labChannelValue->setStyleSheet("border-bottom-right-radius: 10px;"); + labComputeValue->setStyleSheet("border-bottom-right-radius: 10px;"); } } layoutChannelPage->addLayout(layoutChannelLeft); + layoutChannelPage->addLayout(layoutChannelMain); layoutChannelPage->addLayout(layoutChannelRight); + layoutChannelPage->setStretch(0, 35); + layoutChannelPage->setStretch(1, 50); + layoutChannelPage->setStretch(2, 15); widgetDev->setLayout(layoutChannelPage); } } @@ -407,13 +457,19 @@ // 参考通道号 int refChNo = messageArray.at(0).toObject().value("data").toObject().value("channelRefNo").toInt(); + CounterDevice * counter = ConstCache::getInstance().deviceMap.value(deviceId); + if (counter == nullptr) { + return; + } + counter->setRefChannelNo(refChNo); + // 根据设备id 从map中取出列索引的值 - int devIdx = ConstCache::getInstance().deviceMap.value(deviceId)->getFormColIndex(); + int devIdx = counter->getFormColIndex(); if (devIdx < devRefList.size()) { // 参考通道的显示 QString refText = devRefList.at(devIdx)->text(); - channelNameList.at(devIdx * 16 + refChNo - 1)->setText(QString("CH%1:%2").arg(refChNo, 2, 10, QLatin1Char('0')).arg(refText.right(refText.length() - 4))); + channelNameList.at(devIdx * 16 + refChNo - 1)->setText(QString("%1:%2").arg(refChNo, 2, 10, QLatin1Char('0')).arg(refText.right(refText.length() - 4))); if (alarmDev.contains(deviceId) == true) { @@ -433,11 +489,11 @@ for (int i = 0; i < messageArray.size(); i++) { QJsonObject channelDataItem = messageArray.at(i).toObject(); - QString channelNo = QString::number(channelDataItem.value("channelNo").toInt()); // 通道序号 + QString channelNo = QString("%1").arg(channelDataItem.value("channelNo").toInt(), 2, 10, QLatin1Char('0')); // 通道序号 channelDataJsonMap.insert(channelNo, channelDataItem); } - CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo)); + CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo, 2, 10, QLatin1Char('0'))); double refDelay = 0.0; if (refChanPtr != nullptr && refChanPtr->getDelays().isEmpty() == false) { refDelay = refChanPtr->getDelays().toDouble(); @@ -454,11 +510,10 @@ continue; } - CounterChannel * channel = ConstCache::getInstance().channelMap.value(deviceId + "-" + channelNo); // 从map中找到对应的通道 - - if (channelDataJsonMap.contains(channelNo) == true) + CounterChannel * channel = ConstCache::getInstance().channelMap.value(deviceId + "-" + channelNoStr); // 从map中找到对应的通道 + if (channelDataJsonMap.contains(channelNoStr) == true) { - QJsonObject channelDataItem = channelDataJsonMap.value(channelNo); + QJsonObject channelDataItem = channelDataJsonMap.value(channelNoStr); // 通道Label的序号 int channelIdx = devIdx * 16 + channelDataItem.value("channelNo").toInt() - 1; @@ -483,19 +538,20 @@ double valueMinusDelay = channelDataItem.value("data").toObject().value("dataValue").toString().toDouble() - delay * 1E-9 + refDelay * 1E-9; // 设置通道名和测量值的QLabel - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); channelValueList.at(channelIdx)->setText(QString::number(valueMinusDelay, 'f', 12)); channelNameList.at(channelIdx)->setProperty("channelId", channel->getChannelId()); channelNameList.at(channelIdx)->setProperty("deviceId", deviceId); - channelNameList.at(channelIdx)->setProperty("channelNo", channelNo); + channelNameList.at(channelIdx)->setProperty("channelNo", channelNoStr); channelValueList.at(channelIdx)->setProperty("channelId", channel->getChannelId()); channelValueList.at(channelIdx)->setProperty("deviceId", deviceId); - channelValueList.at(channelIdx)->setProperty("channelNo", channelNo); + channelValueList.at(channelIdx)->setProperty("channelNo", channelNoStr); } else { - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg("-")); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg("-")); channelValueList.at(channelIdx)->setText(""); + computeValueList.at(channelIdx)->setText(""); } } else { // 计数器返回的无测量值的通道处理逻辑 @@ -503,6 +559,7 @@ // 没有测量值的通道清空 channelValueList.at(channelIdx)->setText(""); + computeValueList.at(channelIdx)->setText(""); // 当通道启用时显示通道离线 不再判断后台传回来的状态 // 当通道未启用时显示正常状态 @@ -510,12 +567,12 @@ channelNameList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value("channelOffline")); channelValueList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value("channelOffline")); - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); } else { channelNameList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value(channelNameList.at(channelIdx)->property("labType").toString())); channelValueList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value(channelValueList.at(channelIdx)->property("labType").toString())); - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg("-")); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg("-")); } } } @@ -523,7 +580,7 @@ void CounterWindowRT::updateDeviceAlarm(QJsonArray alarmList) { - qDebug() << alarmList; +// qDebug() << alarmList; for (int i = 0; i < alarmList.size(); i++) { QJsonObject alarmData = alarmList.at(i).toObject(); @@ -532,7 +589,7 @@ QString alarmCode = alarmData.value("alarmCode").toString(); QString status = alarmData.value("status").toString(); - qDebug() << alarmCode << deviceId << channelId; +// qDebug() << alarmCode << deviceId << channelId; // 如果报警状态不是正在报警 status==0 或者报警设备不是计数器 则不处理 if (status != "0" || ConstCache::getInstance().deviceMap.contains(deviceId) == false) @@ -560,6 +617,92 @@ } } +void CounterWindowRT::findRefAndMeasureChannel() +{ + // 查询主路的参考通道的钟编号 + QString masterKey = QString("%1-%2").arg(ConstCache::getInstance().deviceIdLoopA.at(0)).arg("01"); // 暂时固定为01通道 + CounterChannel * refChannelMaster = ConstCache::getInstance().channelMap.value(masterKey); // 主路参考的钟编号 + + // 查询主路参考通道在备路的测量通道 + for (QString channelKey : ConstCache::getInstance().channelMap.keys()) { + QString deviceId = channelKey.split("-")[0]; + if (ConstCache::getInstance().deviceIdLoopB.contains(deviceId)) { + CounterChannel * channel = ConstCache::getInstance().channelMap.value(channelKey); + if (channel->getChannelCode() == refChannelMaster->getChannelCode()) { + QStringList masterInfo; + masterInfo << refChannelMaster->getChannelCode() << deviceId << channel->getChannelId() << channel->getChannelNo(); + ConstCache::getInstance().loopInfos.append(masterInfo); + + break; + } + } + } + + // 查询备路的参考通道钟编号 + QString slaveKey = QString("%1-%2").arg(ConstCache::getInstance().deviceIdLoopB.at(0)).arg("01"); // 暂时固定为01通道 + CounterChannel * refChannelSlave = ConstCache::getInstance().channelMap.value(slaveKey); // 备路参考的钟编号 + + // 查询备路参考通道在主路的测量通道 + for (QString channelKey : ConstCache::getInstance().channelMap.keys()) { + QString deviceId = channelKey.split("-")[0]; + if (ConstCache::getInstance().deviceIdLoopA.contains(deviceId)) { + CounterChannel * channel = ConstCache::getInstance().channelMap.value(channelKey); + if (channel->getChannelCode() == refChannelSlave->getChannelCode()) { + QStringList slaveInfo; + slaveInfo << refChannelSlave->getChannelCode() << deviceId << channel->getChannelId() << channel->getChannelNo(); + ConstCache::getInstance().loopInfos.append(slaveInfo); + + break; + } + } + } + +// qDebug() << ConstCache::getInstance().loopInfos.at(0); +// qDebug() << ConstCache::getInstance().loopInfos.at(1); +// qDebug() << ConstCache::getInstance().channelMap; +} + +double CounterWindowRT::calculateAvgStandbyTimeDiff(QList thisChannel, + QList refChannel, + QList standbyChannel) +{ + double avgTimeDiff = 0.0; + + if (thisChannel.isEmpty() || refChannel.isEmpty() || standbyChannel.isEmpty()) { + return avgTimeDiff; + } + + double sumThis = 0.0; + double avgThis = 0.0; + int countThis = 0; + for (QStringList thisData : thisChannel) { + sumThis += thisData.at(1).toDouble(); + countThis++; + } + avgThis = sumThis / countThis * 1.0; + + double sumRef = 0.0; + double avgRef = 0.0; + int countRef = 0; + for (QStringList refData : refChannel) { + sumRef += refData.at(1).toDouble(); + countRef++; + } + avgRef = sumRef / countRef * 1.0; + + double sumStandby = 0.0; + double avgStandby = 0.0; + int countStandby = 0; + for (QStringList standbyData : standbyChannel) { + sumStandby += standbyData.at(1).toDouble(); + countStandby++; + } + avgStandby = sumStandby / countStandby * 1.0; + + avgTimeDiff = avgThis - avgRef - avgStandby; + return avgTimeDiff; +} + void CounterWindowRT::updateDateAndTime() { QString date = QDate::currentDate().toString("yyyy-MM-dd"); @@ -567,6 +710,171 @@ ui->labTime->setText(date + " " + time); } +void CounterWindowRT::watchStandbyConsistency() +{ + quint8 second = QTime::currentTime().second(); + if (second % SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND == 0) { + qDebug() << "watchStandbyConsistency: " << QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"); + // 1. 遍历所有的主路计数器 + for (QString devAId : ConstCache::getInstance().deviceIdLoopA) { + // 2. 遍历主路计数器的每一个通道(除参考通道外) + for (QString key : ConstCache::getInstance().channelMap.keys()) { + if (key.contains(devAId) == false) { + continue; + } else { + // A当前通道 + CounterChannel * channel = ConstCache::getInstance().channelMap.value(key); + QString channelCode = channel->getChannelCode(); // 钟编号 + QString channelNo = channel->getChannelNo(); // 通道号 + + if (channelNo == "00" || channelNo == "01" || channelCode.isEmpty()) { + continue; + } + + // B备路参考通道在主路的测量通道 + CounterChannel * standbyRefChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(ConstCache::getInstance().loopInfos.at(1).at(1)).arg(ConstCache::getInstance().loopInfos.at(1).at(3))); + + // 3. 获得通道的钟编号、通道号,找到对应钟编号、通道号在备路对应的通道 + // C对应的备路测量通道 + QString standbyKey = ""; + CounterChannel * standbyChannel = nullptr; + if (ConstCache::getInstance().standbyMap.contains(key) == false) { + // 在对路计数器中找 并存入standbyMap + for (QString standbyDevId : ConstCache::getInstance().deviceIdLoopB) { + // 通道号和钟编号都匹配 + standbyChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(standbyDevId).arg(channelNo)); + if (standbyChannel != nullptr && standbyChannel->getChannelCode() == channelCode) { + standbyKey = QString("%1-%2").arg(standbyDevId).arg(channelNo); + ConstCache::getInstance().standbyMap.insert(key, standbyKey); + } + } + } else { + standbyKey = ConstCache::getInstance().standbyMap.value(key); + standbyChannel = ConstCache::getInstance().channelMap.value(standbyKey); + } + + // 4. 取当前通道的最后10个历史数据 channel + QList thisChannelDataList; + if (channel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + thisChannelDataList = channel->getHisData().mid(channel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 5. 取备路参考通道最后10个历史数据 standbyRefChannel + QList standbyRefChannelDataList; + if (standbyRefChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyRefChannelDataList = standbyRefChannel->getHisData().mid(standbyRefChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 6. 取备路计数器对应通道的最后10个历史数据 standbyChannel + QList standbyChannelDataList; + if (standbyChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyChannelDataList = standbyChannel->getHisData().mid(standbyChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 7. 计算当前通道相对备路参考钟的时差 与备路对应通道的时差做差 + if (thisChannelDataList.isEmpty() || standbyChannelDataList.isEmpty()) { + continue; + } + double avgTimeDiff = calculateAvgStandbyTimeDiff(thisChannelDataList, standbyRefChannelDataList, standbyChannelDataList); + + // 8. 显示在界面上 + CounterDevice * devicePtr = ConstCache::getInstance().deviceMap.value(devAId); + if (devicePtr != nullptr && SettingConfig::getInstance().MASTER == devicePtr->getIsUse()) + { + int devIdx = devicePtr->getFormColIndex(); + + // 通道Label的序号 + int channelIdx = devIdx * 16 + channelNo.toInt() - 1; + computeValueList.at(channelIdx)->setText(QString::number(avgTimeDiff * 1E9, 'f', 3)); + } + } + } + } + + // 8. 遍历所有的备路计数器 + for (QString devBId : ConstCache::getInstance().deviceIdLoopB) { + // 2. 遍历主路计数器的每一个通道(除参考通道外) + for (QString key : ConstCache::getInstance().channelMap.keys()) { + if (key.contains(devBId) == false) { + continue; + } else { + // A当前通道 + CounterChannel * channel = ConstCache::getInstance().channelMap.value(key); + QString channelCode = channel->getChannelCode(); // 钟编号 + QString channelNo = channel->getChannelNo(); // 通道号 + + if (channelNo == "00" || channelNo == "01" || channelCode.isEmpty()) { + continue; + } + + // B主路参考通道在主路的测量通道 + CounterChannel * standbyRefChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(ConstCache::getInstance().loopInfos.at(0).at(1)).arg(ConstCache::getInstance().loopInfos.at(0).at(3))); + + // 3. 获得通道的钟编号、通道号,找到对应钟编号、通道号在备路对应的通道 + // C对应的主路测量通道 + QString standbyKey = ""; + CounterChannel * standbyChannel = nullptr; + if (ConstCache::getInstance().standbyMap.contains(key) == false) { + // 在对路计数器中找 并存入standbyMap + for (QString standbyDevId : ConstCache::getInstance().deviceIdLoopA) { + // 通道号和钟编号都匹配 + standbyChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(standbyDevId).arg(channelNo)); + if (standbyChannel != nullptr && standbyChannel->getChannelCode() == channelCode) { + standbyKey = QString("%1-%2").arg(standbyDevId).arg(channelNo); + ConstCache::getInstance().standbyMap.insert(key, standbyKey); + } + } + } else { + standbyKey = ConstCache::getInstance().standbyMap.value(key); + standbyChannel = ConstCache::getInstance().channelMap.value(standbyKey); + } + + // 4. 取当前通道的最后10个历史数据 channel + QList thisChannelDataList; + if (channel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + thisChannelDataList = channel->getHisData().mid(channel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 5. 取主路参考通道最后10个历史数据 standbyRefChannel + QList standbyRefChannelDataList; + if (standbyRefChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyRefChannelDataList = standbyRefChannel->getHisData().mid(standbyRefChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 6. 取主路计数器对应通道的最后10个历史数据 standbyChannel + QList standbyChannelDataList; + if (standbyChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyChannelDataList = standbyChannel->getHisData().mid(standbyChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 7. 计算当前通道相对主路参考钟的时差 与主路对应通道的时差做差 + if (thisChannelDataList.isEmpty() || standbyChannelDataList.isEmpty()) { + continue; + } + double avgTimeDiff = calculateAvgStandbyTimeDiff(thisChannelDataList, standbyRefChannelDataList, standbyChannelDataList); + + // 8. 显示在界面上 + CounterDevice * devicePtr = ConstCache::getInstance().deviceMap.value(devBId); + if (devicePtr != nullptr && SettingConfig::getInstance().MASTER == devicePtr->getIsUse()) + { + int devIdx = devicePtr->getFormColIndex(); + + // 通道Label的序号 + int channelIdx = devIdx * 16 + channelNo.toInt() - 1; + computeValueList.at(channelIdx)->setText(QString::number(avgTimeDiff * 1E9, 'f', 3)); + } + } + } + } + } +} + void CounterWindowRT::on_btnMenuSetting_clicked() { settingForm->setWindowModality(Qt::ApplicationModal); @@ -600,8 +908,10 @@ // 将lab列表的数量置0 devTitleList.resize(0); devRefList.resize(0); + devCompRefList.resize(0); channelNameList.resize(0); channelValueList.resize(0); + computeValueList.resize(0); initDevAndChannelForm(SettingConfig::getInstance().DISPLAY_COUNT); } @@ -620,14 +930,20 @@ devTitleList.at(i)->setText(dev->getDeviceName()); // 设备名称 dev->setFormColIndex(i); } + for (int j = 1; j < 16; j++) + { + computeValueList.at(i * 16 + j)->setText("-"); + } } else { devTitleList.at(i)->setText(""); devRefList.at(i)->setText(""); + devCompRefList.at(i)->setText(""); for (int j = 0; j < 16; j++) { channelNameList.at(i * 16 + j)->setText(""); channelValueList.at(i * 16 + j)->setText(""); + computeValueList.at(i * 16 + j)->setText(""); } } } @@ -685,7 +1001,7 @@ // 参考通道 int refChNo = messageArray.at(0).toObject().value("data").toObject().value("channelRefNo").toInt(); - CounterChannel * refChann = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo)); + CounterChannel * refChann = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo, 2, 10, QLatin1Char('0'))); if (refChann != nullptr) { if (devIdx < devRefList.size()) { @@ -704,7 +1020,7 @@ void CounterWindowRT::onKafkaMessageReceived(QJsonObject message) { qDebug() << message; - std::cout << QString(QJsonDocument(message).toJson(QJsonDocument::Compact)).toStdString() << std::endl; + std::cout << "kafka message received: " << std::endl << QString(QJsonDocument(message).toJson(QJsonDocument::Compact)).toStdString() << std::endl; // 找不到deviceId deviceType operation三个必填项 直接返回 if (message.contains("deviceId") == false || message.contains("operation") == false || message.contains("deviceType") == false) { @@ -732,7 +1048,7 @@ void CounterWindowRT::onAlarmMessageReceived(QJsonObject alarmMsg) { qDebug() << alarmMsg; - std::cout << QString(QJsonDocument(alarmMsg).toJson(QJsonDocument::Compact)).toStdString() << std::endl; + std::cout << "alarm message received: " << std::endl << QString(QJsonDocument(alarmMsg).toJson(QJsonDocument::Compact)).toStdString() << std::endl; QString deviceId = alarmMsg.value("deviceId").toString(); QString channelId = alarmMsg.value("channelId").toString(); diff --git a/CounterRealTime/CounterWindowRT.h b/CounterRealTime/CounterWindowRT.h index b672cfc..b4eea96 100644 --- a/CounterRealTime/CounterWindowRT.h +++ b/CounterRealTime/CounterWindowRT.h @@ -17,10 +17,13 @@ #include "CounterSettingForm.h" #include "common/utils/SettingConfig.h" #include "common/utils/TimerCounterUtil.h" -#include "common/utils/QKafkaConsumer.h" #include "common/HttpRequestController.h" #include "common/HttpServer.h" +#ifdef unix +#include "common/utils/QKafkaConsumer.h" +#endif + QT_BEGIN_NAMESPACE namespace Ui { class CounterWindowRT; } QT_END_NAMESPACE @@ -47,12 +50,17 @@ QVector devTitleList; // 计数器设备标题的QLabel集合 QVector devRefList; // Ref通道 + QVector devCompRefList; // 归算Ref通道 QVector channelNameList; // 通道名的QLabel集合 QVector channelValueList; // 通道测量值的QLabel集合 + QVector computeValueList; // 通道归算值的QLabel集合 HttpRequestController * httpReq; + +#ifdef unix QKafkaConsumer * kafkaConsumer; QKafkaConsumer * alarmMsgConsumer; +#endif QVector alarmDev; QVector offlineDev; @@ -67,9 +75,13 @@ void initDevAndChannelForm(int count); void updateChannelDataForm(QJsonArray messageArray); void updateDeviceAlarm(QJsonArray alarmList); + void findRefAndMeasureChannel(); // 查找主备路的测量参考通道以及各自的测量通道 + double calculateAvgStandbyTimeDiff(QList thisChannel, QList refChannel, QList standbyChannel); + private slots: void updateDateAndTime(); + void watchStandbyConsistency(); int initHttpToken(); diff --git a/CounterRealTime/common/ConstCache.h b/CounterRealTime/common/ConstCache.h index 25a97d4..c5af508 100644 --- a/CounterRealTime/common/ConstCache.h +++ b/CounterRealTime/common/ConstCache.h @@ -31,6 +31,9 @@ QList deviceIdLoopB; // B路计数器对象集合 key=deviceId QMap channelMap; // 通道对象集合 key=deviceId-channelNo + QList loopInfos; // 存储主备路关键信息 参考钟编号;在对路的测量计数器ID;在对路的测量计数器所在通道ID;对路计数器所在的通道号 + QMap standbyMap; // 主路/备路通道的备路/主路对应通道key key=deviceId-channelNo value=deviceId-channelNo + QMap alarmDeviceMap; // 报警设备 QMap alarmChannelMap; // 报警通道 diff --git a/CounterRealTime/common/HttpRequestController.cpp b/CounterRealTime/common/HttpRequestController.cpp index 58ac632..0b8a3e4 100644 --- a/CounterRealTime/common/HttpRequestController.cpp +++ b/CounterRealTime/common/HttpRequestController.cpp @@ -130,7 +130,7 @@ } delete reply; - qDebug() << resultObj; +// qDebug() << resultObj; return resultObj; } @@ -239,7 +239,7 @@ } delete reply; - qDebug() << resultObj; +// qDebug() << "alarm List: " << resultObj; return resultObj; } diff --git a/CounterRealTime/CounterDevice.cpp b/CounterRealTime/CounterDevice.cpp index 4ff6565..f656746 100644 --- a/CounterRealTime/CounterDevice.cpp +++ b/CounterRealTime/CounterDevice.cpp @@ -9,11 +9,13 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &CounterDevice::dataReceivedHandler); +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); kafkaUtil.createProducer(); } +#endif } CounterDevice::~CounterDevice() @@ -78,6 +80,15 @@ this->refChannelCode = refChannelCode; } +int CounterDevice::getRefChannelNo() +{ + return this->refChannelNo; +} +void CounterDevice::setRefChannelNo(int refChannelNo) +{ + this->refChannelNo = refChannelNo; +} + bool CounterDevice::isSerialOpen() { return this->serialUtil.isOpen(); @@ -156,7 +167,7 @@ msgLogFilename = msgLogFilename.arg((hour / 6) * 6, 2, 10, QLatin1Char('0')); msgLogFilename = msgLogFilename.arg((hour / 6) * 6 + 5, 2, 10, QLatin1Char('0')); - CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(counterData->channelRefId)); + CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(counterData->channelRefId, 2, 10, QLatin1Char('0'))); this->refChannelNo = counterData->channelRefId; double refDelay = 0.0; if (refChanPtr != nullptr && refChanPtr->getDelays().isEmpty() == false) { @@ -186,7 +197,7 @@ } // 加到hisDataList中 用于绘制图表 - CounterChannel * channelPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i)); + CounterChannel * channelPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i, 2, 10, QLatin1Char('0'))); if (channelPtr != nullptr && channelPtr->isActive() == true) { // 通道时延值 并计算 减去时延值的测量值 @@ -210,6 +221,7 @@ statusObj.insert("master", SettingConfig::getInstance().MASTER); statusObj.insert("deviceId", deviceId); +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { if (SettingConfig::getInstance().MASTER == 0) @@ -227,6 +239,7 @@ kafkaUtil.produceMessage(SettingConfig::getInstance().KAFKA_STATUS_TOPIC, QString(QJsonDocument(statusObj).toJson(QJsonDocument::Compact))); } } +#endif QLogUtil::writeMessageLogByDate(date, msgLogFilename, QString(QJsonDocument(messageArray).toJson(QJsonDocument::Compact))); diff --git a/CounterRealTime/CounterDevice.h b/CounterRealTime/CounterDevice.h index c4d003d..68390c8 100644 --- a/CounterRealTime/CounterDevice.h +++ b/CounterRealTime/CounterDevice.h @@ -6,7 +6,6 @@ #include "CounterChannel.h" #include "common/utils/QSerialPortUtil.h" -#include "common/utils/QKafkaUtil.h" #include "common/utils/QByteUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" @@ -14,6 +13,10 @@ #include "common/LinearRegression.h" #include "protocol/CounterProtocolXH.h" +#ifdef unix +#include "common/utils/QKafkaUtil.h" +#endif + class CounterDevice : public QObject { Q_OBJECT @@ -37,6 +40,9 @@ int getIsUse(); void setIsUse(int isUse); + int getRefChannelNo(); + void setRefChannelNo(int refChannelNo); + QString getRefChannelCode(); void setRefChannelCode(QString refChannelCode); @@ -56,9 +62,12 @@ int formColIndex; QSerialPortUtil serialUtil; - QKafkaUtil kafkaUtil; QByteArray dataBuff; +#ifdef unix + QKafkaUtil kafkaUtil; +#endif + void afterFramePhase(CounterDataDto * counterData); void calcResidualClockData(qlonglong tm); diff --git a/CounterRealTime/CounterRealTime.pro b/CounterRealTime/CounterRealTime.pro index c323f04..f990ff3 100644 --- a/CounterRealTime/CounterRealTime.pro +++ b/CounterRealTime/CounterRealTime.pro @@ -49,7 +49,8 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka++ -lrdkafka +win32: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka++ -lrdkafka INCLUDEPATH += $$PWD/include/librdkafka DEPENDPATH += $$PWD/include/librdkafka diff --git a/CounterRealTime/CounterSettingForm.cpp b/CounterRealTime/CounterSettingForm.cpp index c1945d1..bc43ac7 100644 --- a/CounterRealTime/CounterSettingForm.cpp +++ b/CounterRealTime/CounterSettingForm.cpp @@ -335,7 +335,7 @@ active = activeListRight.at(i - 8)->isChecked(); } - CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1)); + CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1, 2, 10, QLatin1Char('0'))); if (channelPrt != nullptr) { bool isUpdated = isChannelSettingUpdated(i, channelPrt); @@ -362,7 +362,7 @@ newChannel->setChannelCode(channelCode); newChannel->setDelays(QString::number(delay)); - ConstCache::getInstance().channelMap.insert(QString("%1-%2").arg(deviceId).arg(i+1), newChannel); + ConstCache::getInstance().channelMap.insert(QString("%1-%2").arg(deviceId).arg(i+1, 2, 10, QLatin1Char('0')), newChannel); QJsonObject channelObj; channelObj.insert("id", ""); @@ -412,7 +412,7 @@ activeListLeft.at(i)->setCheckable(true); activeListRight.at(i)->setCheckable(true); - CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1)); + CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1, 2, 10, QLatin1Char('0'))); if (channelPrt != nullptr) { QString channelCode = channelPrt->getChannelCode(); // 通道钟号 @@ -429,7 +429,7 @@ } } - CounterChannel * channelRightPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1+8)); + CounterChannel * channelRightPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1+8, 2, 10, QLatin1Char('0'))); if (channelRightPrt != nullptr) { QString channelCode = channelRightPrt->getChannelCode(); // 通道钟号 diff --git a/CounterRealTime/CounterWindowRT.cpp b/CounterRealTime/CounterWindowRT.cpp index 30adf9b..78815d7 100644 --- a/CounterRealTime/CounterWindowRT.cpp +++ b/CounterRealTime/CounterWindowRT.cpp @@ -76,6 +76,7 @@ file.close(); } +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { // kafka consumer kafkaConsumer = new QKafkaConsumer(this); @@ -93,6 +94,7 @@ alarmMsgConsumer->start(); connect(alarmMsgConsumer, &QKafkaConsumer::messageRecieved, this, &CounterWindowRT::onAlarmMessageReceived); } +#endif // 绘制界面上的表格 initChannelForm(); @@ -100,6 +102,10 @@ // 显示时钟 每秒更新 connect(TimerCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &CounterWindowRT::updateDateAndTime); TimerCounterUtil::getInstance().clockCounter->start(1000); + QTimer::singleShot(30000, [=](){ + // 定时执行主备一致性监测 + connect(TimerCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &CounterWindowRT::watchStandbyConsistency); + }); // 重新选择显示多少个计数器 connect(settingForm, &CounterSettingForm::swiftDisplayLoop, this, &CounterWindowRT::updateDeviceWidget); @@ -182,7 +188,7 @@ } for (int i = 0; i < devSet.size(); i++) { - getChannelList(devSet.toList().at(i)); + getChannelList(devSet.values().at(i)); } } } @@ -233,6 +239,13 @@ } updateDeviceWidget(); + +// qDebug() << "loop A: " << ConstCache::getInstance().deviceIdLoopA; +// qDebug() << "loop B: " << ConstCache::getInstance().deviceIdLoopB; + + // 查找主路参考钟在备路计数器的测量通道 + // 查找备路参考钟在主路计数器的测量通道 + findRefAndMeasureChannel(); } } QList CounterWindowRT::getClockNumList() @@ -262,7 +275,8 @@ { // for (int i = 0; i <= 16; i++) { - ConstCache::getInstance().channelMap.remove(QString("%1-%2").arg(deviceId).arg(i)); + QString channelKey = QString("%1-%2").arg(deviceId).arg(i); + ConstCache::getInstance().channelMap.remove(channelKey); } // 将通道绘制在界面上 @@ -273,7 +287,7 @@ QJsonObject channelItem = channelArray.at(i).toObject(); QString channelId = channelItem.value("id").toString(); // 通道ID QString channelCode = channelItem.value("channelCode").toString(); // 通道钟号 - QString channelNo = QString::number(channelItem.value("channelNo").toInt()); // 通道序号 + QString channelNo = QString("%1").arg(channelItem.value("channelNo").toInt(), 2, 10, QLatin1Char('0')); // 通道序号 QString delays = channelItem.value("delays").toString(); // 通道时延值 QString isUse = channelItem.value("isUse").toString(); QString name = channelItem.value("name").toString(); @@ -292,6 +306,14 @@ // 添加到通道的集合中 key=deviceId-channelNo ConstCache::getInstance().channelMap.insert(deviceId + "-" + channelNo, channel); + + if (channelCode.isEmpty() == false && active == true) { + CounterDevice * counterDev = ConstCache::getInstance().deviceMap.value(deviceId); + if (counterDev != nullptr) { + QStringList channelBase; + channelBase << QString::number(counterDev->getIsUse()) << channelCode; + } + } } } } @@ -314,10 +336,12 @@ layoutChannelPage->setMargin(3); // 留出边框的位置 // 左右布局中是垂直布局,用于显示通道 - QVBoxLayout * layoutChannelLeft = new QVBoxLayout(); - QVBoxLayout * layoutChannelRight = new QVBoxLayout(); + QVBoxLayout * layoutChannelLeft = new QVBoxLayout(); // 最左侧显示设备简称 + QVBoxLayout * layoutChannelMain = new QVBoxLayout(); // 中间显示参考通道 + QVBoxLayout * layoutChannelRight = new QVBoxLayout(); // 最右侧显示归算参考通道 字号小一号 layoutChannelLeft->setSpacing(0); + layoutChannelMain->setSpacing(0); layoutChannelRight->setSpacing(0); // 设备标题的Label @@ -330,55 +354,76 @@ // 设备参考通道的Label QLabel * labDevRef = new QLabel(widgetDev); labDevRef->setProperty("labType", QString("devRef%1").arg(count)); // 样式表属性 - labDevRef->setText(QString("REF: %1").arg("1000")); + labDevRef->setText(QString("REF: %1").arg("10000")); labDevRef->setAlignment(Qt::AlignCenter); // 文字居中显示 devRefList.append(labDevRef); + // 设置归算使用的参考通道Label + QLabel * labCompDevRef = new QLabel(widgetDev); + labCompDevRef->setProperty("labType", QString("devCompRef%1").arg(count)); // 样式表属性 + labCompDevRef->setText(QString("%1").arg("主备时差")); + labCompDevRef->setAlignment(Qt::AlignCenter); // 文字居中显示 + devCompRefList.append(labCompDevRef); + if (count == 4) { labDevTitle->setMaximumHeight(80); // 设置固定高度 labDevTitle->setMinimumHeight(80); labDevRef->setMaximumHeight(80); // 设置固定高度 labDevRef->setMinimumHeight(80); + + labCompDevRef->setMaximumHeight(80); // 设置固定高度 + labCompDevRef->setMinimumHeight(80); } else { labDevTitle->setMaximumHeight(60); // 设置固定高度 labDevTitle->setMinimumHeight(60); labDevRef->setMaximumHeight(60); // 设置固定高度 labDevRef->setMinimumHeight(60); + + labCompDevRef->setMaximumHeight(60); // 设置固定高度 + labCompDevRef->setMinimumHeight(60); } // 左侧显示设备简称,右侧显示参考通道名 layoutChannelLeft->addWidget(labDevTitle); - layoutChannelRight->addWidget(labDevRef); + layoutChannelMain->addWidget(labDevRef); + layoutChannelRight->addWidget(labCompDevRef); // 每个计数器显示16个通道 for ( int i = 0; i < 16; i++ ) { QLabelDblClick * labChannelName = new QLabelDblClick(widgetDev); // 通道名 QLabelDblClick * labChannelValue = new QLabelDblClick(widgetDev); // 通道测量值 + QLabelDblClick * labComputeValue = new QLabelDblClick(widgetDev); // 通道归算值 // 默认显示内容 - labChannelName->setText(QString("CH%1").arg(i+1, 2, 10, QLatin1Char('0'))); + labChannelName->setText(QString("%1: 10000").arg(i+1, 2, 10, QLatin1Char('0'))); labChannelValue->setText("0.000000000000"); + labComputeValue->setText(""); // css不支持的样式用代码实现 - labChannelName->setMargin(10); - labChannelValue->setMargin(10); + labChannelName->setMargin(5); + labChannelValue->setMargin(5); labChannelValue->setAlignment(Qt::AlignRight | Qt::AlignVCenter); + labComputeValue->setMargin(5); + labComputeValue->setAlignment(Qt::AlignRight | Qt::AlignVCenter); // 奇偶显示不同的背景色 if (i % 2 == 0) { labChannelName->setProperty("labType", QString("channelNameEven%1").arg(count)); labChannelValue->setProperty("labType", QString("channelValueEven%1").arg(count)); + labComputeValue->setProperty("labType", QString("computeValueEven%1").arg(count)); } else { labChannelName->setProperty("labType", QString("channelNameOdd%1").arg(count)); labChannelValue->setProperty("labType", QString("channelValueOdd%1").arg(count)); + labComputeValue->setProperty("labType", QString("computeValueOdd%1").arg(count)); } layoutChannelLeft->addWidget(labChannelName); - layoutChannelRight->addWidget(labChannelValue); + layoutChannelMain->addWidget(labChannelValue); + layoutChannelRight->addWidget(labComputeValue); // 添加通道名称的双击事件,显示数据和残差图表 connect(labChannelName, &QLabelDblClick::doubleClicked, this, &CounterWindowRT::onChannelNameLabelDblClicked); @@ -386,16 +431,21 @@ channelNameList.append(labChannelName); channelValueList.append(labChannelValue); + computeValueList.append(labComputeValue); // 左下角和右下角的圆角处理 if (i == 15) { labChannelName->setStyleSheet("border-bottom-left-radius: 10px;"); - labChannelValue->setStyleSheet("border-bottom-right-radius: 10px;"); + labComputeValue->setStyleSheet("border-bottom-right-radius: 10px;"); } } layoutChannelPage->addLayout(layoutChannelLeft); + layoutChannelPage->addLayout(layoutChannelMain); layoutChannelPage->addLayout(layoutChannelRight); + layoutChannelPage->setStretch(0, 35); + layoutChannelPage->setStretch(1, 50); + layoutChannelPage->setStretch(2, 15); widgetDev->setLayout(layoutChannelPage); } } @@ -407,13 +457,19 @@ // 参考通道号 int refChNo = messageArray.at(0).toObject().value("data").toObject().value("channelRefNo").toInt(); + CounterDevice * counter = ConstCache::getInstance().deviceMap.value(deviceId); + if (counter == nullptr) { + return; + } + counter->setRefChannelNo(refChNo); + // 根据设备id 从map中取出列索引的值 - int devIdx = ConstCache::getInstance().deviceMap.value(deviceId)->getFormColIndex(); + int devIdx = counter->getFormColIndex(); if (devIdx < devRefList.size()) { // 参考通道的显示 QString refText = devRefList.at(devIdx)->text(); - channelNameList.at(devIdx * 16 + refChNo - 1)->setText(QString("CH%1:%2").arg(refChNo, 2, 10, QLatin1Char('0')).arg(refText.right(refText.length() - 4))); + channelNameList.at(devIdx * 16 + refChNo - 1)->setText(QString("%1:%2").arg(refChNo, 2, 10, QLatin1Char('0')).arg(refText.right(refText.length() - 4))); if (alarmDev.contains(deviceId) == true) { @@ -433,11 +489,11 @@ for (int i = 0; i < messageArray.size(); i++) { QJsonObject channelDataItem = messageArray.at(i).toObject(); - QString channelNo = QString::number(channelDataItem.value("channelNo").toInt()); // 通道序号 + QString channelNo = QString("%1").arg(channelDataItem.value("channelNo").toInt(), 2, 10, QLatin1Char('0')); // 通道序号 channelDataJsonMap.insert(channelNo, channelDataItem); } - CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo)); + CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo, 2, 10, QLatin1Char('0'))); double refDelay = 0.0; if (refChanPtr != nullptr && refChanPtr->getDelays().isEmpty() == false) { refDelay = refChanPtr->getDelays().toDouble(); @@ -454,11 +510,10 @@ continue; } - CounterChannel * channel = ConstCache::getInstance().channelMap.value(deviceId + "-" + channelNo); // 从map中找到对应的通道 - - if (channelDataJsonMap.contains(channelNo) == true) + CounterChannel * channel = ConstCache::getInstance().channelMap.value(deviceId + "-" + channelNoStr); // 从map中找到对应的通道 + if (channelDataJsonMap.contains(channelNoStr) == true) { - QJsonObject channelDataItem = channelDataJsonMap.value(channelNo); + QJsonObject channelDataItem = channelDataJsonMap.value(channelNoStr); // 通道Label的序号 int channelIdx = devIdx * 16 + channelDataItem.value("channelNo").toInt() - 1; @@ -483,19 +538,20 @@ double valueMinusDelay = channelDataItem.value("data").toObject().value("dataValue").toString().toDouble() - delay * 1E-9 + refDelay * 1E-9; // 设置通道名和测量值的QLabel - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); channelValueList.at(channelIdx)->setText(QString::number(valueMinusDelay, 'f', 12)); channelNameList.at(channelIdx)->setProperty("channelId", channel->getChannelId()); channelNameList.at(channelIdx)->setProperty("deviceId", deviceId); - channelNameList.at(channelIdx)->setProperty("channelNo", channelNo); + channelNameList.at(channelIdx)->setProperty("channelNo", channelNoStr); channelValueList.at(channelIdx)->setProperty("channelId", channel->getChannelId()); channelValueList.at(channelIdx)->setProperty("deviceId", deviceId); - channelValueList.at(channelIdx)->setProperty("channelNo", channelNo); + channelValueList.at(channelIdx)->setProperty("channelNo", channelNoStr); } else { - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg("-")); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg("-")); channelValueList.at(channelIdx)->setText(""); + computeValueList.at(channelIdx)->setText(""); } } else { // 计数器返回的无测量值的通道处理逻辑 @@ -503,6 +559,7 @@ // 没有测量值的通道清空 channelValueList.at(channelIdx)->setText(""); + computeValueList.at(channelIdx)->setText(""); // 当通道启用时显示通道离线 不再判断后台传回来的状态 // 当通道未启用时显示正常状态 @@ -510,12 +567,12 @@ channelNameList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value("channelOffline")); channelValueList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value("channelOffline")); - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); } else { channelNameList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value(channelNameList.at(channelIdx)->property("labType").toString())); channelValueList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value(channelValueList.at(channelIdx)->property("labType").toString())); - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg("-")); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg("-")); } } } @@ -523,7 +580,7 @@ void CounterWindowRT::updateDeviceAlarm(QJsonArray alarmList) { - qDebug() << alarmList; +// qDebug() << alarmList; for (int i = 0; i < alarmList.size(); i++) { QJsonObject alarmData = alarmList.at(i).toObject(); @@ -532,7 +589,7 @@ QString alarmCode = alarmData.value("alarmCode").toString(); QString status = alarmData.value("status").toString(); - qDebug() << alarmCode << deviceId << channelId; +// qDebug() << alarmCode << deviceId << channelId; // 如果报警状态不是正在报警 status==0 或者报警设备不是计数器 则不处理 if (status != "0" || ConstCache::getInstance().deviceMap.contains(deviceId) == false) @@ -560,6 +617,92 @@ } } +void CounterWindowRT::findRefAndMeasureChannel() +{ + // 查询主路的参考通道的钟编号 + QString masterKey = QString("%1-%2").arg(ConstCache::getInstance().deviceIdLoopA.at(0)).arg("01"); // 暂时固定为01通道 + CounterChannel * refChannelMaster = ConstCache::getInstance().channelMap.value(masterKey); // 主路参考的钟编号 + + // 查询主路参考通道在备路的测量通道 + for (QString channelKey : ConstCache::getInstance().channelMap.keys()) { + QString deviceId = channelKey.split("-")[0]; + if (ConstCache::getInstance().deviceIdLoopB.contains(deviceId)) { + CounterChannel * channel = ConstCache::getInstance().channelMap.value(channelKey); + if (channel->getChannelCode() == refChannelMaster->getChannelCode()) { + QStringList masterInfo; + masterInfo << refChannelMaster->getChannelCode() << deviceId << channel->getChannelId() << channel->getChannelNo(); + ConstCache::getInstance().loopInfos.append(masterInfo); + + break; + } + } + } + + // 查询备路的参考通道钟编号 + QString slaveKey = QString("%1-%2").arg(ConstCache::getInstance().deviceIdLoopB.at(0)).arg("01"); // 暂时固定为01通道 + CounterChannel * refChannelSlave = ConstCache::getInstance().channelMap.value(slaveKey); // 备路参考的钟编号 + + // 查询备路参考通道在主路的测量通道 + for (QString channelKey : ConstCache::getInstance().channelMap.keys()) { + QString deviceId = channelKey.split("-")[0]; + if (ConstCache::getInstance().deviceIdLoopA.contains(deviceId)) { + CounterChannel * channel = ConstCache::getInstance().channelMap.value(channelKey); + if (channel->getChannelCode() == refChannelSlave->getChannelCode()) { + QStringList slaveInfo; + slaveInfo << refChannelSlave->getChannelCode() << deviceId << channel->getChannelId() << channel->getChannelNo(); + ConstCache::getInstance().loopInfos.append(slaveInfo); + + break; + } + } + } + +// qDebug() << ConstCache::getInstance().loopInfos.at(0); +// qDebug() << ConstCache::getInstance().loopInfos.at(1); +// qDebug() << ConstCache::getInstance().channelMap; +} + +double CounterWindowRT::calculateAvgStandbyTimeDiff(QList thisChannel, + QList refChannel, + QList standbyChannel) +{ + double avgTimeDiff = 0.0; + + if (thisChannel.isEmpty() || refChannel.isEmpty() || standbyChannel.isEmpty()) { + return avgTimeDiff; + } + + double sumThis = 0.0; + double avgThis = 0.0; + int countThis = 0; + for (QStringList thisData : thisChannel) { + sumThis += thisData.at(1).toDouble(); + countThis++; + } + avgThis = sumThis / countThis * 1.0; + + double sumRef = 0.0; + double avgRef = 0.0; + int countRef = 0; + for (QStringList refData : refChannel) { + sumRef += refData.at(1).toDouble(); + countRef++; + } + avgRef = sumRef / countRef * 1.0; + + double sumStandby = 0.0; + double avgStandby = 0.0; + int countStandby = 0; + for (QStringList standbyData : standbyChannel) { + sumStandby += standbyData.at(1).toDouble(); + countStandby++; + } + avgStandby = sumStandby / countStandby * 1.0; + + avgTimeDiff = avgThis - avgRef - avgStandby; + return avgTimeDiff; +} + void CounterWindowRT::updateDateAndTime() { QString date = QDate::currentDate().toString("yyyy-MM-dd"); @@ -567,6 +710,171 @@ ui->labTime->setText(date + " " + time); } +void CounterWindowRT::watchStandbyConsistency() +{ + quint8 second = QTime::currentTime().second(); + if (second % SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND == 0) { + qDebug() << "watchStandbyConsistency: " << QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"); + // 1. 遍历所有的主路计数器 + for (QString devAId : ConstCache::getInstance().deviceIdLoopA) { + // 2. 遍历主路计数器的每一个通道(除参考通道外) + for (QString key : ConstCache::getInstance().channelMap.keys()) { + if (key.contains(devAId) == false) { + continue; + } else { + // A当前通道 + CounterChannel * channel = ConstCache::getInstance().channelMap.value(key); + QString channelCode = channel->getChannelCode(); // 钟编号 + QString channelNo = channel->getChannelNo(); // 通道号 + + if (channelNo == "00" || channelNo == "01" || channelCode.isEmpty()) { + continue; + } + + // B备路参考通道在主路的测量通道 + CounterChannel * standbyRefChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(ConstCache::getInstance().loopInfos.at(1).at(1)).arg(ConstCache::getInstance().loopInfos.at(1).at(3))); + + // 3. 获得通道的钟编号、通道号,找到对应钟编号、通道号在备路对应的通道 + // C对应的备路测量通道 + QString standbyKey = ""; + CounterChannel * standbyChannel = nullptr; + if (ConstCache::getInstance().standbyMap.contains(key) == false) { + // 在对路计数器中找 并存入standbyMap + for (QString standbyDevId : ConstCache::getInstance().deviceIdLoopB) { + // 通道号和钟编号都匹配 + standbyChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(standbyDevId).arg(channelNo)); + if (standbyChannel != nullptr && standbyChannel->getChannelCode() == channelCode) { + standbyKey = QString("%1-%2").arg(standbyDevId).arg(channelNo); + ConstCache::getInstance().standbyMap.insert(key, standbyKey); + } + } + } else { + standbyKey = ConstCache::getInstance().standbyMap.value(key); + standbyChannel = ConstCache::getInstance().channelMap.value(standbyKey); + } + + // 4. 取当前通道的最后10个历史数据 channel + QList thisChannelDataList; + if (channel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + thisChannelDataList = channel->getHisData().mid(channel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 5. 取备路参考通道最后10个历史数据 standbyRefChannel + QList standbyRefChannelDataList; + if (standbyRefChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyRefChannelDataList = standbyRefChannel->getHisData().mid(standbyRefChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 6. 取备路计数器对应通道的最后10个历史数据 standbyChannel + QList standbyChannelDataList; + if (standbyChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyChannelDataList = standbyChannel->getHisData().mid(standbyChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 7. 计算当前通道相对备路参考钟的时差 与备路对应通道的时差做差 + if (thisChannelDataList.isEmpty() || standbyChannelDataList.isEmpty()) { + continue; + } + double avgTimeDiff = calculateAvgStandbyTimeDiff(thisChannelDataList, standbyRefChannelDataList, standbyChannelDataList); + + // 8. 显示在界面上 + CounterDevice * devicePtr = ConstCache::getInstance().deviceMap.value(devAId); + if (devicePtr != nullptr && SettingConfig::getInstance().MASTER == devicePtr->getIsUse()) + { + int devIdx = devicePtr->getFormColIndex(); + + // 通道Label的序号 + int channelIdx = devIdx * 16 + channelNo.toInt() - 1; + computeValueList.at(channelIdx)->setText(QString::number(avgTimeDiff * 1E9, 'f', 3)); + } + } + } + } + + // 8. 遍历所有的备路计数器 + for (QString devBId : ConstCache::getInstance().deviceIdLoopB) { + // 2. 遍历主路计数器的每一个通道(除参考通道外) + for (QString key : ConstCache::getInstance().channelMap.keys()) { + if (key.contains(devBId) == false) { + continue; + } else { + // A当前通道 + CounterChannel * channel = ConstCache::getInstance().channelMap.value(key); + QString channelCode = channel->getChannelCode(); // 钟编号 + QString channelNo = channel->getChannelNo(); // 通道号 + + if (channelNo == "00" || channelNo == "01" || channelCode.isEmpty()) { + continue; + } + + // B主路参考通道在主路的测量通道 + CounterChannel * standbyRefChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(ConstCache::getInstance().loopInfos.at(0).at(1)).arg(ConstCache::getInstance().loopInfos.at(0).at(3))); + + // 3. 获得通道的钟编号、通道号,找到对应钟编号、通道号在备路对应的通道 + // C对应的主路测量通道 + QString standbyKey = ""; + CounterChannel * standbyChannel = nullptr; + if (ConstCache::getInstance().standbyMap.contains(key) == false) { + // 在对路计数器中找 并存入standbyMap + for (QString standbyDevId : ConstCache::getInstance().deviceIdLoopA) { + // 通道号和钟编号都匹配 + standbyChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(standbyDevId).arg(channelNo)); + if (standbyChannel != nullptr && standbyChannel->getChannelCode() == channelCode) { + standbyKey = QString("%1-%2").arg(standbyDevId).arg(channelNo); + ConstCache::getInstance().standbyMap.insert(key, standbyKey); + } + } + } else { + standbyKey = ConstCache::getInstance().standbyMap.value(key); + standbyChannel = ConstCache::getInstance().channelMap.value(standbyKey); + } + + // 4. 取当前通道的最后10个历史数据 channel + QList thisChannelDataList; + if (channel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + thisChannelDataList = channel->getHisData().mid(channel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 5. 取主路参考通道最后10个历史数据 standbyRefChannel + QList standbyRefChannelDataList; + if (standbyRefChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyRefChannelDataList = standbyRefChannel->getHisData().mid(standbyRefChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 6. 取主路计数器对应通道的最后10个历史数据 standbyChannel + QList standbyChannelDataList; + if (standbyChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyChannelDataList = standbyChannel->getHisData().mid(standbyChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 7. 计算当前通道相对主路参考钟的时差 与主路对应通道的时差做差 + if (thisChannelDataList.isEmpty() || standbyChannelDataList.isEmpty()) { + continue; + } + double avgTimeDiff = calculateAvgStandbyTimeDiff(thisChannelDataList, standbyRefChannelDataList, standbyChannelDataList); + + // 8. 显示在界面上 + CounterDevice * devicePtr = ConstCache::getInstance().deviceMap.value(devBId); + if (devicePtr != nullptr && SettingConfig::getInstance().MASTER == devicePtr->getIsUse()) + { + int devIdx = devicePtr->getFormColIndex(); + + // 通道Label的序号 + int channelIdx = devIdx * 16 + channelNo.toInt() - 1; + computeValueList.at(channelIdx)->setText(QString::number(avgTimeDiff * 1E9, 'f', 3)); + } + } + } + } + } +} + void CounterWindowRT::on_btnMenuSetting_clicked() { settingForm->setWindowModality(Qt::ApplicationModal); @@ -600,8 +908,10 @@ // 将lab列表的数量置0 devTitleList.resize(0); devRefList.resize(0); + devCompRefList.resize(0); channelNameList.resize(0); channelValueList.resize(0); + computeValueList.resize(0); initDevAndChannelForm(SettingConfig::getInstance().DISPLAY_COUNT); } @@ -620,14 +930,20 @@ devTitleList.at(i)->setText(dev->getDeviceName()); // 设备名称 dev->setFormColIndex(i); } + for (int j = 1; j < 16; j++) + { + computeValueList.at(i * 16 + j)->setText("-"); + } } else { devTitleList.at(i)->setText(""); devRefList.at(i)->setText(""); + devCompRefList.at(i)->setText(""); for (int j = 0; j < 16; j++) { channelNameList.at(i * 16 + j)->setText(""); channelValueList.at(i * 16 + j)->setText(""); + computeValueList.at(i * 16 + j)->setText(""); } } } @@ -685,7 +1001,7 @@ // 参考通道 int refChNo = messageArray.at(0).toObject().value("data").toObject().value("channelRefNo").toInt(); - CounterChannel * refChann = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo)); + CounterChannel * refChann = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo, 2, 10, QLatin1Char('0'))); if (refChann != nullptr) { if (devIdx < devRefList.size()) { @@ -704,7 +1020,7 @@ void CounterWindowRT::onKafkaMessageReceived(QJsonObject message) { qDebug() << message; - std::cout << QString(QJsonDocument(message).toJson(QJsonDocument::Compact)).toStdString() << std::endl; + std::cout << "kafka message received: " << std::endl << QString(QJsonDocument(message).toJson(QJsonDocument::Compact)).toStdString() << std::endl; // 找不到deviceId deviceType operation三个必填项 直接返回 if (message.contains("deviceId") == false || message.contains("operation") == false || message.contains("deviceType") == false) { @@ -732,7 +1048,7 @@ void CounterWindowRT::onAlarmMessageReceived(QJsonObject alarmMsg) { qDebug() << alarmMsg; - std::cout << QString(QJsonDocument(alarmMsg).toJson(QJsonDocument::Compact)).toStdString() << std::endl; + std::cout << "alarm message received: " << std::endl << QString(QJsonDocument(alarmMsg).toJson(QJsonDocument::Compact)).toStdString() << std::endl; QString deviceId = alarmMsg.value("deviceId").toString(); QString channelId = alarmMsg.value("channelId").toString(); diff --git a/CounterRealTime/CounterWindowRT.h b/CounterRealTime/CounterWindowRT.h index b672cfc..b4eea96 100644 --- a/CounterRealTime/CounterWindowRT.h +++ b/CounterRealTime/CounterWindowRT.h @@ -17,10 +17,13 @@ #include "CounterSettingForm.h" #include "common/utils/SettingConfig.h" #include "common/utils/TimerCounterUtil.h" -#include "common/utils/QKafkaConsumer.h" #include "common/HttpRequestController.h" #include "common/HttpServer.h" +#ifdef unix +#include "common/utils/QKafkaConsumer.h" +#endif + QT_BEGIN_NAMESPACE namespace Ui { class CounterWindowRT; } QT_END_NAMESPACE @@ -47,12 +50,17 @@ QVector devTitleList; // 计数器设备标题的QLabel集合 QVector devRefList; // Ref通道 + QVector devCompRefList; // 归算Ref通道 QVector channelNameList; // 通道名的QLabel集合 QVector channelValueList; // 通道测量值的QLabel集合 + QVector computeValueList; // 通道归算值的QLabel集合 HttpRequestController * httpReq; + +#ifdef unix QKafkaConsumer * kafkaConsumer; QKafkaConsumer * alarmMsgConsumer; +#endif QVector alarmDev; QVector offlineDev; @@ -67,9 +75,13 @@ void initDevAndChannelForm(int count); void updateChannelDataForm(QJsonArray messageArray); void updateDeviceAlarm(QJsonArray alarmList); + void findRefAndMeasureChannel(); // 查找主备路的测量参考通道以及各自的测量通道 + double calculateAvgStandbyTimeDiff(QList thisChannel, QList refChannel, QList standbyChannel); + private slots: void updateDateAndTime(); + void watchStandbyConsistency(); int initHttpToken(); diff --git a/CounterRealTime/common/ConstCache.h b/CounterRealTime/common/ConstCache.h index 25a97d4..c5af508 100644 --- a/CounterRealTime/common/ConstCache.h +++ b/CounterRealTime/common/ConstCache.h @@ -31,6 +31,9 @@ QList deviceIdLoopB; // B路计数器对象集合 key=deviceId QMap channelMap; // 通道对象集合 key=deviceId-channelNo + QList loopInfos; // 存储主备路关键信息 参考钟编号;在对路的测量计数器ID;在对路的测量计数器所在通道ID;对路计数器所在的通道号 + QMap standbyMap; // 主路/备路通道的备路/主路对应通道key key=deviceId-channelNo value=deviceId-channelNo + QMap alarmDeviceMap; // 报警设备 QMap alarmChannelMap; // 报警通道 diff --git a/CounterRealTime/common/HttpRequestController.cpp b/CounterRealTime/common/HttpRequestController.cpp index 58ac632..0b8a3e4 100644 --- a/CounterRealTime/common/HttpRequestController.cpp +++ b/CounterRealTime/common/HttpRequestController.cpp @@ -130,7 +130,7 @@ } delete reply; - qDebug() << resultObj; +// qDebug() << resultObj; return resultObj; } @@ -239,7 +239,7 @@ } delete reply; - qDebug() << resultObj; +// qDebug() << "alarm List: " << resultObj; return resultObj; } diff --git a/CounterRealTime/common/common.pri b/CounterRealTime/common/common.pri index aa3f245..9d51c30 100644 --- a/CounterRealTime/common/common.pri +++ b/CounterRealTime/common/common.pri @@ -1,10 +1,7 @@ - SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp -SOURCES += $$PWD/utils/QKafkaUtil.cpp -SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/LinearRegression.cpp @@ -16,8 +13,6 @@ HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h -HEADERS += $$PWD/utils/QKafkaUtil.h -HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h @@ -25,3 +20,11 @@ HEADERS += $$PWD/HttpRequestController.h HEADERS += $$PWD/HttpServer.h HEADERS += $$PWD/ConstCache.h + +unix { + SOURCES += $$PWD/utils/QKafkaUtil.cpp + SOURCES += $$PWD/utils/QKafkaConsumer.cpp + + HEADERS += $$PWD/utils/QKafkaUtil.h + HEADERS += $$PWD/utils/QKafkaConsumer.h +} diff --git a/CounterRealTime/CounterDevice.cpp b/CounterRealTime/CounterDevice.cpp index 4ff6565..f656746 100644 --- a/CounterRealTime/CounterDevice.cpp +++ b/CounterRealTime/CounterDevice.cpp @@ -9,11 +9,13 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &CounterDevice::dataReceivedHandler); +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); kafkaUtil.createProducer(); } +#endif } CounterDevice::~CounterDevice() @@ -78,6 +80,15 @@ this->refChannelCode = refChannelCode; } +int CounterDevice::getRefChannelNo() +{ + return this->refChannelNo; +} +void CounterDevice::setRefChannelNo(int refChannelNo) +{ + this->refChannelNo = refChannelNo; +} + bool CounterDevice::isSerialOpen() { return this->serialUtil.isOpen(); @@ -156,7 +167,7 @@ msgLogFilename = msgLogFilename.arg((hour / 6) * 6, 2, 10, QLatin1Char('0')); msgLogFilename = msgLogFilename.arg((hour / 6) * 6 + 5, 2, 10, QLatin1Char('0')); - CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(counterData->channelRefId)); + CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(counterData->channelRefId, 2, 10, QLatin1Char('0'))); this->refChannelNo = counterData->channelRefId; double refDelay = 0.0; if (refChanPtr != nullptr && refChanPtr->getDelays().isEmpty() == false) { @@ -186,7 +197,7 @@ } // 加到hisDataList中 用于绘制图表 - CounterChannel * channelPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i)); + CounterChannel * channelPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i, 2, 10, QLatin1Char('0'))); if (channelPtr != nullptr && channelPtr->isActive() == true) { // 通道时延值 并计算 减去时延值的测量值 @@ -210,6 +221,7 @@ statusObj.insert("master", SettingConfig::getInstance().MASTER); statusObj.insert("deviceId", deviceId); +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { if (SettingConfig::getInstance().MASTER == 0) @@ -227,6 +239,7 @@ kafkaUtil.produceMessage(SettingConfig::getInstance().KAFKA_STATUS_TOPIC, QString(QJsonDocument(statusObj).toJson(QJsonDocument::Compact))); } } +#endif QLogUtil::writeMessageLogByDate(date, msgLogFilename, QString(QJsonDocument(messageArray).toJson(QJsonDocument::Compact))); diff --git a/CounterRealTime/CounterDevice.h b/CounterRealTime/CounterDevice.h index c4d003d..68390c8 100644 --- a/CounterRealTime/CounterDevice.h +++ b/CounterRealTime/CounterDevice.h @@ -6,7 +6,6 @@ #include "CounterChannel.h" #include "common/utils/QSerialPortUtil.h" -#include "common/utils/QKafkaUtil.h" #include "common/utils/QByteUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" @@ -14,6 +13,10 @@ #include "common/LinearRegression.h" #include "protocol/CounterProtocolXH.h" +#ifdef unix +#include "common/utils/QKafkaUtil.h" +#endif + class CounterDevice : public QObject { Q_OBJECT @@ -37,6 +40,9 @@ int getIsUse(); void setIsUse(int isUse); + int getRefChannelNo(); + void setRefChannelNo(int refChannelNo); + QString getRefChannelCode(); void setRefChannelCode(QString refChannelCode); @@ -56,9 +62,12 @@ int formColIndex; QSerialPortUtil serialUtil; - QKafkaUtil kafkaUtil; QByteArray dataBuff; +#ifdef unix + QKafkaUtil kafkaUtil; +#endif + void afterFramePhase(CounterDataDto * counterData); void calcResidualClockData(qlonglong tm); diff --git a/CounterRealTime/CounterRealTime.pro b/CounterRealTime/CounterRealTime.pro index c323f04..f990ff3 100644 --- a/CounterRealTime/CounterRealTime.pro +++ b/CounterRealTime/CounterRealTime.pro @@ -49,7 +49,8 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka++ -lrdkafka +win32: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka++ -lrdkafka INCLUDEPATH += $$PWD/include/librdkafka DEPENDPATH += $$PWD/include/librdkafka diff --git a/CounterRealTime/CounterSettingForm.cpp b/CounterRealTime/CounterSettingForm.cpp index c1945d1..bc43ac7 100644 --- a/CounterRealTime/CounterSettingForm.cpp +++ b/CounterRealTime/CounterSettingForm.cpp @@ -335,7 +335,7 @@ active = activeListRight.at(i - 8)->isChecked(); } - CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1)); + CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1, 2, 10, QLatin1Char('0'))); if (channelPrt != nullptr) { bool isUpdated = isChannelSettingUpdated(i, channelPrt); @@ -362,7 +362,7 @@ newChannel->setChannelCode(channelCode); newChannel->setDelays(QString::number(delay)); - ConstCache::getInstance().channelMap.insert(QString("%1-%2").arg(deviceId).arg(i+1), newChannel); + ConstCache::getInstance().channelMap.insert(QString("%1-%2").arg(deviceId).arg(i+1, 2, 10, QLatin1Char('0')), newChannel); QJsonObject channelObj; channelObj.insert("id", ""); @@ -412,7 +412,7 @@ activeListLeft.at(i)->setCheckable(true); activeListRight.at(i)->setCheckable(true); - CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1)); + CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1, 2, 10, QLatin1Char('0'))); if (channelPrt != nullptr) { QString channelCode = channelPrt->getChannelCode(); // 通道钟号 @@ -429,7 +429,7 @@ } } - CounterChannel * channelRightPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1+8)); + CounterChannel * channelRightPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1+8, 2, 10, QLatin1Char('0'))); if (channelRightPrt != nullptr) { QString channelCode = channelRightPrt->getChannelCode(); // 通道钟号 diff --git a/CounterRealTime/CounterWindowRT.cpp b/CounterRealTime/CounterWindowRT.cpp index 30adf9b..78815d7 100644 --- a/CounterRealTime/CounterWindowRT.cpp +++ b/CounterRealTime/CounterWindowRT.cpp @@ -76,6 +76,7 @@ file.close(); } +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { // kafka consumer kafkaConsumer = new QKafkaConsumer(this); @@ -93,6 +94,7 @@ alarmMsgConsumer->start(); connect(alarmMsgConsumer, &QKafkaConsumer::messageRecieved, this, &CounterWindowRT::onAlarmMessageReceived); } +#endif // 绘制界面上的表格 initChannelForm(); @@ -100,6 +102,10 @@ // 显示时钟 每秒更新 connect(TimerCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &CounterWindowRT::updateDateAndTime); TimerCounterUtil::getInstance().clockCounter->start(1000); + QTimer::singleShot(30000, [=](){ + // 定时执行主备一致性监测 + connect(TimerCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &CounterWindowRT::watchStandbyConsistency); + }); // 重新选择显示多少个计数器 connect(settingForm, &CounterSettingForm::swiftDisplayLoop, this, &CounterWindowRT::updateDeviceWidget); @@ -182,7 +188,7 @@ } for (int i = 0; i < devSet.size(); i++) { - getChannelList(devSet.toList().at(i)); + getChannelList(devSet.values().at(i)); } } } @@ -233,6 +239,13 @@ } updateDeviceWidget(); + +// qDebug() << "loop A: " << ConstCache::getInstance().deviceIdLoopA; +// qDebug() << "loop B: " << ConstCache::getInstance().deviceIdLoopB; + + // 查找主路参考钟在备路计数器的测量通道 + // 查找备路参考钟在主路计数器的测量通道 + findRefAndMeasureChannel(); } } QList CounterWindowRT::getClockNumList() @@ -262,7 +275,8 @@ { // for (int i = 0; i <= 16; i++) { - ConstCache::getInstance().channelMap.remove(QString("%1-%2").arg(deviceId).arg(i)); + QString channelKey = QString("%1-%2").arg(deviceId).arg(i); + ConstCache::getInstance().channelMap.remove(channelKey); } // 将通道绘制在界面上 @@ -273,7 +287,7 @@ QJsonObject channelItem = channelArray.at(i).toObject(); QString channelId = channelItem.value("id").toString(); // 通道ID QString channelCode = channelItem.value("channelCode").toString(); // 通道钟号 - QString channelNo = QString::number(channelItem.value("channelNo").toInt()); // 通道序号 + QString channelNo = QString("%1").arg(channelItem.value("channelNo").toInt(), 2, 10, QLatin1Char('0')); // 通道序号 QString delays = channelItem.value("delays").toString(); // 通道时延值 QString isUse = channelItem.value("isUse").toString(); QString name = channelItem.value("name").toString(); @@ -292,6 +306,14 @@ // 添加到通道的集合中 key=deviceId-channelNo ConstCache::getInstance().channelMap.insert(deviceId + "-" + channelNo, channel); + + if (channelCode.isEmpty() == false && active == true) { + CounterDevice * counterDev = ConstCache::getInstance().deviceMap.value(deviceId); + if (counterDev != nullptr) { + QStringList channelBase; + channelBase << QString::number(counterDev->getIsUse()) << channelCode; + } + } } } } @@ -314,10 +336,12 @@ layoutChannelPage->setMargin(3); // 留出边框的位置 // 左右布局中是垂直布局,用于显示通道 - QVBoxLayout * layoutChannelLeft = new QVBoxLayout(); - QVBoxLayout * layoutChannelRight = new QVBoxLayout(); + QVBoxLayout * layoutChannelLeft = new QVBoxLayout(); // 最左侧显示设备简称 + QVBoxLayout * layoutChannelMain = new QVBoxLayout(); // 中间显示参考通道 + QVBoxLayout * layoutChannelRight = new QVBoxLayout(); // 最右侧显示归算参考通道 字号小一号 layoutChannelLeft->setSpacing(0); + layoutChannelMain->setSpacing(0); layoutChannelRight->setSpacing(0); // 设备标题的Label @@ -330,55 +354,76 @@ // 设备参考通道的Label QLabel * labDevRef = new QLabel(widgetDev); labDevRef->setProperty("labType", QString("devRef%1").arg(count)); // 样式表属性 - labDevRef->setText(QString("REF: %1").arg("1000")); + labDevRef->setText(QString("REF: %1").arg("10000")); labDevRef->setAlignment(Qt::AlignCenter); // 文字居中显示 devRefList.append(labDevRef); + // 设置归算使用的参考通道Label + QLabel * labCompDevRef = new QLabel(widgetDev); + labCompDevRef->setProperty("labType", QString("devCompRef%1").arg(count)); // 样式表属性 + labCompDevRef->setText(QString("%1").arg("主备时差")); + labCompDevRef->setAlignment(Qt::AlignCenter); // 文字居中显示 + devCompRefList.append(labCompDevRef); + if (count == 4) { labDevTitle->setMaximumHeight(80); // 设置固定高度 labDevTitle->setMinimumHeight(80); labDevRef->setMaximumHeight(80); // 设置固定高度 labDevRef->setMinimumHeight(80); + + labCompDevRef->setMaximumHeight(80); // 设置固定高度 + labCompDevRef->setMinimumHeight(80); } else { labDevTitle->setMaximumHeight(60); // 设置固定高度 labDevTitle->setMinimumHeight(60); labDevRef->setMaximumHeight(60); // 设置固定高度 labDevRef->setMinimumHeight(60); + + labCompDevRef->setMaximumHeight(60); // 设置固定高度 + labCompDevRef->setMinimumHeight(60); } // 左侧显示设备简称,右侧显示参考通道名 layoutChannelLeft->addWidget(labDevTitle); - layoutChannelRight->addWidget(labDevRef); + layoutChannelMain->addWidget(labDevRef); + layoutChannelRight->addWidget(labCompDevRef); // 每个计数器显示16个通道 for ( int i = 0; i < 16; i++ ) { QLabelDblClick * labChannelName = new QLabelDblClick(widgetDev); // 通道名 QLabelDblClick * labChannelValue = new QLabelDblClick(widgetDev); // 通道测量值 + QLabelDblClick * labComputeValue = new QLabelDblClick(widgetDev); // 通道归算值 // 默认显示内容 - labChannelName->setText(QString("CH%1").arg(i+1, 2, 10, QLatin1Char('0'))); + labChannelName->setText(QString("%1: 10000").arg(i+1, 2, 10, QLatin1Char('0'))); labChannelValue->setText("0.000000000000"); + labComputeValue->setText(""); // css不支持的样式用代码实现 - labChannelName->setMargin(10); - labChannelValue->setMargin(10); + labChannelName->setMargin(5); + labChannelValue->setMargin(5); labChannelValue->setAlignment(Qt::AlignRight | Qt::AlignVCenter); + labComputeValue->setMargin(5); + labComputeValue->setAlignment(Qt::AlignRight | Qt::AlignVCenter); // 奇偶显示不同的背景色 if (i % 2 == 0) { labChannelName->setProperty("labType", QString("channelNameEven%1").arg(count)); labChannelValue->setProperty("labType", QString("channelValueEven%1").arg(count)); + labComputeValue->setProperty("labType", QString("computeValueEven%1").arg(count)); } else { labChannelName->setProperty("labType", QString("channelNameOdd%1").arg(count)); labChannelValue->setProperty("labType", QString("channelValueOdd%1").arg(count)); + labComputeValue->setProperty("labType", QString("computeValueOdd%1").arg(count)); } layoutChannelLeft->addWidget(labChannelName); - layoutChannelRight->addWidget(labChannelValue); + layoutChannelMain->addWidget(labChannelValue); + layoutChannelRight->addWidget(labComputeValue); // 添加通道名称的双击事件,显示数据和残差图表 connect(labChannelName, &QLabelDblClick::doubleClicked, this, &CounterWindowRT::onChannelNameLabelDblClicked); @@ -386,16 +431,21 @@ channelNameList.append(labChannelName); channelValueList.append(labChannelValue); + computeValueList.append(labComputeValue); // 左下角和右下角的圆角处理 if (i == 15) { labChannelName->setStyleSheet("border-bottom-left-radius: 10px;"); - labChannelValue->setStyleSheet("border-bottom-right-radius: 10px;"); + labComputeValue->setStyleSheet("border-bottom-right-radius: 10px;"); } } layoutChannelPage->addLayout(layoutChannelLeft); + layoutChannelPage->addLayout(layoutChannelMain); layoutChannelPage->addLayout(layoutChannelRight); + layoutChannelPage->setStretch(0, 35); + layoutChannelPage->setStretch(1, 50); + layoutChannelPage->setStretch(2, 15); widgetDev->setLayout(layoutChannelPage); } } @@ -407,13 +457,19 @@ // 参考通道号 int refChNo = messageArray.at(0).toObject().value("data").toObject().value("channelRefNo").toInt(); + CounterDevice * counter = ConstCache::getInstance().deviceMap.value(deviceId); + if (counter == nullptr) { + return; + } + counter->setRefChannelNo(refChNo); + // 根据设备id 从map中取出列索引的值 - int devIdx = ConstCache::getInstance().deviceMap.value(deviceId)->getFormColIndex(); + int devIdx = counter->getFormColIndex(); if (devIdx < devRefList.size()) { // 参考通道的显示 QString refText = devRefList.at(devIdx)->text(); - channelNameList.at(devIdx * 16 + refChNo - 1)->setText(QString("CH%1:%2").arg(refChNo, 2, 10, QLatin1Char('0')).arg(refText.right(refText.length() - 4))); + channelNameList.at(devIdx * 16 + refChNo - 1)->setText(QString("%1:%2").arg(refChNo, 2, 10, QLatin1Char('0')).arg(refText.right(refText.length() - 4))); if (alarmDev.contains(deviceId) == true) { @@ -433,11 +489,11 @@ for (int i = 0; i < messageArray.size(); i++) { QJsonObject channelDataItem = messageArray.at(i).toObject(); - QString channelNo = QString::number(channelDataItem.value("channelNo").toInt()); // 通道序号 + QString channelNo = QString("%1").arg(channelDataItem.value("channelNo").toInt(), 2, 10, QLatin1Char('0')); // 通道序号 channelDataJsonMap.insert(channelNo, channelDataItem); } - CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo)); + CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo, 2, 10, QLatin1Char('0'))); double refDelay = 0.0; if (refChanPtr != nullptr && refChanPtr->getDelays().isEmpty() == false) { refDelay = refChanPtr->getDelays().toDouble(); @@ -454,11 +510,10 @@ continue; } - CounterChannel * channel = ConstCache::getInstance().channelMap.value(deviceId + "-" + channelNo); // 从map中找到对应的通道 - - if (channelDataJsonMap.contains(channelNo) == true) + CounterChannel * channel = ConstCache::getInstance().channelMap.value(deviceId + "-" + channelNoStr); // 从map中找到对应的通道 + if (channelDataJsonMap.contains(channelNoStr) == true) { - QJsonObject channelDataItem = channelDataJsonMap.value(channelNo); + QJsonObject channelDataItem = channelDataJsonMap.value(channelNoStr); // 通道Label的序号 int channelIdx = devIdx * 16 + channelDataItem.value("channelNo").toInt() - 1; @@ -483,19 +538,20 @@ double valueMinusDelay = channelDataItem.value("data").toObject().value("dataValue").toString().toDouble() - delay * 1E-9 + refDelay * 1E-9; // 设置通道名和测量值的QLabel - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); channelValueList.at(channelIdx)->setText(QString::number(valueMinusDelay, 'f', 12)); channelNameList.at(channelIdx)->setProperty("channelId", channel->getChannelId()); channelNameList.at(channelIdx)->setProperty("deviceId", deviceId); - channelNameList.at(channelIdx)->setProperty("channelNo", channelNo); + channelNameList.at(channelIdx)->setProperty("channelNo", channelNoStr); channelValueList.at(channelIdx)->setProperty("channelId", channel->getChannelId()); channelValueList.at(channelIdx)->setProperty("deviceId", deviceId); - channelValueList.at(channelIdx)->setProperty("channelNo", channelNo); + channelValueList.at(channelIdx)->setProperty("channelNo", channelNoStr); } else { - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg("-")); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg("-")); channelValueList.at(channelIdx)->setText(""); + computeValueList.at(channelIdx)->setText(""); } } else { // 计数器返回的无测量值的通道处理逻辑 @@ -503,6 +559,7 @@ // 没有测量值的通道清空 channelValueList.at(channelIdx)->setText(""); + computeValueList.at(channelIdx)->setText(""); // 当通道启用时显示通道离线 不再判断后台传回来的状态 // 当通道未启用时显示正常状态 @@ -510,12 +567,12 @@ channelNameList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value("channelOffline")); channelValueList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value("channelOffline")); - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); } else { channelNameList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value(channelNameList.at(channelIdx)->property("labType").toString())); channelValueList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value(channelValueList.at(channelIdx)->property("labType").toString())); - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg("-")); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg("-")); } } } @@ -523,7 +580,7 @@ void CounterWindowRT::updateDeviceAlarm(QJsonArray alarmList) { - qDebug() << alarmList; +// qDebug() << alarmList; for (int i = 0; i < alarmList.size(); i++) { QJsonObject alarmData = alarmList.at(i).toObject(); @@ -532,7 +589,7 @@ QString alarmCode = alarmData.value("alarmCode").toString(); QString status = alarmData.value("status").toString(); - qDebug() << alarmCode << deviceId << channelId; +// qDebug() << alarmCode << deviceId << channelId; // 如果报警状态不是正在报警 status==0 或者报警设备不是计数器 则不处理 if (status != "0" || ConstCache::getInstance().deviceMap.contains(deviceId) == false) @@ -560,6 +617,92 @@ } } +void CounterWindowRT::findRefAndMeasureChannel() +{ + // 查询主路的参考通道的钟编号 + QString masterKey = QString("%1-%2").arg(ConstCache::getInstance().deviceIdLoopA.at(0)).arg("01"); // 暂时固定为01通道 + CounterChannel * refChannelMaster = ConstCache::getInstance().channelMap.value(masterKey); // 主路参考的钟编号 + + // 查询主路参考通道在备路的测量通道 + for (QString channelKey : ConstCache::getInstance().channelMap.keys()) { + QString deviceId = channelKey.split("-")[0]; + if (ConstCache::getInstance().deviceIdLoopB.contains(deviceId)) { + CounterChannel * channel = ConstCache::getInstance().channelMap.value(channelKey); + if (channel->getChannelCode() == refChannelMaster->getChannelCode()) { + QStringList masterInfo; + masterInfo << refChannelMaster->getChannelCode() << deviceId << channel->getChannelId() << channel->getChannelNo(); + ConstCache::getInstance().loopInfos.append(masterInfo); + + break; + } + } + } + + // 查询备路的参考通道钟编号 + QString slaveKey = QString("%1-%2").arg(ConstCache::getInstance().deviceIdLoopB.at(0)).arg("01"); // 暂时固定为01通道 + CounterChannel * refChannelSlave = ConstCache::getInstance().channelMap.value(slaveKey); // 备路参考的钟编号 + + // 查询备路参考通道在主路的测量通道 + for (QString channelKey : ConstCache::getInstance().channelMap.keys()) { + QString deviceId = channelKey.split("-")[0]; + if (ConstCache::getInstance().deviceIdLoopA.contains(deviceId)) { + CounterChannel * channel = ConstCache::getInstance().channelMap.value(channelKey); + if (channel->getChannelCode() == refChannelSlave->getChannelCode()) { + QStringList slaveInfo; + slaveInfo << refChannelSlave->getChannelCode() << deviceId << channel->getChannelId() << channel->getChannelNo(); + ConstCache::getInstance().loopInfos.append(slaveInfo); + + break; + } + } + } + +// qDebug() << ConstCache::getInstance().loopInfos.at(0); +// qDebug() << ConstCache::getInstance().loopInfos.at(1); +// qDebug() << ConstCache::getInstance().channelMap; +} + +double CounterWindowRT::calculateAvgStandbyTimeDiff(QList thisChannel, + QList refChannel, + QList standbyChannel) +{ + double avgTimeDiff = 0.0; + + if (thisChannel.isEmpty() || refChannel.isEmpty() || standbyChannel.isEmpty()) { + return avgTimeDiff; + } + + double sumThis = 0.0; + double avgThis = 0.0; + int countThis = 0; + for (QStringList thisData : thisChannel) { + sumThis += thisData.at(1).toDouble(); + countThis++; + } + avgThis = sumThis / countThis * 1.0; + + double sumRef = 0.0; + double avgRef = 0.0; + int countRef = 0; + for (QStringList refData : refChannel) { + sumRef += refData.at(1).toDouble(); + countRef++; + } + avgRef = sumRef / countRef * 1.0; + + double sumStandby = 0.0; + double avgStandby = 0.0; + int countStandby = 0; + for (QStringList standbyData : standbyChannel) { + sumStandby += standbyData.at(1).toDouble(); + countStandby++; + } + avgStandby = sumStandby / countStandby * 1.0; + + avgTimeDiff = avgThis - avgRef - avgStandby; + return avgTimeDiff; +} + void CounterWindowRT::updateDateAndTime() { QString date = QDate::currentDate().toString("yyyy-MM-dd"); @@ -567,6 +710,171 @@ ui->labTime->setText(date + " " + time); } +void CounterWindowRT::watchStandbyConsistency() +{ + quint8 second = QTime::currentTime().second(); + if (second % SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND == 0) { + qDebug() << "watchStandbyConsistency: " << QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"); + // 1. 遍历所有的主路计数器 + for (QString devAId : ConstCache::getInstance().deviceIdLoopA) { + // 2. 遍历主路计数器的每一个通道(除参考通道外) + for (QString key : ConstCache::getInstance().channelMap.keys()) { + if (key.contains(devAId) == false) { + continue; + } else { + // A当前通道 + CounterChannel * channel = ConstCache::getInstance().channelMap.value(key); + QString channelCode = channel->getChannelCode(); // 钟编号 + QString channelNo = channel->getChannelNo(); // 通道号 + + if (channelNo == "00" || channelNo == "01" || channelCode.isEmpty()) { + continue; + } + + // B备路参考通道在主路的测量通道 + CounterChannel * standbyRefChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(ConstCache::getInstance().loopInfos.at(1).at(1)).arg(ConstCache::getInstance().loopInfos.at(1).at(3))); + + // 3. 获得通道的钟编号、通道号,找到对应钟编号、通道号在备路对应的通道 + // C对应的备路测量通道 + QString standbyKey = ""; + CounterChannel * standbyChannel = nullptr; + if (ConstCache::getInstance().standbyMap.contains(key) == false) { + // 在对路计数器中找 并存入standbyMap + for (QString standbyDevId : ConstCache::getInstance().deviceIdLoopB) { + // 通道号和钟编号都匹配 + standbyChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(standbyDevId).arg(channelNo)); + if (standbyChannel != nullptr && standbyChannel->getChannelCode() == channelCode) { + standbyKey = QString("%1-%2").arg(standbyDevId).arg(channelNo); + ConstCache::getInstance().standbyMap.insert(key, standbyKey); + } + } + } else { + standbyKey = ConstCache::getInstance().standbyMap.value(key); + standbyChannel = ConstCache::getInstance().channelMap.value(standbyKey); + } + + // 4. 取当前通道的最后10个历史数据 channel + QList thisChannelDataList; + if (channel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + thisChannelDataList = channel->getHisData().mid(channel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 5. 取备路参考通道最后10个历史数据 standbyRefChannel + QList standbyRefChannelDataList; + if (standbyRefChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyRefChannelDataList = standbyRefChannel->getHisData().mid(standbyRefChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 6. 取备路计数器对应通道的最后10个历史数据 standbyChannel + QList standbyChannelDataList; + if (standbyChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyChannelDataList = standbyChannel->getHisData().mid(standbyChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 7. 计算当前通道相对备路参考钟的时差 与备路对应通道的时差做差 + if (thisChannelDataList.isEmpty() || standbyChannelDataList.isEmpty()) { + continue; + } + double avgTimeDiff = calculateAvgStandbyTimeDiff(thisChannelDataList, standbyRefChannelDataList, standbyChannelDataList); + + // 8. 显示在界面上 + CounterDevice * devicePtr = ConstCache::getInstance().deviceMap.value(devAId); + if (devicePtr != nullptr && SettingConfig::getInstance().MASTER == devicePtr->getIsUse()) + { + int devIdx = devicePtr->getFormColIndex(); + + // 通道Label的序号 + int channelIdx = devIdx * 16 + channelNo.toInt() - 1; + computeValueList.at(channelIdx)->setText(QString::number(avgTimeDiff * 1E9, 'f', 3)); + } + } + } + } + + // 8. 遍历所有的备路计数器 + for (QString devBId : ConstCache::getInstance().deviceIdLoopB) { + // 2. 遍历主路计数器的每一个通道(除参考通道外) + for (QString key : ConstCache::getInstance().channelMap.keys()) { + if (key.contains(devBId) == false) { + continue; + } else { + // A当前通道 + CounterChannel * channel = ConstCache::getInstance().channelMap.value(key); + QString channelCode = channel->getChannelCode(); // 钟编号 + QString channelNo = channel->getChannelNo(); // 通道号 + + if (channelNo == "00" || channelNo == "01" || channelCode.isEmpty()) { + continue; + } + + // B主路参考通道在主路的测量通道 + CounterChannel * standbyRefChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(ConstCache::getInstance().loopInfos.at(0).at(1)).arg(ConstCache::getInstance().loopInfos.at(0).at(3))); + + // 3. 获得通道的钟编号、通道号,找到对应钟编号、通道号在备路对应的通道 + // C对应的主路测量通道 + QString standbyKey = ""; + CounterChannel * standbyChannel = nullptr; + if (ConstCache::getInstance().standbyMap.contains(key) == false) { + // 在对路计数器中找 并存入standbyMap + for (QString standbyDevId : ConstCache::getInstance().deviceIdLoopA) { + // 通道号和钟编号都匹配 + standbyChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(standbyDevId).arg(channelNo)); + if (standbyChannel != nullptr && standbyChannel->getChannelCode() == channelCode) { + standbyKey = QString("%1-%2").arg(standbyDevId).arg(channelNo); + ConstCache::getInstance().standbyMap.insert(key, standbyKey); + } + } + } else { + standbyKey = ConstCache::getInstance().standbyMap.value(key); + standbyChannel = ConstCache::getInstance().channelMap.value(standbyKey); + } + + // 4. 取当前通道的最后10个历史数据 channel + QList thisChannelDataList; + if (channel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + thisChannelDataList = channel->getHisData().mid(channel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 5. 取主路参考通道最后10个历史数据 standbyRefChannel + QList standbyRefChannelDataList; + if (standbyRefChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyRefChannelDataList = standbyRefChannel->getHisData().mid(standbyRefChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 6. 取主路计数器对应通道的最后10个历史数据 standbyChannel + QList standbyChannelDataList; + if (standbyChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyChannelDataList = standbyChannel->getHisData().mid(standbyChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 7. 计算当前通道相对主路参考钟的时差 与主路对应通道的时差做差 + if (thisChannelDataList.isEmpty() || standbyChannelDataList.isEmpty()) { + continue; + } + double avgTimeDiff = calculateAvgStandbyTimeDiff(thisChannelDataList, standbyRefChannelDataList, standbyChannelDataList); + + // 8. 显示在界面上 + CounterDevice * devicePtr = ConstCache::getInstance().deviceMap.value(devBId); + if (devicePtr != nullptr && SettingConfig::getInstance().MASTER == devicePtr->getIsUse()) + { + int devIdx = devicePtr->getFormColIndex(); + + // 通道Label的序号 + int channelIdx = devIdx * 16 + channelNo.toInt() - 1; + computeValueList.at(channelIdx)->setText(QString::number(avgTimeDiff * 1E9, 'f', 3)); + } + } + } + } + } +} + void CounterWindowRT::on_btnMenuSetting_clicked() { settingForm->setWindowModality(Qt::ApplicationModal); @@ -600,8 +908,10 @@ // 将lab列表的数量置0 devTitleList.resize(0); devRefList.resize(0); + devCompRefList.resize(0); channelNameList.resize(0); channelValueList.resize(0); + computeValueList.resize(0); initDevAndChannelForm(SettingConfig::getInstance().DISPLAY_COUNT); } @@ -620,14 +930,20 @@ devTitleList.at(i)->setText(dev->getDeviceName()); // 设备名称 dev->setFormColIndex(i); } + for (int j = 1; j < 16; j++) + { + computeValueList.at(i * 16 + j)->setText("-"); + } } else { devTitleList.at(i)->setText(""); devRefList.at(i)->setText(""); + devCompRefList.at(i)->setText(""); for (int j = 0; j < 16; j++) { channelNameList.at(i * 16 + j)->setText(""); channelValueList.at(i * 16 + j)->setText(""); + computeValueList.at(i * 16 + j)->setText(""); } } } @@ -685,7 +1001,7 @@ // 参考通道 int refChNo = messageArray.at(0).toObject().value("data").toObject().value("channelRefNo").toInt(); - CounterChannel * refChann = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo)); + CounterChannel * refChann = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo, 2, 10, QLatin1Char('0'))); if (refChann != nullptr) { if (devIdx < devRefList.size()) { @@ -704,7 +1020,7 @@ void CounterWindowRT::onKafkaMessageReceived(QJsonObject message) { qDebug() << message; - std::cout << QString(QJsonDocument(message).toJson(QJsonDocument::Compact)).toStdString() << std::endl; + std::cout << "kafka message received: " << std::endl << QString(QJsonDocument(message).toJson(QJsonDocument::Compact)).toStdString() << std::endl; // 找不到deviceId deviceType operation三个必填项 直接返回 if (message.contains("deviceId") == false || message.contains("operation") == false || message.contains("deviceType") == false) { @@ -732,7 +1048,7 @@ void CounterWindowRT::onAlarmMessageReceived(QJsonObject alarmMsg) { qDebug() << alarmMsg; - std::cout << QString(QJsonDocument(alarmMsg).toJson(QJsonDocument::Compact)).toStdString() << std::endl; + std::cout << "alarm message received: " << std::endl << QString(QJsonDocument(alarmMsg).toJson(QJsonDocument::Compact)).toStdString() << std::endl; QString deviceId = alarmMsg.value("deviceId").toString(); QString channelId = alarmMsg.value("channelId").toString(); diff --git a/CounterRealTime/CounterWindowRT.h b/CounterRealTime/CounterWindowRT.h index b672cfc..b4eea96 100644 --- a/CounterRealTime/CounterWindowRT.h +++ b/CounterRealTime/CounterWindowRT.h @@ -17,10 +17,13 @@ #include "CounterSettingForm.h" #include "common/utils/SettingConfig.h" #include "common/utils/TimerCounterUtil.h" -#include "common/utils/QKafkaConsumer.h" #include "common/HttpRequestController.h" #include "common/HttpServer.h" +#ifdef unix +#include "common/utils/QKafkaConsumer.h" +#endif + QT_BEGIN_NAMESPACE namespace Ui { class CounterWindowRT; } QT_END_NAMESPACE @@ -47,12 +50,17 @@ QVector devTitleList; // 计数器设备标题的QLabel集合 QVector devRefList; // Ref通道 + QVector devCompRefList; // 归算Ref通道 QVector channelNameList; // 通道名的QLabel集合 QVector channelValueList; // 通道测量值的QLabel集合 + QVector computeValueList; // 通道归算值的QLabel集合 HttpRequestController * httpReq; + +#ifdef unix QKafkaConsumer * kafkaConsumer; QKafkaConsumer * alarmMsgConsumer; +#endif QVector alarmDev; QVector offlineDev; @@ -67,9 +75,13 @@ void initDevAndChannelForm(int count); void updateChannelDataForm(QJsonArray messageArray); void updateDeviceAlarm(QJsonArray alarmList); + void findRefAndMeasureChannel(); // 查找主备路的测量参考通道以及各自的测量通道 + double calculateAvgStandbyTimeDiff(QList thisChannel, QList refChannel, QList standbyChannel); + private slots: void updateDateAndTime(); + void watchStandbyConsistency(); int initHttpToken(); diff --git a/CounterRealTime/common/ConstCache.h b/CounterRealTime/common/ConstCache.h index 25a97d4..c5af508 100644 --- a/CounterRealTime/common/ConstCache.h +++ b/CounterRealTime/common/ConstCache.h @@ -31,6 +31,9 @@ QList deviceIdLoopB; // B路计数器对象集合 key=deviceId QMap channelMap; // 通道对象集合 key=deviceId-channelNo + QList loopInfos; // 存储主备路关键信息 参考钟编号;在对路的测量计数器ID;在对路的测量计数器所在通道ID;对路计数器所在的通道号 + QMap standbyMap; // 主路/备路通道的备路/主路对应通道key key=deviceId-channelNo value=deviceId-channelNo + QMap alarmDeviceMap; // 报警设备 QMap alarmChannelMap; // 报警通道 diff --git a/CounterRealTime/common/HttpRequestController.cpp b/CounterRealTime/common/HttpRequestController.cpp index 58ac632..0b8a3e4 100644 --- a/CounterRealTime/common/HttpRequestController.cpp +++ b/CounterRealTime/common/HttpRequestController.cpp @@ -130,7 +130,7 @@ } delete reply; - qDebug() << resultObj; +// qDebug() << resultObj; return resultObj; } @@ -239,7 +239,7 @@ } delete reply; - qDebug() << resultObj; +// qDebug() << "alarm List: " << resultObj; return resultObj; } diff --git a/CounterRealTime/common/common.pri b/CounterRealTime/common/common.pri index aa3f245..9d51c30 100644 --- a/CounterRealTime/common/common.pri +++ b/CounterRealTime/common/common.pri @@ -1,10 +1,7 @@ - SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp -SOURCES += $$PWD/utils/QKafkaUtil.cpp -SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/LinearRegression.cpp @@ -16,8 +13,6 @@ HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h -HEADERS += $$PWD/utils/QKafkaUtil.h -HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h @@ -25,3 +20,11 @@ HEADERS += $$PWD/HttpRequestController.h HEADERS += $$PWD/HttpServer.h HEADERS += $$PWD/ConstCache.h + +unix { + SOURCES += $$PWD/utils/QKafkaUtil.cpp + SOURCES += $$PWD/utils/QKafkaConsumer.cpp + + HEADERS += $$PWD/utils/QKafkaUtil.h + HEADERS += $$PWD/utils/QKafkaConsumer.h +} diff --git a/CounterRealTime/common/utils/SettingConfig.cpp b/CounterRealTime/common/utils/SettingConfig.cpp index b6c72d7..f94a918 100644 --- a/CounterRealTime/common/utils/SettingConfig.cpp +++ b/CounterRealTime/common/utils/SettingConfig.cpp @@ -51,6 +51,7 @@ PASSWORD = getProperty("client", "password").toString(); SERVER_PORT = getProperty("client", "serverPort").toInt(); CLIENT_TITLE = getProperty("client", "title").toString(); + STANDBY_CONSISTENCY_SECOND = getProperty("client", "standbyConsistencySecond").toUInt(); DEVICE_ALARM_CODES = getProperty("alarm", "deviceAlarmCodes").toString().split(","); CHANNEL_ALARM_CODES = getProperty("alarm", "channelAlarmCodes").toString().split(","); diff --git a/CounterRealTime/CounterDevice.cpp b/CounterRealTime/CounterDevice.cpp index 4ff6565..f656746 100644 --- a/CounterRealTime/CounterDevice.cpp +++ b/CounterRealTime/CounterDevice.cpp @@ -9,11 +9,13 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &CounterDevice::dataReceivedHandler); +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); kafkaUtil.createProducer(); } +#endif } CounterDevice::~CounterDevice() @@ -78,6 +80,15 @@ this->refChannelCode = refChannelCode; } +int CounterDevice::getRefChannelNo() +{ + return this->refChannelNo; +} +void CounterDevice::setRefChannelNo(int refChannelNo) +{ + this->refChannelNo = refChannelNo; +} + bool CounterDevice::isSerialOpen() { return this->serialUtil.isOpen(); @@ -156,7 +167,7 @@ msgLogFilename = msgLogFilename.arg((hour / 6) * 6, 2, 10, QLatin1Char('0')); msgLogFilename = msgLogFilename.arg((hour / 6) * 6 + 5, 2, 10, QLatin1Char('0')); - CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(counterData->channelRefId)); + CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(counterData->channelRefId, 2, 10, QLatin1Char('0'))); this->refChannelNo = counterData->channelRefId; double refDelay = 0.0; if (refChanPtr != nullptr && refChanPtr->getDelays().isEmpty() == false) { @@ -186,7 +197,7 @@ } // 加到hisDataList中 用于绘制图表 - CounterChannel * channelPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i)); + CounterChannel * channelPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i, 2, 10, QLatin1Char('0'))); if (channelPtr != nullptr && channelPtr->isActive() == true) { // 通道时延值 并计算 减去时延值的测量值 @@ -210,6 +221,7 @@ statusObj.insert("master", SettingConfig::getInstance().MASTER); statusObj.insert("deviceId", deviceId); +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { if (SettingConfig::getInstance().MASTER == 0) @@ -227,6 +239,7 @@ kafkaUtil.produceMessage(SettingConfig::getInstance().KAFKA_STATUS_TOPIC, QString(QJsonDocument(statusObj).toJson(QJsonDocument::Compact))); } } +#endif QLogUtil::writeMessageLogByDate(date, msgLogFilename, QString(QJsonDocument(messageArray).toJson(QJsonDocument::Compact))); diff --git a/CounterRealTime/CounterDevice.h b/CounterRealTime/CounterDevice.h index c4d003d..68390c8 100644 --- a/CounterRealTime/CounterDevice.h +++ b/CounterRealTime/CounterDevice.h @@ -6,7 +6,6 @@ #include "CounterChannel.h" #include "common/utils/QSerialPortUtil.h" -#include "common/utils/QKafkaUtil.h" #include "common/utils/QByteUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" @@ -14,6 +13,10 @@ #include "common/LinearRegression.h" #include "protocol/CounterProtocolXH.h" +#ifdef unix +#include "common/utils/QKafkaUtil.h" +#endif + class CounterDevice : public QObject { Q_OBJECT @@ -37,6 +40,9 @@ int getIsUse(); void setIsUse(int isUse); + int getRefChannelNo(); + void setRefChannelNo(int refChannelNo); + QString getRefChannelCode(); void setRefChannelCode(QString refChannelCode); @@ -56,9 +62,12 @@ int formColIndex; QSerialPortUtil serialUtil; - QKafkaUtil kafkaUtil; QByteArray dataBuff; +#ifdef unix + QKafkaUtil kafkaUtil; +#endif + void afterFramePhase(CounterDataDto * counterData); void calcResidualClockData(qlonglong tm); diff --git a/CounterRealTime/CounterRealTime.pro b/CounterRealTime/CounterRealTime.pro index c323f04..f990ff3 100644 --- a/CounterRealTime/CounterRealTime.pro +++ b/CounterRealTime/CounterRealTime.pro @@ -49,7 +49,8 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka++ -lrdkafka +win32: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka++ -lrdkafka INCLUDEPATH += $$PWD/include/librdkafka DEPENDPATH += $$PWD/include/librdkafka diff --git a/CounterRealTime/CounterSettingForm.cpp b/CounterRealTime/CounterSettingForm.cpp index c1945d1..bc43ac7 100644 --- a/CounterRealTime/CounterSettingForm.cpp +++ b/CounterRealTime/CounterSettingForm.cpp @@ -335,7 +335,7 @@ active = activeListRight.at(i - 8)->isChecked(); } - CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1)); + CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1, 2, 10, QLatin1Char('0'))); if (channelPrt != nullptr) { bool isUpdated = isChannelSettingUpdated(i, channelPrt); @@ -362,7 +362,7 @@ newChannel->setChannelCode(channelCode); newChannel->setDelays(QString::number(delay)); - ConstCache::getInstance().channelMap.insert(QString("%1-%2").arg(deviceId).arg(i+1), newChannel); + ConstCache::getInstance().channelMap.insert(QString("%1-%2").arg(deviceId).arg(i+1, 2, 10, QLatin1Char('0')), newChannel); QJsonObject channelObj; channelObj.insert("id", ""); @@ -412,7 +412,7 @@ activeListLeft.at(i)->setCheckable(true); activeListRight.at(i)->setCheckable(true); - CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1)); + CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1, 2, 10, QLatin1Char('0'))); if (channelPrt != nullptr) { QString channelCode = channelPrt->getChannelCode(); // 通道钟号 @@ -429,7 +429,7 @@ } } - CounterChannel * channelRightPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1+8)); + CounterChannel * channelRightPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1+8, 2, 10, QLatin1Char('0'))); if (channelRightPrt != nullptr) { QString channelCode = channelRightPrt->getChannelCode(); // 通道钟号 diff --git a/CounterRealTime/CounterWindowRT.cpp b/CounterRealTime/CounterWindowRT.cpp index 30adf9b..78815d7 100644 --- a/CounterRealTime/CounterWindowRT.cpp +++ b/CounterRealTime/CounterWindowRT.cpp @@ -76,6 +76,7 @@ file.close(); } +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { // kafka consumer kafkaConsumer = new QKafkaConsumer(this); @@ -93,6 +94,7 @@ alarmMsgConsumer->start(); connect(alarmMsgConsumer, &QKafkaConsumer::messageRecieved, this, &CounterWindowRT::onAlarmMessageReceived); } +#endif // 绘制界面上的表格 initChannelForm(); @@ -100,6 +102,10 @@ // 显示时钟 每秒更新 connect(TimerCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &CounterWindowRT::updateDateAndTime); TimerCounterUtil::getInstance().clockCounter->start(1000); + QTimer::singleShot(30000, [=](){ + // 定时执行主备一致性监测 + connect(TimerCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &CounterWindowRT::watchStandbyConsistency); + }); // 重新选择显示多少个计数器 connect(settingForm, &CounterSettingForm::swiftDisplayLoop, this, &CounterWindowRT::updateDeviceWidget); @@ -182,7 +188,7 @@ } for (int i = 0; i < devSet.size(); i++) { - getChannelList(devSet.toList().at(i)); + getChannelList(devSet.values().at(i)); } } } @@ -233,6 +239,13 @@ } updateDeviceWidget(); + +// qDebug() << "loop A: " << ConstCache::getInstance().deviceIdLoopA; +// qDebug() << "loop B: " << ConstCache::getInstance().deviceIdLoopB; + + // 查找主路参考钟在备路计数器的测量通道 + // 查找备路参考钟在主路计数器的测量通道 + findRefAndMeasureChannel(); } } QList CounterWindowRT::getClockNumList() @@ -262,7 +275,8 @@ { // for (int i = 0; i <= 16; i++) { - ConstCache::getInstance().channelMap.remove(QString("%1-%2").arg(deviceId).arg(i)); + QString channelKey = QString("%1-%2").arg(deviceId).arg(i); + ConstCache::getInstance().channelMap.remove(channelKey); } // 将通道绘制在界面上 @@ -273,7 +287,7 @@ QJsonObject channelItem = channelArray.at(i).toObject(); QString channelId = channelItem.value("id").toString(); // 通道ID QString channelCode = channelItem.value("channelCode").toString(); // 通道钟号 - QString channelNo = QString::number(channelItem.value("channelNo").toInt()); // 通道序号 + QString channelNo = QString("%1").arg(channelItem.value("channelNo").toInt(), 2, 10, QLatin1Char('0')); // 通道序号 QString delays = channelItem.value("delays").toString(); // 通道时延值 QString isUse = channelItem.value("isUse").toString(); QString name = channelItem.value("name").toString(); @@ -292,6 +306,14 @@ // 添加到通道的集合中 key=deviceId-channelNo ConstCache::getInstance().channelMap.insert(deviceId + "-" + channelNo, channel); + + if (channelCode.isEmpty() == false && active == true) { + CounterDevice * counterDev = ConstCache::getInstance().deviceMap.value(deviceId); + if (counterDev != nullptr) { + QStringList channelBase; + channelBase << QString::number(counterDev->getIsUse()) << channelCode; + } + } } } } @@ -314,10 +336,12 @@ layoutChannelPage->setMargin(3); // 留出边框的位置 // 左右布局中是垂直布局,用于显示通道 - QVBoxLayout * layoutChannelLeft = new QVBoxLayout(); - QVBoxLayout * layoutChannelRight = new QVBoxLayout(); + QVBoxLayout * layoutChannelLeft = new QVBoxLayout(); // 最左侧显示设备简称 + QVBoxLayout * layoutChannelMain = new QVBoxLayout(); // 中间显示参考通道 + QVBoxLayout * layoutChannelRight = new QVBoxLayout(); // 最右侧显示归算参考通道 字号小一号 layoutChannelLeft->setSpacing(0); + layoutChannelMain->setSpacing(0); layoutChannelRight->setSpacing(0); // 设备标题的Label @@ -330,55 +354,76 @@ // 设备参考通道的Label QLabel * labDevRef = new QLabel(widgetDev); labDevRef->setProperty("labType", QString("devRef%1").arg(count)); // 样式表属性 - labDevRef->setText(QString("REF: %1").arg("1000")); + labDevRef->setText(QString("REF: %1").arg("10000")); labDevRef->setAlignment(Qt::AlignCenter); // 文字居中显示 devRefList.append(labDevRef); + // 设置归算使用的参考通道Label + QLabel * labCompDevRef = new QLabel(widgetDev); + labCompDevRef->setProperty("labType", QString("devCompRef%1").arg(count)); // 样式表属性 + labCompDevRef->setText(QString("%1").arg("主备时差")); + labCompDevRef->setAlignment(Qt::AlignCenter); // 文字居中显示 + devCompRefList.append(labCompDevRef); + if (count == 4) { labDevTitle->setMaximumHeight(80); // 设置固定高度 labDevTitle->setMinimumHeight(80); labDevRef->setMaximumHeight(80); // 设置固定高度 labDevRef->setMinimumHeight(80); + + labCompDevRef->setMaximumHeight(80); // 设置固定高度 + labCompDevRef->setMinimumHeight(80); } else { labDevTitle->setMaximumHeight(60); // 设置固定高度 labDevTitle->setMinimumHeight(60); labDevRef->setMaximumHeight(60); // 设置固定高度 labDevRef->setMinimumHeight(60); + + labCompDevRef->setMaximumHeight(60); // 设置固定高度 + labCompDevRef->setMinimumHeight(60); } // 左侧显示设备简称,右侧显示参考通道名 layoutChannelLeft->addWidget(labDevTitle); - layoutChannelRight->addWidget(labDevRef); + layoutChannelMain->addWidget(labDevRef); + layoutChannelRight->addWidget(labCompDevRef); // 每个计数器显示16个通道 for ( int i = 0; i < 16; i++ ) { QLabelDblClick * labChannelName = new QLabelDblClick(widgetDev); // 通道名 QLabelDblClick * labChannelValue = new QLabelDblClick(widgetDev); // 通道测量值 + QLabelDblClick * labComputeValue = new QLabelDblClick(widgetDev); // 通道归算值 // 默认显示内容 - labChannelName->setText(QString("CH%1").arg(i+1, 2, 10, QLatin1Char('0'))); + labChannelName->setText(QString("%1: 10000").arg(i+1, 2, 10, QLatin1Char('0'))); labChannelValue->setText("0.000000000000"); + labComputeValue->setText(""); // css不支持的样式用代码实现 - labChannelName->setMargin(10); - labChannelValue->setMargin(10); + labChannelName->setMargin(5); + labChannelValue->setMargin(5); labChannelValue->setAlignment(Qt::AlignRight | Qt::AlignVCenter); + labComputeValue->setMargin(5); + labComputeValue->setAlignment(Qt::AlignRight | Qt::AlignVCenter); // 奇偶显示不同的背景色 if (i % 2 == 0) { labChannelName->setProperty("labType", QString("channelNameEven%1").arg(count)); labChannelValue->setProperty("labType", QString("channelValueEven%1").arg(count)); + labComputeValue->setProperty("labType", QString("computeValueEven%1").arg(count)); } else { labChannelName->setProperty("labType", QString("channelNameOdd%1").arg(count)); labChannelValue->setProperty("labType", QString("channelValueOdd%1").arg(count)); + labComputeValue->setProperty("labType", QString("computeValueOdd%1").arg(count)); } layoutChannelLeft->addWidget(labChannelName); - layoutChannelRight->addWidget(labChannelValue); + layoutChannelMain->addWidget(labChannelValue); + layoutChannelRight->addWidget(labComputeValue); // 添加通道名称的双击事件,显示数据和残差图表 connect(labChannelName, &QLabelDblClick::doubleClicked, this, &CounterWindowRT::onChannelNameLabelDblClicked); @@ -386,16 +431,21 @@ channelNameList.append(labChannelName); channelValueList.append(labChannelValue); + computeValueList.append(labComputeValue); // 左下角和右下角的圆角处理 if (i == 15) { labChannelName->setStyleSheet("border-bottom-left-radius: 10px;"); - labChannelValue->setStyleSheet("border-bottom-right-radius: 10px;"); + labComputeValue->setStyleSheet("border-bottom-right-radius: 10px;"); } } layoutChannelPage->addLayout(layoutChannelLeft); + layoutChannelPage->addLayout(layoutChannelMain); layoutChannelPage->addLayout(layoutChannelRight); + layoutChannelPage->setStretch(0, 35); + layoutChannelPage->setStretch(1, 50); + layoutChannelPage->setStretch(2, 15); widgetDev->setLayout(layoutChannelPage); } } @@ -407,13 +457,19 @@ // 参考通道号 int refChNo = messageArray.at(0).toObject().value("data").toObject().value("channelRefNo").toInt(); + CounterDevice * counter = ConstCache::getInstance().deviceMap.value(deviceId); + if (counter == nullptr) { + return; + } + counter->setRefChannelNo(refChNo); + // 根据设备id 从map中取出列索引的值 - int devIdx = ConstCache::getInstance().deviceMap.value(deviceId)->getFormColIndex(); + int devIdx = counter->getFormColIndex(); if (devIdx < devRefList.size()) { // 参考通道的显示 QString refText = devRefList.at(devIdx)->text(); - channelNameList.at(devIdx * 16 + refChNo - 1)->setText(QString("CH%1:%2").arg(refChNo, 2, 10, QLatin1Char('0')).arg(refText.right(refText.length() - 4))); + channelNameList.at(devIdx * 16 + refChNo - 1)->setText(QString("%1:%2").arg(refChNo, 2, 10, QLatin1Char('0')).arg(refText.right(refText.length() - 4))); if (alarmDev.contains(deviceId) == true) { @@ -433,11 +489,11 @@ for (int i = 0; i < messageArray.size(); i++) { QJsonObject channelDataItem = messageArray.at(i).toObject(); - QString channelNo = QString::number(channelDataItem.value("channelNo").toInt()); // 通道序号 + QString channelNo = QString("%1").arg(channelDataItem.value("channelNo").toInt(), 2, 10, QLatin1Char('0')); // 通道序号 channelDataJsonMap.insert(channelNo, channelDataItem); } - CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo)); + CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo, 2, 10, QLatin1Char('0'))); double refDelay = 0.0; if (refChanPtr != nullptr && refChanPtr->getDelays().isEmpty() == false) { refDelay = refChanPtr->getDelays().toDouble(); @@ -454,11 +510,10 @@ continue; } - CounterChannel * channel = ConstCache::getInstance().channelMap.value(deviceId + "-" + channelNo); // 从map中找到对应的通道 - - if (channelDataJsonMap.contains(channelNo) == true) + CounterChannel * channel = ConstCache::getInstance().channelMap.value(deviceId + "-" + channelNoStr); // 从map中找到对应的通道 + if (channelDataJsonMap.contains(channelNoStr) == true) { - QJsonObject channelDataItem = channelDataJsonMap.value(channelNo); + QJsonObject channelDataItem = channelDataJsonMap.value(channelNoStr); // 通道Label的序号 int channelIdx = devIdx * 16 + channelDataItem.value("channelNo").toInt() - 1; @@ -483,19 +538,20 @@ double valueMinusDelay = channelDataItem.value("data").toObject().value("dataValue").toString().toDouble() - delay * 1E-9 + refDelay * 1E-9; // 设置通道名和测量值的QLabel - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); channelValueList.at(channelIdx)->setText(QString::number(valueMinusDelay, 'f', 12)); channelNameList.at(channelIdx)->setProperty("channelId", channel->getChannelId()); channelNameList.at(channelIdx)->setProperty("deviceId", deviceId); - channelNameList.at(channelIdx)->setProperty("channelNo", channelNo); + channelNameList.at(channelIdx)->setProperty("channelNo", channelNoStr); channelValueList.at(channelIdx)->setProperty("channelId", channel->getChannelId()); channelValueList.at(channelIdx)->setProperty("deviceId", deviceId); - channelValueList.at(channelIdx)->setProperty("channelNo", channelNo); + channelValueList.at(channelIdx)->setProperty("channelNo", channelNoStr); } else { - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg("-")); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg("-")); channelValueList.at(channelIdx)->setText(""); + computeValueList.at(channelIdx)->setText(""); } } else { // 计数器返回的无测量值的通道处理逻辑 @@ -503,6 +559,7 @@ // 没有测量值的通道清空 channelValueList.at(channelIdx)->setText(""); + computeValueList.at(channelIdx)->setText(""); // 当通道启用时显示通道离线 不再判断后台传回来的状态 // 当通道未启用时显示正常状态 @@ -510,12 +567,12 @@ channelNameList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value("channelOffline")); channelValueList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value("channelOffline")); - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); } else { channelNameList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value(channelNameList.at(channelIdx)->property("labType").toString())); channelValueList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value(channelValueList.at(channelIdx)->property("labType").toString())); - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg("-")); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg("-")); } } } @@ -523,7 +580,7 @@ void CounterWindowRT::updateDeviceAlarm(QJsonArray alarmList) { - qDebug() << alarmList; +// qDebug() << alarmList; for (int i = 0; i < alarmList.size(); i++) { QJsonObject alarmData = alarmList.at(i).toObject(); @@ -532,7 +589,7 @@ QString alarmCode = alarmData.value("alarmCode").toString(); QString status = alarmData.value("status").toString(); - qDebug() << alarmCode << deviceId << channelId; +// qDebug() << alarmCode << deviceId << channelId; // 如果报警状态不是正在报警 status==0 或者报警设备不是计数器 则不处理 if (status != "0" || ConstCache::getInstance().deviceMap.contains(deviceId) == false) @@ -560,6 +617,92 @@ } } +void CounterWindowRT::findRefAndMeasureChannel() +{ + // 查询主路的参考通道的钟编号 + QString masterKey = QString("%1-%2").arg(ConstCache::getInstance().deviceIdLoopA.at(0)).arg("01"); // 暂时固定为01通道 + CounterChannel * refChannelMaster = ConstCache::getInstance().channelMap.value(masterKey); // 主路参考的钟编号 + + // 查询主路参考通道在备路的测量通道 + for (QString channelKey : ConstCache::getInstance().channelMap.keys()) { + QString deviceId = channelKey.split("-")[0]; + if (ConstCache::getInstance().deviceIdLoopB.contains(deviceId)) { + CounterChannel * channel = ConstCache::getInstance().channelMap.value(channelKey); + if (channel->getChannelCode() == refChannelMaster->getChannelCode()) { + QStringList masterInfo; + masterInfo << refChannelMaster->getChannelCode() << deviceId << channel->getChannelId() << channel->getChannelNo(); + ConstCache::getInstance().loopInfos.append(masterInfo); + + break; + } + } + } + + // 查询备路的参考通道钟编号 + QString slaveKey = QString("%1-%2").arg(ConstCache::getInstance().deviceIdLoopB.at(0)).arg("01"); // 暂时固定为01通道 + CounterChannel * refChannelSlave = ConstCache::getInstance().channelMap.value(slaveKey); // 备路参考的钟编号 + + // 查询备路参考通道在主路的测量通道 + for (QString channelKey : ConstCache::getInstance().channelMap.keys()) { + QString deviceId = channelKey.split("-")[0]; + if (ConstCache::getInstance().deviceIdLoopA.contains(deviceId)) { + CounterChannel * channel = ConstCache::getInstance().channelMap.value(channelKey); + if (channel->getChannelCode() == refChannelSlave->getChannelCode()) { + QStringList slaveInfo; + slaveInfo << refChannelSlave->getChannelCode() << deviceId << channel->getChannelId() << channel->getChannelNo(); + ConstCache::getInstance().loopInfos.append(slaveInfo); + + break; + } + } + } + +// qDebug() << ConstCache::getInstance().loopInfos.at(0); +// qDebug() << ConstCache::getInstance().loopInfos.at(1); +// qDebug() << ConstCache::getInstance().channelMap; +} + +double CounterWindowRT::calculateAvgStandbyTimeDiff(QList thisChannel, + QList refChannel, + QList standbyChannel) +{ + double avgTimeDiff = 0.0; + + if (thisChannel.isEmpty() || refChannel.isEmpty() || standbyChannel.isEmpty()) { + return avgTimeDiff; + } + + double sumThis = 0.0; + double avgThis = 0.0; + int countThis = 0; + for (QStringList thisData : thisChannel) { + sumThis += thisData.at(1).toDouble(); + countThis++; + } + avgThis = sumThis / countThis * 1.0; + + double sumRef = 0.0; + double avgRef = 0.0; + int countRef = 0; + for (QStringList refData : refChannel) { + sumRef += refData.at(1).toDouble(); + countRef++; + } + avgRef = sumRef / countRef * 1.0; + + double sumStandby = 0.0; + double avgStandby = 0.0; + int countStandby = 0; + for (QStringList standbyData : standbyChannel) { + sumStandby += standbyData.at(1).toDouble(); + countStandby++; + } + avgStandby = sumStandby / countStandby * 1.0; + + avgTimeDiff = avgThis - avgRef - avgStandby; + return avgTimeDiff; +} + void CounterWindowRT::updateDateAndTime() { QString date = QDate::currentDate().toString("yyyy-MM-dd"); @@ -567,6 +710,171 @@ ui->labTime->setText(date + " " + time); } +void CounterWindowRT::watchStandbyConsistency() +{ + quint8 second = QTime::currentTime().second(); + if (second % SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND == 0) { + qDebug() << "watchStandbyConsistency: " << QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"); + // 1. 遍历所有的主路计数器 + for (QString devAId : ConstCache::getInstance().deviceIdLoopA) { + // 2. 遍历主路计数器的每一个通道(除参考通道外) + for (QString key : ConstCache::getInstance().channelMap.keys()) { + if (key.contains(devAId) == false) { + continue; + } else { + // A当前通道 + CounterChannel * channel = ConstCache::getInstance().channelMap.value(key); + QString channelCode = channel->getChannelCode(); // 钟编号 + QString channelNo = channel->getChannelNo(); // 通道号 + + if (channelNo == "00" || channelNo == "01" || channelCode.isEmpty()) { + continue; + } + + // B备路参考通道在主路的测量通道 + CounterChannel * standbyRefChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(ConstCache::getInstance().loopInfos.at(1).at(1)).arg(ConstCache::getInstance().loopInfos.at(1).at(3))); + + // 3. 获得通道的钟编号、通道号,找到对应钟编号、通道号在备路对应的通道 + // C对应的备路测量通道 + QString standbyKey = ""; + CounterChannel * standbyChannel = nullptr; + if (ConstCache::getInstance().standbyMap.contains(key) == false) { + // 在对路计数器中找 并存入standbyMap + for (QString standbyDevId : ConstCache::getInstance().deviceIdLoopB) { + // 通道号和钟编号都匹配 + standbyChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(standbyDevId).arg(channelNo)); + if (standbyChannel != nullptr && standbyChannel->getChannelCode() == channelCode) { + standbyKey = QString("%1-%2").arg(standbyDevId).arg(channelNo); + ConstCache::getInstance().standbyMap.insert(key, standbyKey); + } + } + } else { + standbyKey = ConstCache::getInstance().standbyMap.value(key); + standbyChannel = ConstCache::getInstance().channelMap.value(standbyKey); + } + + // 4. 取当前通道的最后10个历史数据 channel + QList thisChannelDataList; + if (channel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + thisChannelDataList = channel->getHisData().mid(channel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 5. 取备路参考通道最后10个历史数据 standbyRefChannel + QList standbyRefChannelDataList; + if (standbyRefChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyRefChannelDataList = standbyRefChannel->getHisData().mid(standbyRefChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 6. 取备路计数器对应通道的最后10个历史数据 standbyChannel + QList standbyChannelDataList; + if (standbyChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyChannelDataList = standbyChannel->getHisData().mid(standbyChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 7. 计算当前通道相对备路参考钟的时差 与备路对应通道的时差做差 + if (thisChannelDataList.isEmpty() || standbyChannelDataList.isEmpty()) { + continue; + } + double avgTimeDiff = calculateAvgStandbyTimeDiff(thisChannelDataList, standbyRefChannelDataList, standbyChannelDataList); + + // 8. 显示在界面上 + CounterDevice * devicePtr = ConstCache::getInstance().deviceMap.value(devAId); + if (devicePtr != nullptr && SettingConfig::getInstance().MASTER == devicePtr->getIsUse()) + { + int devIdx = devicePtr->getFormColIndex(); + + // 通道Label的序号 + int channelIdx = devIdx * 16 + channelNo.toInt() - 1; + computeValueList.at(channelIdx)->setText(QString::number(avgTimeDiff * 1E9, 'f', 3)); + } + } + } + } + + // 8. 遍历所有的备路计数器 + for (QString devBId : ConstCache::getInstance().deviceIdLoopB) { + // 2. 遍历主路计数器的每一个通道(除参考通道外) + for (QString key : ConstCache::getInstance().channelMap.keys()) { + if (key.contains(devBId) == false) { + continue; + } else { + // A当前通道 + CounterChannel * channel = ConstCache::getInstance().channelMap.value(key); + QString channelCode = channel->getChannelCode(); // 钟编号 + QString channelNo = channel->getChannelNo(); // 通道号 + + if (channelNo == "00" || channelNo == "01" || channelCode.isEmpty()) { + continue; + } + + // B主路参考通道在主路的测量通道 + CounterChannel * standbyRefChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(ConstCache::getInstance().loopInfos.at(0).at(1)).arg(ConstCache::getInstance().loopInfos.at(0).at(3))); + + // 3. 获得通道的钟编号、通道号,找到对应钟编号、通道号在备路对应的通道 + // C对应的主路测量通道 + QString standbyKey = ""; + CounterChannel * standbyChannel = nullptr; + if (ConstCache::getInstance().standbyMap.contains(key) == false) { + // 在对路计数器中找 并存入standbyMap + for (QString standbyDevId : ConstCache::getInstance().deviceIdLoopA) { + // 通道号和钟编号都匹配 + standbyChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(standbyDevId).arg(channelNo)); + if (standbyChannel != nullptr && standbyChannel->getChannelCode() == channelCode) { + standbyKey = QString("%1-%2").arg(standbyDevId).arg(channelNo); + ConstCache::getInstance().standbyMap.insert(key, standbyKey); + } + } + } else { + standbyKey = ConstCache::getInstance().standbyMap.value(key); + standbyChannel = ConstCache::getInstance().channelMap.value(standbyKey); + } + + // 4. 取当前通道的最后10个历史数据 channel + QList thisChannelDataList; + if (channel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + thisChannelDataList = channel->getHisData().mid(channel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 5. 取主路参考通道最后10个历史数据 standbyRefChannel + QList standbyRefChannelDataList; + if (standbyRefChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyRefChannelDataList = standbyRefChannel->getHisData().mid(standbyRefChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 6. 取主路计数器对应通道的最后10个历史数据 standbyChannel + QList standbyChannelDataList; + if (standbyChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyChannelDataList = standbyChannel->getHisData().mid(standbyChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 7. 计算当前通道相对主路参考钟的时差 与主路对应通道的时差做差 + if (thisChannelDataList.isEmpty() || standbyChannelDataList.isEmpty()) { + continue; + } + double avgTimeDiff = calculateAvgStandbyTimeDiff(thisChannelDataList, standbyRefChannelDataList, standbyChannelDataList); + + // 8. 显示在界面上 + CounterDevice * devicePtr = ConstCache::getInstance().deviceMap.value(devBId); + if (devicePtr != nullptr && SettingConfig::getInstance().MASTER == devicePtr->getIsUse()) + { + int devIdx = devicePtr->getFormColIndex(); + + // 通道Label的序号 + int channelIdx = devIdx * 16 + channelNo.toInt() - 1; + computeValueList.at(channelIdx)->setText(QString::number(avgTimeDiff * 1E9, 'f', 3)); + } + } + } + } + } +} + void CounterWindowRT::on_btnMenuSetting_clicked() { settingForm->setWindowModality(Qt::ApplicationModal); @@ -600,8 +908,10 @@ // 将lab列表的数量置0 devTitleList.resize(0); devRefList.resize(0); + devCompRefList.resize(0); channelNameList.resize(0); channelValueList.resize(0); + computeValueList.resize(0); initDevAndChannelForm(SettingConfig::getInstance().DISPLAY_COUNT); } @@ -620,14 +930,20 @@ devTitleList.at(i)->setText(dev->getDeviceName()); // 设备名称 dev->setFormColIndex(i); } + for (int j = 1; j < 16; j++) + { + computeValueList.at(i * 16 + j)->setText("-"); + } } else { devTitleList.at(i)->setText(""); devRefList.at(i)->setText(""); + devCompRefList.at(i)->setText(""); for (int j = 0; j < 16; j++) { channelNameList.at(i * 16 + j)->setText(""); channelValueList.at(i * 16 + j)->setText(""); + computeValueList.at(i * 16 + j)->setText(""); } } } @@ -685,7 +1001,7 @@ // 参考通道 int refChNo = messageArray.at(0).toObject().value("data").toObject().value("channelRefNo").toInt(); - CounterChannel * refChann = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo)); + CounterChannel * refChann = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo, 2, 10, QLatin1Char('0'))); if (refChann != nullptr) { if (devIdx < devRefList.size()) { @@ -704,7 +1020,7 @@ void CounterWindowRT::onKafkaMessageReceived(QJsonObject message) { qDebug() << message; - std::cout << QString(QJsonDocument(message).toJson(QJsonDocument::Compact)).toStdString() << std::endl; + std::cout << "kafka message received: " << std::endl << QString(QJsonDocument(message).toJson(QJsonDocument::Compact)).toStdString() << std::endl; // 找不到deviceId deviceType operation三个必填项 直接返回 if (message.contains("deviceId") == false || message.contains("operation") == false || message.contains("deviceType") == false) { @@ -732,7 +1048,7 @@ void CounterWindowRT::onAlarmMessageReceived(QJsonObject alarmMsg) { qDebug() << alarmMsg; - std::cout << QString(QJsonDocument(alarmMsg).toJson(QJsonDocument::Compact)).toStdString() << std::endl; + std::cout << "alarm message received: " << std::endl << QString(QJsonDocument(alarmMsg).toJson(QJsonDocument::Compact)).toStdString() << std::endl; QString deviceId = alarmMsg.value("deviceId").toString(); QString channelId = alarmMsg.value("channelId").toString(); diff --git a/CounterRealTime/CounterWindowRT.h b/CounterRealTime/CounterWindowRT.h index b672cfc..b4eea96 100644 --- a/CounterRealTime/CounterWindowRT.h +++ b/CounterRealTime/CounterWindowRT.h @@ -17,10 +17,13 @@ #include "CounterSettingForm.h" #include "common/utils/SettingConfig.h" #include "common/utils/TimerCounterUtil.h" -#include "common/utils/QKafkaConsumer.h" #include "common/HttpRequestController.h" #include "common/HttpServer.h" +#ifdef unix +#include "common/utils/QKafkaConsumer.h" +#endif + QT_BEGIN_NAMESPACE namespace Ui { class CounterWindowRT; } QT_END_NAMESPACE @@ -47,12 +50,17 @@ QVector devTitleList; // 计数器设备标题的QLabel集合 QVector devRefList; // Ref通道 + QVector devCompRefList; // 归算Ref通道 QVector channelNameList; // 通道名的QLabel集合 QVector channelValueList; // 通道测量值的QLabel集合 + QVector computeValueList; // 通道归算值的QLabel集合 HttpRequestController * httpReq; + +#ifdef unix QKafkaConsumer * kafkaConsumer; QKafkaConsumer * alarmMsgConsumer; +#endif QVector alarmDev; QVector offlineDev; @@ -67,9 +75,13 @@ void initDevAndChannelForm(int count); void updateChannelDataForm(QJsonArray messageArray); void updateDeviceAlarm(QJsonArray alarmList); + void findRefAndMeasureChannel(); // 查找主备路的测量参考通道以及各自的测量通道 + double calculateAvgStandbyTimeDiff(QList thisChannel, QList refChannel, QList standbyChannel); + private slots: void updateDateAndTime(); + void watchStandbyConsistency(); int initHttpToken(); diff --git a/CounterRealTime/common/ConstCache.h b/CounterRealTime/common/ConstCache.h index 25a97d4..c5af508 100644 --- a/CounterRealTime/common/ConstCache.h +++ b/CounterRealTime/common/ConstCache.h @@ -31,6 +31,9 @@ QList deviceIdLoopB; // B路计数器对象集合 key=deviceId QMap channelMap; // 通道对象集合 key=deviceId-channelNo + QList loopInfos; // 存储主备路关键信息 参考钟编号;在对路的测量计数器ID;在对路的测量计数器所在通道ID;对路计数器所在的通道号 + QMap standbyMap; // 主路/备路通道的备路/主路对应通道key key=deviceId-channelNo value=deviceId-channelNo + QMap alarmDeviceMap; // 报警设备 QMap alarmChannelMap; // 报警通道 diff --git a/CounterRealTime/common/HttpRequestController.cpp b/CounterRealTime/common/HttpRequestController.cpp index 58ac632..0b8a3e4 100644 --- a/CounterRealTime/common/HttpRequestController.cpp +++ b/CounterRealTime/common/HttpRequestController.cpp @@ -130,7 +130,7 @@ } delete reply; - qDebug() << resultObj; +// qDebug() << resultObj; return resultObj; } @@ -239,7 +239,7 @@ } delete reply; - qDebug() << resultObj; +// qDebug() << "alarm List: " << resultObj; return resultObj; } diff --git a/CounterRealTime/common/common.pri b/CounterRealTime/common/common.pri index aa3f245..9d51c30 100644 --- a/CounterRealTime/common/common.pri +++ b/CounterRealTime/common/common.pri @@ -1,10 +1,7 @@ - SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp -SOURCES += $$PWD/utils/QKafkaUtil.cpp -SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/LinearRegression.cpp @@ -16,8 +13,6 @@ HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h -HEADERS += $$PWD/utils/QKafkaUtil.h -HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h @@ -25,3 +20,11 @@ HEADERS += $$PWD/HttpRequestController.h HEADERS += $$PWD/HttpServer.h HEADERS += $$PWD/ConstCache.h + +unix { + SOURCES += $$PWD/utils/QKafkaUtil.cpp + SOURCES += $$PWD/utils/QKafkaConsumer.cpp + + HEADERS += $$PWD/utils/QKafkaUtil.h + HEADERS += $$PWD/utils/QKafkaConsumer.h +} diff --git a/CounterRealTime/common/utils/SettingConfig.cpp b/CounterRealTime/common/utils/SettingConfig.cpp index b6c72d7..f94a918 100644 --- a/CounterRealTime/common/utils/SettingConfig.cpp +++ b/CounterRealTime/common/utils/SettingConfig.cpp @@ -51,6 +51,7 @@ PASSWORD = getProperty("client", "password").toString(); SERVER_PORT = getProperty("client", "serverPort").toInt(); CLIENT_TITLE = getProperty("client", "title").toString(); + STANDBY_CONSISTENCY_SECOND = getProperty("client", "standbyConsistencySecond").toUInt(); DEVICE_ALARM_CODES = getProperty("alarm", "deviceAlarmCodes").toString().split(","); CHANNEL_ALARM_CODES = getProperty("alarm", "channelAlarmCodes").toString().split(","); diff --git a/CounterRealTime/common/utils/SettingConfig.h b/CounterRealTime/common/utils/SettingConfig.h index 5b8735a..64e11f3 100644 --- a/CounterRealTime/common/utils/SettingConfig.h +++ b/CounterRealTime/common/utils/SettingConfig.h @@ -75,6 +75,8 @@ // 服务监听端口号 quint16 SERVER_PORT; QString CLIENT_TITLE; + // 主备一致性监测执行频次 + quint8 STANDBY_CONSISTENCY_SECOND; // 设备报警类型 QStringList DEVICE_ALARM_CODES; diff --git a/CounterRealTime/CounterDevice.cpp b/CounterRealTime/CounterDevice.cpp index 4ff6565..f656746 100644 --- a/CounterRealTime/CounterDevice.cpp +++ b/CounterRealTime/CounterDevice.cpp @@ -9,11 +9,13 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &CounterDevice::dataReceivedHandler); +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); kafkaUtil.createProducer(); } +#endif } CounterDevice::~CounterDevice() @@ -78,6 +80,15 @@ this->refChannelCode = refChannelCode; } +int CounterDevice::getRefChannelNo() +{ + return this->refChannelNo; +} +void CounterDevice::setRefChannelNo(int refChannelNo) +{ + this->refChannelNo = refChannelNo; +} + bool CounterDevice::isSerialOpen() { return this->serialUtil.isOpen(); @@ -156,7 +167,7 @@ msgLogFilename = msgLogFilename.arg((hour / 6) * 6, 2, 10, QLatin1Char('0')); msgLogFilename = msgLogFilename.arg((hour / 6) * 6 + 5, 2, 10, QLatin1Char('0')); - CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(counterData->channelRefId)); + CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(counterData->channelRefId, 2, 10, QLatin1Char('0'))); this->refChannelNo = counterData->channelRefId; double refDelay = 0.0; if (refChanPtr != nullptr && refChanPtr->getDelays().isEmpty() == false) { @@ -186,7 +197,7 @@ } // 加到hisDataList中 用于绘制图表 - CounterChannel * channelPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i)); + CounterChannel * channelPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i, 2, 10, QLatin1Char('0'))); if (channelPtr != nullptr && channelPtr->isActive() == true) { // 通道时延值 并计算 减去时延值的测量值 @@ -210,6 +221,7 @@ statusObj.insert("master", SettingConfig::getInstance().MASTER); statusObj.insert("deviceId", deviceId); +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { if (SettingConfig::getInstance().MASTER == 0) @@ -227,6 +239,7 @@ kafkaUtil.produceMessage(SettingConfig::getInstance().KAFKA_STATUS_TOPIC, QString(QJsonDocument(statusObj).toJson(QJsonDocument::Compact))); } } +#endif QLogUtil::writeMessageLogByDate(date, msgLogFilename, QString(QJsonDocument(messageArray).toJson(QJsonDocument::Compact))); diff --git a/CounterRealTime/CounterDevice.h b/CounterRealTime/CounterDevice.h index c4d003d..68390c8 100644 --- a/CounterRealTime/CounterDevice.h +++ b/CounterRealTime/CounterDevice.h @@ -6,7 +6,6 @@ #include "CounterChannel.h" #include "common/utils/QSerialPortUtil.h" -#include "common/utils/QKafkaUtil.h" #include "common/utils/QByteUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" @@ -14,6 +13,10 @@ #include "common/LinearRegression.h" #include "protocol/CounterProtocolXH.h" +#ifdef unix +#include "common/utils/QKafkaUtil.h" +#endif + class CounterDevice : public QObject { Q_OBJECT @@ -37,6 +40,9 @@ int getIsUse(); void setIsUse(int isUse); + int getRefChannelNo(); + void setRefChannelNo(int refChannelNo); + QString getRefChannelCode(); void setRefChannelCode(QString refChannelCode); @@ -56,9 +62,12 @@ int formColIndex; QSerialPortUtil serialUtil; - QKafkaUtil kafkaUtil; QByteArray dataBuff; +#ifdef unix + QKafkaUtil kafkaUtil; +#endif + void afterFramePhase(CounterDataDto * counterData); void calcResidualClockData(qlonglong tm); diff --git a/CounterRealTime/CounterRealTime.pro b/CounterRealTime/CounterRealTime.pro index c323f04..f990ff3 100644 --- a/CounterRealTime/CounterRealTime.pro +++ b/CounterRealTime/CounterRealTime.pro @@ -49,7 +49,8 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka++ -lrdkafka +win32: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka++ -lrdkafka INCLUDEPATH += $$PWD/include/librdkafka DEPENDPATH += $$PWD/include/librdkafka diff --git a/CounterRealTime/CounterSettingForm.cpp b/CounterRealTime/CounterSettingForm.cpp index c1945d1..bc43ac7 100644 --- a/CounterRealTime/CounterSettingForm.cpp +++ b/CounterRealTime/CounterSettingForm.cpp @@ -335,7 +335,7 @@ active = activeListRight.at(i - 8)->isChecked(); } - CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1)); + CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1, 2, 10, QLatin1Char('0'))); if (channelPrt != nullptr) { bool isUpdated = isChannelSettingUpdated(i, channelPrt); @@ -362,7 +362,7 @@ newChannel->setChannelCode(channelCode); newChannel->setDelays(QString::number(delay)); - ConstCache::getInstance().channelMap.insert(QString("%1-%2").arg(deviceId).arg(i+1), newChannel); + ConstCache::getInstance().channelMap.insert(QString("%1-%2").arg(deviceId).arg(i+1, 2, 10, QLatin1Char('0')), newChannel); QJsonObject channelObj; channelObj.insert("id", ""); @@ -412,7 +412,7 @@ activeListLeft.at(i)->setCheckable(true); activeListRight.at(i)->setCheckable(true); - CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1)); + CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1, 2, 10, QLatin1Char('0'))); if (channelPrt != nullptr) { QString channelCode = channelPrt->getChannelCode(); // 通道钟号 @@ -429,7 +429,7 @@ } } - CounterChannel * channelRightPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1+8)); + CounterChannel * channelRightPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1+8, 2, 10, QLatin1Char('0'))); if (channelRightPrt != nullptr) { QString channelCode = channelRightPrt->getChannelCode(); // 通道钟号 diff --git a/CounterRealTime/CounterWindowRT.cpp b/CounterRealTime/CounterWindowRT.cpp index 30adf9b..78815d7 100644 --- a/CounterRealTime/CounterWindowRT.cpp +++ b/CounterRealTime/CounterWindowRT.cpp @@ -76,6 +76,7 @@ file.close(); } +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { // kafka consumer kafkaConsumer = new QKafkaConsumer(this); @@ -93,6 +94,7 @@ alarmMsgConsumer->start(); connect(alarmMsgConsumer, &QKafkaConsumer::messageRecieved, this, &CounterWindowRT::onAlarmMessageReceived); } +#endif // 绘制界面上的表格 initChannelForm(); @@ -100,6 +102,10 @@ // 显示时钟 每秒更新 connect(TimerCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &CounterWindowRT::updateDateAndTime); TimerCounterUtil::getInstance().clockCounter->start(1000); + QTimer::singleShot(30000, [=](){ + // 定时执行主备一致性监测 + connect(TimerCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &CounterWindowRT::watchStandbyConsistency); + }); // 重新选择显示多少个计数器 connect(settingForm, &CounterSettingForm::swiftDisplayLoop, this, &CounterWindowRT::updateDeviceWidget); @@ -182,7 +188,7 @@ } for (int i = 0; i < devSet.size(); i++) { - getChannelList(devSet.toList().at(i)); + getChannelList(devSet.values().at(i)); } } } @@ -233,6 +239,13 @@ } updateDeviceWidget(); + +// qDebug() << "loop A: " << ConstCache::getInstance().deviceIdLoopA; +// qDebug() << "loop B: " << ConstCache::getInstance().deviceIdLoopB; + + // 查找主路参考钟在备路计数器的测量通道 + // 查找备路参考钟在主路计数器的测量通道 + findRefAndMeasureChannel(); } } QList CounterWindowRT::getClockNumList() @@ -262,7 +275,8 @@ { // for (int i = 0; i <= 16; i++) { - ConstCache::getInstance().channelMap.remove(QString("%1-%2").arg(deviceId).arg(i)); + QString channelKey = QString("%1-%2").arg(deviceId).arg(i); + ConstCache::getInstance().channelMap.remove(channelKey); } // 将通道绘制在界面上 @@ -273,7 +287,7 @@ QJsonObject channelItem = channelArray.at(i).toObject(); QString channelId = channelItem.value("id").toString(); // 通道ID QString channelCode = channelItem.value("channelCode").toString(); // 通道钟号 - QString channelNo = QString::number(channelItem.value("channelNo").toInt()); // 通道序号 + QString channelNo = QString("%1").arg(channelItem.value("channelNo").toInt(), 2, 10, QLatin1Char('0')); // 通道序号 QString delays = channelItem.value("delays").toString(); // 通道时延值 QString isUse = channelItem.value("isUse").toString(); QString name = channelItem.value("name").toString(); @@ -292,6 +306,14 @@ // 添加到通道的集合中 key=deviceId-channelNo ConstCache::getInstance().channelMap.insert(deviceId + "-" + channelNo, channel); + + if (channelCode.isEmpty() == false && active == true) { + CounterDevice * counterDev = ConstCache::getInstance().deviceMap.value(deviceId); + if (counterDev != nullptr) { + QStringList channelBase; + channelBase << QString::number(counterDev->getIsUse()) << channelCode; + } + } } } } @@ -314,10 +336,12 @@ layoutChannelPage->setMargin(3); // 留出边框的位置 // 左右布局中是垂直布局,用于显示通道 - QVBoxLayout * layoutChannelLeft = new QVBoxLayout(); - QVBoxLayout * layoutChannelRight = new QVBoxLayout(); + QVBoxLayout * layoutChannelLeft = new QVBoxLayout(); // 最左侧显示设备简称 + QVBoxLayout * layoutChannelMain = new QVBoxLayout(); // 中间显示参考通道 + QVBoxLayout * layoutChannelRight = new QVBoxLayout(); // 最右侧显示归算参考通道 字号小一号 layoutChannelLeft->setSpacing(0); + layoutChannelMain->setSpacing(0); layoutChannelRight->setSpacing(0); // 设备标题的Label @@ -330,55 +354,76 @@ // 设备参考通道的Label QLabel * labDevRef = new QLabel(widgetDev); labDevRef->setProperty("labType", QString("devRef%1").arg(count)); // 样式表属性 - labDevRef->setText(QString("REF: %1").arg("1000")); + labDevRef->setText(QString("REF: %1").arg("10000")); labDevRef->setAlignment(Qt::AlignCenter); // 文字居中显示 devRefList.append(labDevRef); + // 设置归算使用的参考通道Label + QLabel * labCompDevRef = new QLabel(widgetDev); + labCompDevRef->setProperty("labType", QString("devCompRef%1").arg(count)); // 样式表属性 + labCompDevRef->setText(QString("%1").arg("主备时差")); + labCompDevRef->setAlignment(Qt::AlignCenter); // 文字居中显示 + devCompRefList.append(labCompDevRef); + if (count == 4) { labDevTitle->setMaximumHeight(80); // 设置固定高度 labDevTitle->setMinimumHeight(80); labDevRef->setMaximumHeight(80); // 设置固定高度 labDevRef->setMinimumHeight(80); + + labCompDevRef->setMaximumHeight(80); // 设置固定高度 + labCompDevRef->setMinimumHeight(80); } else { labDevTitle->setMaximumHeight(60); // 设置固定高度 labDevTitle->setMinimumHeight(60); labDevRef->setMaximumHeight(60); // 设置固定高度 labDevRef->setMinimumHeight(60); + + labCompDevRef->setMaximumHeight(60); // 设置固定高度 + labCompDevRef->setMinimumHeight(60); } // 左侧显示设备简称,右侧显示参考通道名 layoutChannelLeft->addWidget(labDevTitle); - layoutChannelRight->addWidget(labDevRef); + layoutChannelMain->addWidget(labDevRef); + layoutChannelRight->addWidget(labCompDevRef); // 每个计数器显示16个通道 for ( int i = 0; i < 16; i++ ) { QLabelDblClick * labChannelName = new QLabelDblClick(widgetDev); // 通道名 QLabelDblClick * labChannelValue = new QLabelDblClick(widgetDev); // 通道测量值 + QLabelDblClick * labComputeValue = new QLabelDblClick(widgetDev); // 通道归算值 // 默认显示内容 - labChannelName->setText(QString("CH%1").arg(i+1, 2, 10, QLatin1Char('0'))); + labChannelName->setText(QString("%1: 10000").arg(i+1, 2, 10, QLatin1Char('0'))); labChannelValue->setText("0.000000000000"); + labComputeValue->setText(""); // css不支持的样式用代码实现 - labChannelName->setMargin(10); - labChannelValue->setMargin(10); + labChannelName->setMargin(5); + labChannelValue->setMargin(5); labChannelValue->setAlignment(Qt::AlignRight | Qt::AlignVCenter); + labComputeValue->setMargin(5); + labComputeValue->setAlignment(Qt::AlignRight | Qt::AlignVCenter); // 奇偶显示不同的背景色 if (i % 2 == 0) { labChannelName->setProperty("labType", QString("channelNameEven%1").arg(count)); labChannelValue->setProperty("labType", QString("channelValueEven%1").arg(count)); + labComputeValue->setProperty("labType", QString("computeValueEven%1").arg(count)); } else { labChannelName->setProperty("labType", QString("channelNameOdd%1").arg(count)); labChannelValue->setProperty("labType", QString("channelValueOdd%1").arg(count)); + labComputeValue->setProperty("labType", QString("computeValueOdd%1").arg(count)); } layoutChannelLeft->addWidget(labChannelName); - layoutChannelRight->addWidget(labChannelValue); + layoutChannelMain->addWidget(labChannelValue); + layoutChannelRight->addWidget(labComputeValue); // 添加通道名称的双击事件,显示数据和残差图表 connect(labChannelName, &QLabelDblClick::doubleClicked, this, &CounterWindowRT::onChannelNameLabelDblClicked); @@ -386,16 +431,21 @@ channelNameList.append(labChannelName); channelValueList.append(labChannelValue); + computeValueList.append(labComputeValue); // 左下角和右下角的圆角处理 if (i == 15) { labChannelName->setStyleSheet("border-bottom-left-radius: 10px;"); - labChannelValue->setStyleSheet("border-bottom-right-radius: 10px;"); + labComputeValue->setStyleSheet("border-bottom-right-radius: 10px;"); } } layoutChannelPage->addLayout(layoutChannelLeft); + layoutChannelPage->addLayout(layoutChannelMain); layoutChannelPage->addLayout(layoutChannelRight); + layoutChannelPage->setStretch(0, 35); + layoutChannelPage->setStretch(1, 50); + layoutChannelPage->setStretch(2, 15); widgetDev->setLayout(layoutChannelPage); } } @@ -407,13 +457,19 @@ // 参考通道号 int refChNo = messageArray.at(0).toObject().value("data").toObject().value("channelRefNo").toInt(); + CounterDevice * counter = ConstCache::getInstance().deviceMap.value(deviceId); + if (counter == nullptr) { + return; + } + counter->setRefChannelNo(refChNo); + // 根据设备id 从map中取出列索引的值 - int devIdx = ConstCache::getInstance().deviceMap.value(deviceId)->getFormColIndex(); + int devIdx = counter->getFormColIndex(); if (devIdx < devRefList.size()) { // 参考通道的显示 QString refText = devRefList.at(devIdx)->text(); - channelNameList.at(devIdx * 16 + refChNo - 1)->setText(QString("CH%1:%2").arg(refChNo, 2, 10, QLatin1Char('0')).arg(refText.right(refText.length() - 4))); + channelNameList.at(devIdx * 16 + refChNo - 1)->setText(QString("%1:%2").arg(refChNo, 2, 10, QLatin1Char('0')).arg(refText.right(refText.length() - 4))); if (alarmDev.contains(deviceId) == true) { @@ -433,11 +489,11 @@ for (int i = 0; i < messageArray.size(); i++) { QJsonObject channelDataItem = messageArray.at(i).toObject(); - QString channelNo = QString::number(channelDataItem.value("channelNo").toInt()); // 通道序号 + QString channelNo = QString("%1").arg(channelDataItem.value("channelNo").toInt(), 2, 10, QLatin1Char('0')); // 通道序号 channelDataJsonMap.insert(channelNo, channelDataItem); } - CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo)); + CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo, 2, 10, QLatin1Char('0'))); double refDelay = 0.0; if (refChanPtr != nullptr && refChanPtr->getDelays().isEmpty() == false) { refDelay = refChanPtr->getDelays().toDouble(); @@ -454,11 +510,10 @@ continue; } - CounterChannel * channel = ConstCache::getInstance().channelMap.value(deviceId + "-" + channelNo); // 从map中找到对应的通道 - - if (channelDataJsonMap.contains(channelNo) == true) + CounterChannel * channel = ConstCache::getInstance().channelMap.value(deviceId + "-" + channelNoStr); // 从map中找到对应的通道 + if (channelDataJsonMap.contains(channelNoStr) == true) { - QJsonObject channelDataItem = channelDataJsonMap.value(channelNo); + QJsonObject channelDataItem = channelDataJsonMap.value(channelNoStr); // 通道Label的序号 int channelIdx = devIdx * 16 + channelDataItem.value("channelNo").toInt() - 1; @@ -483,19 +538,20 @@ double valueMinusDelay = channelDataItem.value("data").toObject().value("dataValue").toString().toDouble() - delay * 1E-9 + refDelay * 1E-9; // 设置通道名和测量值的QLabel - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); channelValueList.at(channelIdx)->setText(QString::number(valueMinusDelay, 'f', 12)); channelNameList.at(channelIdx)->setProperty("channelId", channel->getChannelId()); channelNameList.at(channelIdx)->setProperty("deviceId", deviceId); - channelNameList.at(channelIdx)->setProperty("channelNo", channelNo); + channelNameList.at(channelIdx)->setProperty("channelNo", channelNoStr); channelValueList.at(channelIdx)->setProperty("channelId", channel->getChannelId()); channelValueList.at(channelIdx)->setProperty("deviceId", deviceId); - channelValueList.at(channelIdx)->setProperty("channelNo", channelNo); + channelValueList.at(channelIdx)->setProperty("channelNo", channelNoStr); } else { - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg("-")); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg("-")); channelValueList.at(channelIdx)->setText(""); + computeValueList.at(channelIdx)->setText(""); } } else { // 计数器返回的无测量值的通道处理逻辑 @@ -503,6 +559,7 @@ // 没有测量值的通道清空 channelValueList.at(channelIdx)->setText(""); + computeValueList.at(channelIdx)->setText(""); // 当通道启用时显示通道离线 不再判断后台传回来的状态 // 当通道未启用时显示正常状态 @@ -510,12 +567,12 @@ channelNameList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value("channelOffline")); channelValueList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value("channelOffline")); - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); } else { channelNameList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value(channelNameList.at(channelIdx)->property("labType").toString())); channelValueList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value(channelValueList.at(channelIdx)->property("labType").toString())); - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg("-")); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg("-")); } } } @@ -523,7 +580,7 @@ void CounterWindowRT::updateDeviceAlarm(QJsonArray alarmList) { - qDebug() << alarmList; +// qDebug() << alarmList; for (int i = 0; i < alarmList.size(); i++) { QJsonObject alarmData = alarmList.at(i).toObject(); @@ -532,7 +589,7 @@ QString alarmCode = alarmData.value("alarmCode").toString(); QString status = alarmData.value("status").toString(); - qDebug() << alarmCode << deviceId << channelId; +// qDebug() << alarmCode << deviceId << channelId; // 如果报警状态不是正在报警 status==0 或者报警设备不是计数器 则不处理 if (status != "0" || ConstCache::getInstance().deviceMap.contains(deviceId) == false) @@ -560,6 +617,92 @@ } } +void CounterWindowRT::findRefAndMeasureChannel() +{ + // 查询主路的参考通道的钟编号 + QString masterKey = QString("%1-%2").arg(ConstCache::getInstance().deviceIdLoopA.at(0)).arg("01"); // 暂时固定为01通道 + CounterChannel * refChannelMaster = ConstCache::getInstance().channelMap.value(masterKey); // 主路参考的钟编号 + + // 查询主路参考通道在备路的测量通道 + for (QString channelKey : ConstCache::getInstance().channelMap.keys()) { + QString deviceId = channelKey.split("-")[0]; + if (ConstCache::getInstance().deviceIdLoopB.contains(deviceId)) { + CounterChannel * channel = ConstCache::getInstance().channelMap.value(channelKey); + if (channel->getChannelCode() == refChannelMaster->getChannelCode()) { + QStringList masterInfo; + masterInfo << refChannelMaster->getChannelCode() << deviceId << channel->getChannelId() << channel->getChannelNo(); + ConstCache::getInstance().loopInfos.append(masterInfo); + + break; + } + } + } + + // 查询备路的参考通道钟编号 + QString slaveKey = QString("%1-%2").arg(ConstCache::getInstance().deviceIdLoopB.at(0)).arg("01"); // 暂时固定为01通道 + CounterChannel * refChannelSlave = ConstCache::getInstance().channelMap.value(slaveKey); // 备路参考的钟编号 + + // 查询备路参考通道在主路的测量通道 + for (QString channelKey : ConstCache::getInstance().channelMap.keys()) { + QString deviceId = channelKey.split("-")[0]; + if (ConstCache::getInstance().deviceIdLoopA.contains(deviceId)) { + CounterChannel * channel = ConstCache::getInstance().channelMap.value(channelKey); + if (channel->getChannelCode() == refChannelSlave->getChannelCode()) { + QStringList slaveInfo; + slaveInfo << refChannelSlave->getChannelCode() << deviceId << channel->getChannelId() << channel->getChannelNo(); + ConstCache::getInstance().loopInfos.append(slaveInfo); + + break; + } + } + } + +// qDebug() << ConstCache::getInstance().loopInfos.at(0); +// qDebug() << ConstCache::getInstance().loopInfos.at(1); +// qDebug() << ConstCache::getInstance().channelMap; +} + +double CounterWindowRT::calculateAvgStandbyTimeDiff(QList thisChannel, + QList refChannel, + QList standbyChannel) +{ + double avgTimeDiff = 0.0; + + if (thisChannel.isEmpty() || refChannel.isEmpty() || standbyChannel.isEmpty()) { + return avgTimeDiff; + } + + double sumThis = 0.0; + double avgThis = 0.0; + int countThis = 0; + for (QStringList thisData : thisChannel) { + sumThis += thisData.at(1).toDouble(); + countThis++; + } + avgThis = sumThis / countThis * 1.0; + + double sumRef = 0.0; + double avgRef = 0.0; + int countRef = 0; + for (QStringList refData : refChannel) { + sumRef += refData.at(1).toDouble(); + countRef++; + } + avgRef = sumRef / countRef * 1.0; + + double sumStandby = 0.0; + double avgStandby = 0.0; + int countStandby = 0; + for (QStringList standbyData : standbyChannel) { + sumStandby += standbyData.at(1).toDouble(); + countStandby++; + } + avgStandby = sumStandby / countStandby * 1.0; + + avgTimeDiff = avgThis - avgRef - avgStandby; + return avgTimeDiff; +} + void CounterWindowRT::updateDateAndTime() { QString date = QDate::currentDate().toString("yyyy-MM-dd"); @@ -567,6 +710,171 @@ ui->labTime->setText(date + " " + time); } +void CounterWindowRT::watchStandbyConsistency() +{ + quint8 second = QTime::currentTime().second(); + if (second % SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND == 0) { + qDebug() << "watchStandbyConsistency: " << QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"); + // 1. 遍历所有的主路计数器 + for (QString devAId : ConstCache::getInstance().deviceIdLoopA) { + // 2. 遍历主路计数器的每一个通道(除参考通道外) + for (QString key : ConstCache::getInstance().channelMap.keys()) { + if (key.contains(devAId) == false) { + continue; + } else { + // A当前通道 + CounterChannel * channel = ConstCache::getInstance().channelMap.value(key); + QString channelCode = channel->getChannelCode(); // 钟编号 + QString channelNo = channel->getChannelNo(); // 通道号 + + if (channelNo == "00" || channelNo == "01" || channelCode.isEmpty()) { + continue; + } + + // B备路参考通道在主路的测量通道 + CounterChannel * standbyRefChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(ConstCache::getInstance().loopInfos.at(1).at(1)).arg(ConstCache::getInstance().loopInfos.at(1).at(3))); + + // 3. 获得通道的钟编号、通道号,找到对应钟编号、通道号在备路对应的通道 + // C对应的备路测量通道 + QString standbyKey = ""; + CounterChannel * standbyChannel = nullptr; + if (ConstCache::getInstance().standbyMap.contains(key) == false) { + // 在对路计数器中找 并存入standbyMap + for (QString standbyDevId : ConstCache::getInstance().deviceIdLoopB) { + // 通道号和钟编号都匹配 + standbyChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(standbyDevId).arg(channelNo)); + if (standbyChannel != nullptr && standbyChannel->getChannelCode() == channelCode) { + standbyKey = QString("%1-%2").arg(standbyDevId).arg(channelNo); + ConstCache::getInstance().standbyMap.insert(key, standbyKey); + } + } + } else { + standbyKey = ConstCache::getInstance().standbyMap.value(key); + standbyChannel = ConstCache::getInstance().channelMap.value(standbyKey); + } + + // 4. 取当前通道的最后10个历史数据 channel + QList thisChannelDataList; + if (channel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + thisChannelDataList = channel->getHisData().mid(channel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 5. 取备路参考通道最后10个历史数据 standbyRefChannel + QList standbyRefChannelDataList; + if (standbyRefChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyRefChannelDataList = standbyRefChannel->getHisData().mid(standbyRefChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 6. 取备路计数器对应通道的最后10个历史数据 standbyChannel + QList standbyChannelDataList; + if (standbyChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyChannelDataList = standbyChannel->getHisData().mid(standbyChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 7. 计算当前通道相对备路参考钟的时差 与备路对应通道的时差做差 + if (thisChannelDataList.isEmpty() || standbyChannelDataList.isEmpty()) { + continue; + } + double avgTimeDiff = calculateAvgStandbyTimeDiff(thisChannelDataList, standbyRefChannelDataList, standbyChannelDataList); + + // 8. 显示在界面上 + CounterDevice * devicePtr = ConstCache::getInstance().deviceMap.value(devAId); + if (devicePtr != nullptr && SettingConfig::getInstance().MASTER == devicePtr->getIsUse()) + { + int devIdx = devicePtr->getFormColIndex(); + + // 通道Label的序号 + int channelIdx = devIdx * 16 + channelNo.toInt() - 1; + computeValueList.at(channelIdx)->setText(QString::number(avgTimeDiff * 1E9, 'f', 3)); + } + } + } + } + + // 8. 遍历所有的备路计数器 + for (QString devBId : ConstCache::getInstance().deviceIdLoopB) { + // 2. 遍历主路计数器的每一个通道(除参考通道外) + for (QString key : ConstCache::getInstance().channelMap.keys()) { + if (key.contains(devBId) == false) { + continue; + } else { + // A当前通道 + CounterChannel * channel = ConstCache::getInstance().channelMap.value(key); + QString channelCode = channel->getChannelCode(); // 钟编号 + QString channelNo = channel->getChannelNo(); // 通道号 + + if (channelNo == "00" || channelNo == "01" || channelCode.isEmpty()) { + continue; + } + + // B主路参考通道在主路的测量通道 + CounterChannel * standbyRefChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(ConstCache::getInstance().loopInfos.at(0).at(1)).arg(ConstCache::getInstance().loopInfos.at(0).at(3))); + + // 3. 获得通道的钟编号、通道号,找到对应钟编号、通道号在备路对应的通道 + // C对应的主路测量通道 + QString standbyKey = ""; + CounterChannel * standbyChannel = nullptr; + if (ConstCache::getInstance().standbyMap.contains(key) == false) { + // 在对路计数器中找 并存入standbyMap + for (QString standbyDevId : ConstCache::getInstance().deviceIdLoopA) { + // 通道号和钟编号都匹配 + standbyChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(standbyDevId).arg(channelNo)); + if (standbyChannel != nullptr && standbyChannel->getChannelCode() == channelCode) { + standbyKey = QString("%1-%2").arg(standbyDevId).arg(channelNo); + ConstCache::getInstance().standbyMap.insert(key, standbyKey); + } + } + } else { + standbyKey = ConstCache::getInstance().standbyMap.value(key); + standbyChannel = ConstCache::getInstance().channelMap.value(standbyKey); + } + + // 4. 取当前通道的最后10个历史数据 channel + QList thisChannelDataList; + if (channel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + thisChannelDataList = channel->getHisData().mid(channel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 5. 取主路参考通道最后10个历史数据 standbyRefChannel + QList standbyRefChannelDataList; + if (standbyRefChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyRefChannelDataList = standbyRefChannel->getHisData().mid(standbyRefChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 6. 取主路计数器对应通道的最后10个历史数据 standbyChannel + QList standbyChannelDataList; + if (standbyChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyChannelDataList = standbyChannel->getHisData().mid(standbyChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 7. 计算当前通道相对主路参考钟的时差 与主路对应通道的时差做差 + if (thisChannelDataList.isEmpty() || standbyChannelDataList.isEmpty()) { + continue; + } + double avgTimeDiff = calculateAvgStandbyTimeDiff(thisChannelDataList, standbyRefChannelDataList, standbyChannelDataList); + + // 8. 显示在界面上 + CounterDevice * devicePtr = ConstCache::getInstance().deviceMap.value(devBId); + if (devicePtr != nullptr && SettingConfig::getInstance().MASTER == devicePtr->getIsUse()) + { + int devIdx = devicePtr->getFormColIndex(); + + // 通道Label的序号 + int channelIdx = devIdx * 16 + channelNo.toInt() - 1; + computeValueList.at(channelIdx)->setText(QString::number(avgTimeDiff * 1E9, 'f', 3)); + } + } + } + } + } +} + void CounterWindowRT::on_btnMenuSetting_clicked() { settingForm->setWindowModality(Qt::ApplicationModal); @@ -600,8 +908,10 @@ // 将lab列表的数量置0 devTitleList.resize(0); devRefList.resize(0); + devCompRefList.resize(0); channelNameList.resize(0); channelValueList.resize(0); + computeValueList.resize(0); initDevAndChannelForm(SettingConfig::getInstance().DISPLAY_COUNT); } @@ -620,14 +930,20 @@ devTitleList.at(i)->setText(dev->getDeviceName()); // 设备名称 dev->setFormColIndex(i); } + for (int j = 1; j < 16; j++) + { + computeValueList.at(i * 16 + j)->setText("-"); + } } else { devTitleList.at(i)->setText(""); devRefList.at(i)->setText(""); + devCompRefList.at(i)->setText(""); for (int j = 0; j < 16; j++) { channelNameList.at(i * 16 + j)->setText(""); channelValueList.at(i * 16 + j)->setText(""); + computeValueList.at(i * 16 + j)->setText(""); } } } @@ -685,7 +1001,7 @@ // 参考通道 int refChNo = messageArray.at(0).toObject().value("data").toObject().value("channelRefNo").toInt(); - CounterChannel * refChann = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo)); + CounterChannel * refChann = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo, 2, 10, QLatin1Char('0'))); if (refChann != nullptr) { if (devIdx < devRefList.size()) { @@ -704,7 +1020,7 @@ void CounterWindowRT::onKafkaMessageReceived(QJsonObject message) { qDebug() << message; - std::cout << QString(QJsonDocument(message).toJson(QJsonDocument::Compact)).toStdString() << std::endl; + std::cout << "kafka message received: " << std::endl << QString(QJsonDocument(message).toJson(QJsonDocument::Compact)).toStdString() << std::endl; // 找不到deviceId deviceType operation三个必填项 直接返回 if (message.contains("deviceId") == false || message.contains("operation") == false || message.contains("deviceType") == false) { @@ -732,7 +1048,7 @@ void CounterWindowRT::onAlarmMessageReceived(QJsonObject alarmMsg) { qDebug() << alarmMsg; - std::cout << QString(QJsonDocument(alarmMsg).toJson(QJsonDocument::Compact)).toStdString() << std::endl; + std::cout << "alarm message received: " << std::endl << QString(QJsonDocument(alarmMsg).toJson(QJsonDocument::Compact)).toStdString() << std::endl; QString deviceId = alarmMsg.value("deviceId").toString(); QString channelId = alarmMsg.value("channelId").toString(); diff --git a/CounterRealTime/CounterWindowRT.h b/CounterRealTime/CounterWindowRT.h index b672cfc..b4eea96 100644 --- a/CounterRealTime/CounterWindowRT.h +++ b/CounterRealTime/CounterWindowRT.h @@ -17,10 +17,13 @@ #include "CounterSettingForm.h" #include "common/utils/SettingConfig.h" #include "common/utils/TimerCounterUtil.h" -#include "common/utils/QKafkaConsumer.h" #include "common/HttpRequestController.h" #include "common/HttpServer.h" +#ifdef unix +#include "common/utils/QKafkaConsumer.h" +#endif + QT_BEGIN_NAMESPACE namespace Ui { class CounterWindowRT; } QT_END_NAMESPACE @@ -47,12 +50,17 @@ QVector devTitleList; // 计数器设备标题的QLabel集合 QVector devRefList; // Ref通道 + QVector devCompRefList; // 归算Ref通道 QVector channelNameList; // 通道名的QLabel集合 QVector channelValueList; // 通道测量值的QLabel集合 + QVector computeValueList; // 通道归算值的QLabel集合 HttpRequestController * httpReq; + +#ifdef unix QKafkaConsumer * kafkaConsumer; QKafkaConsumer * alarmMsgConsumer; +#endif QVector alarmDev; QVector offlineDev; @@ -67,9 +75,13 @@ void initDevAndChannelForm(int count); void updateChannelDataForm(QJsonArray messageArray); void updateDeviceAlarm(QJsonArray alarmList); + void findRefAndMeasureChannel(); // 查找主备路的测量参考通道以及各自的测量通道 + double calculateAvgStandbyTimeDiff(QList thisChannel, QList refChannel, QList standbyChannel); + private slots: void updateDateAndTime(); + void watchStandbyConsistency(); int initHttpToken(); diff --git a/CounterRealTime/common/ConstCache.h b/CounterRealTime/common/ConstCache.h index 25a97d4..c5af508 100644 --- a/CounterRealTime/common/ConstCache.h +++ b/CounterRealTime/common/ConstCache.h @@ -31,6 +31,9 @@ QList deviceIdLoopB; // B路计数器对象集合 key=deviceId QMap channelMap; // 通道对象集合 key=deviceId-channelNo + QList loopInfos; // 存储主备路关键信息 参考钟编号;在对路的测量计数器ID;在对路的测量计数器所在通道ID;对路计数器所在的通道号 + QMap standbyMap; // 主路/备路通道的备路/主路对应通道key key=deviceId-channelNo value=deviceId-channelNo + QMap alarmDeviceMap; // 报警设备 QMap alarmChannelMap; // 报警通道 diff --git a/CounterRealTime/common/HttpRequestController.cpp b/CounterRealTime/common/HttpRequestController.cpp index 58ac632..0b8a3e4 100644 --- a/CounterRealTime/common/HttpRequestController.cpp +++ b/CounterRealTime/common/HttpRequestController.cpp @@ -130,7 +130,7 @@ } delete reply; - qDebug() << resultObj; +// qDebug() << resultObj; return resultObj; } @@ -239,7 +239,7 @@ } delete reply; - qDebug() << resultObj; +// qDebug() << "alarm List: " << resultObj; return resultObj; } diff --git a/CounterRealTime/common/common.pri b/CounterRealTime/common/common.pri index aa3f245..9d51c30 100644 --- a/CounterRealTime/common/common.pri +++ b/CounterRealTime/common/common.pri @@ -1,10 +1,7 @@ - SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp -SOURCES += $$PWD/utils/QKafkaUtil.cpp -SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/LinearRegression.cpp @@ -16,8 +13,6 @@ HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h -HEADERS += $$PWD/utils/QKafkaUtil.h -HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h @@ -25,3 +20,11 @@ HEADERS += $$PWD/HttpRequestController.h HEADERS += $$PWD/HttpServer.h HEADERS += $$PWD/ConstCache.h + +unix { + SOURCES += $$PWD/utils/QKafkaUtil.cpp + SOURCES += $$PWD/utils/QKafkaConsumer.cpp + + HEADERS += $$PWD/utils/QKafkaUtil.h + HEADERS += $$PWD/utils/QKafkaConsumer.h +} diff --git a/CounterRealTime/common/utils/SettingConfig.cpp b/CounterRealTime/common/utils/SettingConfig.cpp index b6c72d7..f94a918 100644 --- a/CounterRealTime/common/utils/SettingConfig.cpp +++ b/CounterRealTime/common/utils/SettingConfig.cpp @@ -51,6 +51,7 @@ PASSWORD = getProperty("client", "password").toString(); SERVER_PORT = getProperty("client", "serverPort").toInt(); CLIENT_TITLE = getProperty("client", "title").toString(); + STANDBY_CONSISTENCY_SECOND = getProperty("client", "standbyConsistencySecond").toUInt(); DEVICE_ALARM_CODES = getProperty("alarm", "deviceAlarmCodes").toString().split(","); CHANNEL_ALARM_CODES = getProperty("alarm", "channelAlarmCodes").toString().split(","); diff --git a/CounterRealTime/common/utils/SettingConfig.h b/CounterRealTime/common/utils/SettingConfig.h index 5b8735a..64e11f3 100644 --- a/CounterRealTime/common/utils/SettingConfig.h +++ b/CounterRealTime/common/utils/SettingConfig.h @@ -75,6 +75,8 @@ // 服务监听端口号 quint16 SERVER_PORT; QString CLIENT_TITLE; + // 主备一致性监测执行频次 + quint8 STANDBY_CONSISTENCY_SECOND; // 设备报警类型 QStringList DEVICE_ALARM_CODES; diff --git a/CounterRealTime/conf/config.ini b/CounterRealTime/conf/config.ini index 1df42d8..56424fe 100644 --- a/CounterRealTime/conf/config.ini +++ b/CounterRealTime/conf/config.ini @@ -28,6 +28,8 @@ displayCount=4 password=MTIzNDU2 serverPort=5905 +title=钟差测量数据采集软件 +standbyConsistencySecond=10 [alarm] deviceAlarmCodes="DEVICE_OFFLINE,DEVICE_ALARM" diff --git a/CounterRealTime/CounterDevice.cpp b/CounterRealTime/CounterDevice.cpp index 4ff6565..f656746 100644 --- a/CounterRealTime/CounterDevice.cpp +++ b/CounterRealTime/CounterDevice.cpp @@ -9,11 +9,13 @@ connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &CounterDevice::dataReceivedHandler); +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); kafkaUtil.createProducer(); } +#endif } CounterDevice::~CounterDevice() @@ -78,6 +80,15 @@ this->refChannelCode = refChannelCode; } +int CounterDevice::getRefChannelNo() +{ + return this->refChannelNo; +} +void CounterDevice::setRefChannelNo(int refChannelNo) +{ + this->refChannelNo = refChannelNo; +} + bool CounterDevice::isSerialOpen() { return this->serialUtil.isOpen(); @@ -156,7 +167,7 @@ msgLogFilename = msgLogFilename.arg((hour / 6) * 6, 2, 10, QLatin1Char('0')); msgLogFilename = msgLogFilename.arg((hour / 6) * 6 + 5, 2, 10, QLatin1Char('0')); - CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(counterData->channelRefId)); + CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(counterData->channelRefId, 2, 10, QLatin1Char('0'))); this->refChannelNo = counterData->channelRefId; double refDelay = 0.0; if (refChanPtr != nullptr && refChanPtr->getDelays().isEmpty() == false) { @@ -186,7 +197,7 @@ } // 加到hisDataList中 用于绘制图表 - CounterChannel * channelPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i)); + CounterChannel * channelPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i, 2, 10, QLatin1Char('0'))); if (channelPtr != nullptr && channelPtr->isActive() == true) { // 通道时延值 并计算 减去时延值的测量值 @@ -210,6 +221,7 @@ statusObj.insert("master", SettingConfig::getInstance().MASTER); statusObj.insert("deviceId", deviceId); +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { if (SettingConfig::getInstance().MASTER == 0) @@ -227,6 +239,7 @@ kafkaUtil.produceMessage(SettingConfig::getInstance().KAFKA_STATUS_TOPIC, QString(QJsonDocument(statusObj).toJson(QJsonDocument::Compact))); } } +#endif QLogUtil::writeMessageLogByDate(date, msgLogFilename, QString(QJsonDocument(messageArray).toJson(QJsonDocument::Compact))); diff --git a/CounterRealTime/CounterDevice.h b/CounterRealTime/CounterDevice.h index c4d003d..68390c8 100644 --- a/CounterRealTime/CounterDevice.h +++ b/CounterRealTime/CounterDevice.h @@ -6,7 +6,6 @@ #include "CounterChannel.h" #include "common/utils/QSerialPortUtil.h" -#include "common/utils/QKafkaUtil.h" #include "common/utils/QByteUtil.h" #include "common/utils/QLogUtil.h" #include "common/utils/SettingConfig.h" @@ -14,6 +13,10 @@ #include "common/LinearRegression.h" #include "protocol/CounterProtocolXH.h" +#ifdef unix +#include "common/utils/QKafkaUtil.h" +#endif + class CounterDevice : public QObject { Q_OBJECT @@ -37,6 +40,9 @@ int getIsUse(); void setIsUse(int isUse); + int getRefChannelNo(); + void setRefChannelNo(int refChannelNo); + QString getRefChannelCode(); void setRefChannelCode(QString refChannelCode); @@ -56,9 +62,12 @@ int formColIndex; QSerialPortUtil serialUtil; - QKafkaUtil kafkaUtil; QByteArray dataBuff; +#ifdef unix + QKafkaUtil kafkaUtil; +#endif + void afterFramePhase(CounterDataDto * counterData); void calcResidualClockData(qlonglong tm); diff --git a/CounterRealTime/CounterRealTime.pro b/CounterRealTime/CounterRealTime.pro index c323f04..f990ff3 100644 --- a/CounterRealTime/CounterRealTime.pro +++ b/CounterRealTime/CounterRealTime.pro @@ -49,7 +49,8 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target -unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka++ -lrdkafka +win32: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka++ -lrdkafka INCLUDEPATH += $$PWD/include/librdkafka DEPENDPATH += $$PWD/include/librdkafka diff --git a/CounterRealTime/CounterSettingForm.cpp b/CounterRealTime/CounterSettingForm.cpp index c1945d1..bc43ac7 100644 --- a/CounterRealTime/CounterSettingForm.cpp +++ b/CounterRealTime/CounterSettingForm.cpp @@ -335,7 +335,7 @@ active = activeListRight.at(i - 8)->isChecked(); } - CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1)); + CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1, 2, 10, QLatin1Char('0'))); if (channelPrt != nullptr) { bool isUpdated = isChannelSettingUpdated(i, channelPrt); @@ -362,7 +362,7 @@ newChannel->setChannelCode(channelCode); newChannel->setDelays(QString::number(delay)); - ConstCache::getInstance().channelMap.insert(QString("%1-%2").arg(deviceId).arg(i+1), newChannel); + ConstCache::getInstance().channelMap.insert(QString("%1-%2").arg(deviceId).arg(i+1, 2, 10, QLatin1Char('0')), newChannel); QJsonObject channelObj; channelObj.insert("id", ""); @@ -412,7 +412,7 @@ activeListLeft.at(i)->setCheckable(true); activeListRight.at(i)->setCheckable(true); - CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1)); + CounterChannel * channelPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1, 2, 10, QLatin1Char('0'))); if (channelPrt != nullptr) { QString channelCode = channelPrt->getChannelCode(); // 通道钟号 @@ -429,7 +429,7 @@ } } - CounterChannel * channelRightPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1+8)); + CounterChannel * channelRightPrt = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(i+1+8, 2, 10, QLatin1Char('0'))); if (channelRightPrt != nullptr) { QString channelCode = channelRightPrt->getChannelCode(); // 通道钟号 diff --git a/CounterRealTime/CounterWindowRT.cpp b/CounterRealTime/CounterWindowRT.cpp index 30adf9b..78815d7 100644 --- a/CounterRealTime/CounterWindowRT.cpp +++ b/CounterRealTime/CounterWindowRT.cpp @@ -76,6 +76,7 @@ file.close(); } +#ifdef unix if (SettingConfig::getInstance().NEED_KAFKA == 1) { // kafka consumer kafkaConsumer = new QKafkaConsumer(this); @@ -93,6 +94,7 @@ alarmMsgConsumer->start(); connect(alarmMsgConsumer, &QKafkaConsumer::messageRecieved, this, &CounterWindowRT::onAlarmMessageReceived); } +#endif // 绘制界面上的表格 initChannelForm(); @@ -100,6 +102,10 @@ // 显示时钟 每秒更新 connect(TimerCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &CounterWindowRT::updateDateAndTime); TimerCounterUtil::getInstance().clockCounter->start(1000); + QTimer::singleShot(30000, [=](){ + // 定时执行主备一致性监测 + connect(TimerCounterUtil::getInstance().clockCounter, &QTimer::timeout, this, &CounterWindowRT::watchStandbyConsistency); + }); // 重新选择显示多少个计数器 connect(settingForm, &CounterSettingForm::swiftDisplayLoop, this, &CounterWindowRT::updateDeviceWidget); @@ -182,7 +188,7 @@ } for (int i = 0; i < devSet.size(); i++) { - getChannelList(devSet.toList().at(i)); + getChannelList(devSet.values().at(i)); } } } @@ -233,6 +239,13 @@ } updateDeviceWidget(); + +// qDebug() << "loop A: " << ConstCache::getInstance().deviceIdLoopA; +// qDebug() << "loop B: " << ConstCache::getInstance().deviceIdLoopB; + + // 查找主路参考钟在备路计数器的测量通道 + // 查找备路参考钟在主路计数器的测量通道 + findRefAndMeasureChannel(); } } QList CounterWindowRT::getClockNumList() @@ -262,7 +275,8 @@ { // for (int i = 0; i <= 16; i++) { - ConstCache::getInstance().channelMap.remove(QString("%1-%2").arg(deviceId).arg(i)); + QString channelKey = QString("%1-%2").arg(deviceId).arg(i); + ConstCache::getInstance().channelMap.remove(channelKey); } // 将通道绘制在界面上 @@ -273,7 +287,7 @@ QJsonObject channelItem = channelArray.at(i).toObject(); QString channelId = channelItem.value("id").toString(); // 通道ID QString channelCode = channelItem.value("channelCode").toString(); // 通道钟号 - QString channelNo = QString::number(channelItem.value("channelNo").toInt()); // 通道序号 + QString channelNo = QString("%1").arg(channelItem.value("channelNo").toInt(), 2, 10, QLatin1Char('0')); // 通道序号 QString delays = channelItem.value("delays").toString(); // 通道时延值 QString isUse = channelItem.value("isUse").toString(); QString name = channelItem.value("name").toString(); @@ -292,6 +306,14 @@ // 添加到通道的集合中 key=deviceId-channelNo ConstCache::getInstance().channelMap.insert(deviceId + "-" + channelNo, channel); + + if (channelCode.isEmpty() == false && active == true) { + CounterDevice * counterDev = ConstCache::getInstance().deviceMap.value(deviceId); + if (counterDev != nullptr) { + QStringList channelBase; + channelBase << QString::number(counterDev->getIsUse()) << channelCode; + } + } } } } @@ -314,10 +336,12 @@ layoutChannelPage->setMargin(3); // 留出边框的位置 // 左右布局中是垂直布局,用于显示通道 - QVBoxLayout * layoutChannelLeft = new QVBoxLayout(); - QVBoxLayout * layoutChannelRight = new QVBoxLayout(); + QVBoxLayout * layoutChannelLeft = new QVBoxLayout(); // 最左侧显示设备简称 + QVBoxLayout * layoutChannelMain = new QVBoxLayout(); // 中间显示参考通道 + QVBoxLayout * layoutChannelRight = new QVBoxLayout(); // 最右侧显示归算参考通道 字号小一号 layoutChannelLeft->setSpacing(0); + layoutChannelMain->setSpacing(0); layoutChannelRight->setSpacing(0); // 设备标题的Label @@ -330,55 +354,76 @@ // 设备参考通道的Label QLabel * labDevRef = new QLabel(widgetDev); labDevRef->setProperty("labType", QString("devRef%1").arg(count)); // 样式表属性 - labDevRef->setText(QString("REF: %1").arg("1000")); + labDevRef->setText(QString("REF: %1").arg("10000")); labDevRef->setAlignment(Qt::AlignCenter); // 文字居中显示 devRefList.append(labDevRef); + // 设置归算使用的参考通道Label + QLabel * labCompDevRef = new QLabel(widgetDev); + labCompDevRef->setProperty("labType", QString("devCompRef%1").arg(count)); // 样式表属性 + labCompDevRef->setText(QString("%1").arg("主备时差")); + labCompDevRef->setAlignment(Qt::AlignCenter); // 文字居中显示 + devCompRefList.append(labCompDevRef); + if (count == 4) { labDevTitle->setMaximumHeight(80); // 设置固定高度 labDevTitle->setMinimumHeight(80); labDevRef->setMaximumHeight(80); // 设置固定高度 labDevRef->setMinimumHeight(80); + + labCompDevRef->setMaximumHeight(80); // 设置固定高度 + labCompDevRef->setMinimumHeight(80); } else { labDevTitle->setMaximumHeight(60); // 设置固定高度 labDevTitle->setMinimumHeight(60); labDevRef->setMaximumHeight(60); // 设置固定高度 labDevRef->setMinimumHeight(60); + + labCompDevRef->setMaximumHeight(60); // 设置固定高度 + labCompDevRef->setMinimumHeight(60); } // 左侧显示设备简称,右侧显示参考通道名 layoutChannelLeft->addWidget(labDevTitle); - layoutChannelRight->addWidget(labDevRef); + layoutChannelMain->addWidget(labDevRef); + layoutChannelRight->addWidget(labCompDevRef); // 每个计数器显示16个通道 for ( int i = 0; i < 16; i++ ) { QLabelDblClick * labChannelName = new QLabelDblClick(widgetDev); // 通道名 QLabelDblClick * labChannelValue = new QLabelDblClick(widgetDev); // 通道测量值 + QLabelDblClick * labComputeValue = new QLabelDblClick(widgetDev); // 通道归算值 // 默认显示内容 - labChannelName->setText(QString("CH%1").arg(i+1, 2, 10, QLatin1Char('0'))); + labChannelName->setText(QString("%1: 10000").arg(i+1, 2, 10, QLatin1Char('0'))); labChannelValue->setText("0.000000000000"); + labComputeValue->setText(""); // css不支持的样式用代码实现 - labChannelName->setMargin(10); - labChannelValue->setMargin(10); + labChannelName->setMargin(5); + labChannelValue->setMargin(5); labChannelValue->setAlignment(Qt::AlignRight | Qt::AlignVCenter); + labComputeValue->setMargin(5); + labComputeValue->setAlignment(Qt::AlignRight | Qt::AlignVCenter); // 奇偶显示不同的背景色 if (i % 2 == 0) { labChannelName->setProperty("labType", QString("channelNameEven%1").arg(count)); labChannelValue->setProperty("labType", QString("channelValueEven%1").arg(count)); + labComputeValue->setProperty("labType", QString("computeValueEven%1").arg(count)); } else { labChannelName->setProperty("labType", QString("channelNameOdd%1").arg(count)); labChannelValue->setProperty("labType", QString("channelValueOdd%1").arg(count)); + labComputeValue->setProperty("labType", QString("computeValueOdd%1").arg(count)); } layoutChannelLeft->addWidget(labChannelName); - layoutChannelRight->addWidget(labChannelValue); + layoutChannelMain->addWidget(labChannelValue); + layoutChannelRight->addWidget(labComputeValue); // 添加通道名称的双击事件,显示数据和残差图表 connect(labChannelName, &QLabelDblClick::doubleClicked, this, &CounterWindowRT::onChannelNameLabelDblClicked); @@ -386,16 +431,21 @@ channelNameList.append(labChannelName); channelValueList.append(labChannelValue); + computeValueList.append(labComputeValue); // 左下角和右下角的圆角处理 if (i == 15) { labChannelName->setStyleSheet("border-bottom-left-radius: 10px;"); - labChannelValue->setStyleSheet("border-bottom-right-radius: 10px;"); + labComputeValue->setStyleSheet("border-bottom-right-radius: 10px;"); } } layoutChannelPage->addLayout(layoutChannelLeft); + layoutChannelPage->addLayout(layoutChannelMain); layoutChannelPage->addLayout(layoutChannelRight); + layoutChannelPage->setStretch(0, 35); + layoutChannelPage->setStretch(1, 50); + layoutChannelPage->setStretch(2, 15); widgetDev->setLayout(layoutChannelPage); } } @@ -407,13 +457,19 @@ // 参考通道号 int refChNo = messageArray.at(0).toObject().value("data").toObject().value("channelRefNo").toInt(); + CounterDevice * counter = ConstCache::getInstance().deviceMap.value(deviceId); + if (counter == nullptr) { + return; + } + counter->setRefChannelNo(refChNo); + // 根据设备id 从map中取出列索引的值 - int devIdx = ConstCache::getInstance().deviceMap.value(deviceId)->getFormColIndex(); + int devIdx = counter->getFormColIndex(); if (devIdx < devRefList.size()) { // 参考通道的显示 QString refText = devRefList.at(devIdx)->text(); - channelNameList.at(devIdx * 16 + refChNo - 1)->setText(QString("CH%1:%2").arg(refChNo, 2, 10, QLatin1Char('0')).arg(refText.right(refText.length() - 4))); + channelNameList.at(devIdx * 16 + refChNo - 1)->setText(QString("%1:%2").arg(refChNo, 2, 10, QLatin1Char('0')).arg(refText.right(refText.length() - 4))); if (alarmDev.contains(deviceId) == true) { @@ -433,11 +489,11 @@ for (int i = 0; i < messageArray.size(); i++) { QJsonObject channelDataItem = messageArray.at(i).toObject(); - QString channelNo = QString::number(channelDataItem.value("channelNo").toInt()); // 通道序号 + QString channelNo = QString("%1").arg(channelDataItem.value("channelNo").toInt(), 2, 10, QLatin1Char('0')); // 通道序号 channelDataJsonMap.insert(channelNo, channelDataItem); } - CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo)); + CounterChannel * refChanPtr = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo, 2, 10, QLatin1Char('0'))); double refDelay = 0.0; if (refChanPtr != nullptr && refChanPtr->getDelays().isEmpty() == false) { refDelay = refChanPtr->getDelays().toDouble(); @@ -454,11 +510,10 @@ continue; } - CounterChannel * channel = ConstCache::getInstance().channelMap.value(deviceId + "-" + channelNo); // 从map中找到对应的通道 - - if (channelDataJsonMap.contains(channelNo) == true) + CounterChannel * channel = ConstCache::getInstance().channelMap.value(deviceId + "-" + channelNoStr); // 从map中找到对应的通道 + if (channelDataJsonMap.contains(channelNoStr) == true) { - QJsonObject channelDataItem = channelDataJsonMap.value(channelNo); + QJsonObject channelDataItem = channelDataJsonMap.value(channelNoStr); // 通道Label的序号 int channelIdx = devIdx * 16 + channelDataItem.value("channelNo").toInt() - 1; @@ -483,19 +538,20 @@ double valueMinusDelay = channelDataItem.value("data").toObject().value("dataValue").toString().toDouble() - delay * 1E-9 + refDelay * 1E-9; // 设置通道名和测量值的QLabel - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); channelValueList.at(channelIdx)->setText(QString::number(valueMinusDelay, 'f', 12)); channelNameList.at(channelIdx)->setProperty("channelId", channel->getChannelId()); channelNameList.at(channelIdx)->setProperty("deviceId", deviceId); - channelNameList.at(channelIdx)->setProperty("channelNo", channelNo); + channelNameList.at(channelIdx)->setProperty("channelNo", channelNoStr); channelValueList.at(channelIdx)->setProperty("channelId", channel->getChannelId()); channelValueList.at(channelIdx)->setProperty("deviceId", deviceId); - channelValueList.at(channelIdx)->setProperty("channelNo", channelNo); + channelValueList.at(channelIdx)->setProperty("channelNo", channelNoStr); } else { - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg("-")); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg("-")); channelValueList.at(channelIdx)->setText(""); + computeValueList.at(channelIdx)->setText(""); } } else { // 计数器返回的无测量值的通道处理逻辑 @@ -503,6 +559,7 @@ // 没有测量值的通道清空 channelValueList.at(channelIdx)->setText(""); + computeValueList.at(channelIdx)->setText(""); // 当通道启用时显示通道离线 不再判断后台传回来的状态 // 当通道未启用时显示正常状态 @@ -510,12 +567,12 @@ channelNameList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value("channelOffline")); channelValueList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value("channelOffline")); - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg(channel->getChannelCode())); } else { channelNameList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value(channelNameList.at(channelIdx)->property("labType").toString())); channelValueList.at(channelIdx)->setStyleSheet(ConstCache::getInstance().qssConstMap.value(channelValueList.at(channelIdx)->property("labType").toString())); - channelNameList.at(channelIdx)->setText(QString("CH%1:%2").arg(channelNoStr).arg("-")); + channelNameList.at(channelIdx)->setText(QString("%1:%2").arg(channelNoStr).arg("-")); } } } @@ -523,7 +580,7 @@ void CounterWindowRT::updateDeviceAlarm(QJsonArray alarmList) { - qDebug() << alarmList; +// qDebug() << alarmList; for (int i = 0; i < alarmList.size(); i++) { QJsonObject alarmData = alarmList.at(i).toObject(); @@ -532,7 +589,7 @@ QString alarmCode = alarmData.value("alarmCode").toString(); QString status = alarmData.value("status").toString(); - qDebug() << alarmCode << deviceId << channelId; +// qDebug() << alarmCode << deviceId << channelId; // 如果报警状态不是正在报警 status==0 或者报警设备不是计数器 则不处理 if (status != "0" || ConstCache::getInstance().deviceMap.contains(deviceId) == false) @@ -560,6 +617,92 @@ } } +void CounterWindowRT::findRefAndMeasureChannel() +{ + // 查询主路的参考通道的钟编号 + QString masterKey = QString("%1-%2").arg(ConstCache::getInstance().deviceIdLoopA.at(0)).arg("01"); // 暂时固定为01通道 + CounterChannel * refChannelMaster = ConstCache::getInstance().channelMap.value(masterKey); // 主路参考的钟编号 + + // 查询主路参考通道在备路的测量通道 + for (QString channelKey : ConstCache::getInstance().channelMap.keys()) { + QString deviceId = channelKey.split("-")[0]; + if (ConstCache::getInstance().deviceIdLoopB.contains(deviceId)) { + CounterChannel * channel = ConstCache::getInstance().channelMap.value(channelKey); + if (channel->getChannelCode() == refChannelMaster->getChannelCode()) { + QStringList masterInfo; + masterInfo << refChannelMaster->getChannelCode() << deviceId << channel->getChannelId() << channel->getChannelNo(); + ConstCache::getInstance().loopInfos.append(masterInfo); + + break; + } + } + } + + // 查询备路的参考通道钟编号 + QString slaveKey = QString("%1-%2").arg(ConstCache::getInstance().deviceIdLoopB.at(0)).arg("01"); // 暂时固定为01通道 + CounterChannel * refChannelSlave = ConstCache::getInstance().channelMap.value(slaveKey); // 备路参考的钟编号 + + // 查询备路参考通道在主路的测量通道 + for (QString channelKey : ConstCache::getInstance().channelMap.keys()) { + QString deviceId = channelKey.split("-")[0]; + if (ConstCache::getInstance().deviceIdLoopA.contains(deviceId)) { + CounterChannel * channel = ConstCache::getInstance().channelMap.value(channelKey); + if (channel->getChannelCode() == refChannelSlave->getChannelCode()) { + QStringList slaveInfo; + slaveInfo << refChannelSlave->getChannelCode() << deviceId << channel->getChannelId() << channel->getChannelNo(); + ConstCache::getInstance().loopInfos.append(slaveInfo); + + break; + } + } + } + +// qDebug() << ConstCache::getInstance().loopInfos.at(0); +// qDebug() << ConstCache::getInstance().loopInfos.at(1); +// qDebug() << ConstCache::getInstance().channelMap; +} + +double CounterWindowRT::calculateAvgStandbyTimeDiff(QList thisChannel, + QList refChannel, + QList standbyChannel) +{ + double avgTimeDiff = 0.0; + + if (thisChannel.isEmpty() || refChannel.isEmpty() || standbyChannel.isEmpty()) { + return avgTimeDiff; + } + + double sumThis = 0.0; + double avgThis = 0.0; + int countThis = 0; + for (QStringList thisData : thisChannel) { + sumThis += thisData.at(1).toDouble(); + countThis++; + } + avgThis = sumThis / countThis * 1.0; + + double sumRef = 0.0; + double avgRef = 0.0; + int countRef = 0; + for (QStringList refData : refChannel) { + sumRef += refData.at(1).toDouble(); + countRef++; + } + avgRef = sumRef / countRef * 1.0; + + double sumStandby = 0.0; + double avgStandby = 0.0; + int countStandby = 0; + for (QStringList standbyData : standbyChannel) { + sumStandby += standbyData.at(1).toDouble(); + countStandby++; + } + avgStandby = sumStandby / countStandby * 1.0; + + avgTimeDiff = avgThis - avgRef - avgStandby; + return avgTimeDiff; +} + void CounterWindowRT::updateDateAndTime() { QString date = QDate::currentDate().toString("yyyy-MM-dd"); @@ -567,6 +710,171 @@ ui->labTime->setText(date + " " + time); } +void CounterWindowRT::watchStandbyConsistency() +{ + quint8 second = QTime::currentTime().second(); + if (second % SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND == 0) { + qDebug() << "watchStandbyConsistency: " << QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"); + // 1. 遍历所有的主路计数器 + for (QString devAId : ConstCache::getInstance().deviceIdLoopA) { + // 2. 遍历主路计数器的每一个通道(除参考通道外) + for (QString key : ConstCache::getInstance().channelMap.keys()) { + if (key.contains(devAId) == false) { + continue; + } else { + // A当前通道 + CounterChannel * channel = ConstCache::getInstance().channelMap.value(key); + QString channelCode = channel->getChannelCode(); // 钟编号 + QString channelNo = channel->getChannelNo(); // 通道号 + + if (channelNo == "00" || channelNo == "01" || channelCode.isEmpty()) { + continue; + } + + // B备路参考通道在主路的测量通道 + CounterChannel * standbyRefChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(ConstCache::getInstance().loopInfos.at(1).at(1)).arg(ConstCache::getInstance().loopInfos.at(1).at(3))); + + // 3. 获得通道的钟编号、通道号,找到对应钟编号、通道号在备路对应的通道 + // C对应的备路测量通道 + QString standbyKey = ""; + CounterChannel * standbyChannel = nullptr; + if (ConstCache::getInstance().standbyMap.contains(key) == false) { + // 在对路计数器中找 并存入standbyMap + for (QString standbyDevId : ConstCache::getInstance().deviceIdLoopB) { + // 通道号和钟编号都匹配 + standbyChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(standbyDevId).arg(channelNo)); + if (standbyChannel != nullptr && standbyChannel->getChannelCode() == channelCode) { + standbyKey = QString("%1-%2").arg(standbyDevId).arg(channelNo); + ConstCache::getInstance().standbyMap.insert(key, standbyKey); + } + } + } else { + standbyKey = ConstCache::getInstance().standbyMap.value(key); + standbyChannel = ConstCache::getInstance().channelMap.value(standbyKey); + } + + // 4. 取当前通道的最后10个历史数据 channel + QList thisChannelDataList; + if (channel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + thisChannelDataList = channel->getHisData().mid(channel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 5. 取备路参考通道最后10个历史数据 standbyRefChannel + QList standbyRefChannelDataList; + if (standbyRefChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyRefChannelDataList = standbyRefChannel->getHisData().mid(standbyRefChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 6. 取备路计数器对应通道的最后10个历史数据 standbyChannel + QList standbyChannelDataList; + if (standbyChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyChannelDataList = standbyChannel->getHisData().mid(standbyChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 7. 计算当前通道相对备路参考钟的时差 与备路对应通道的时差做差 + if (thisChannelDataList.isEmpty() || standbyChannelDataList.isEmpty()) { + continue; + } + double avgTimeDiff = calculateAvgStandbyTimeDiff(thisChannelDataList, standbyRefChannelDataList, standbyChannelDataList); + + // 8. 显示在界面上 + CounterDevice * devicePtr = ConstCache::getInstance().deviceMap.value(devAId); + if (devicePtr != nullptr && SettingConfig::getInstance().MASTER == devicePtr->getIsUse()) + { + int devIdx = devicePtr->getFormColIndex(); + + // 通道Label的序号 + int channelIdx = devIdx * 16 + channelNo.toInt() - 1; + computeValueList.at(channelIdx)->setText(QString::number(avgTimeDiff * 1E9, 'f', 3)); + } + } + } + } + + // 8. 遍历所有的备路计数器 + for (QString devBId : ConstCache::getInstance().deviceIdLoopB) { + // 2. 遍历主路计数器的每一个通道(除参考通道外) + for (QString key : ConstCache::getInstance().channelMap.keys()) { + if (key.contains(devBId) == false) { + continue; + } else { + // A当前通道 + CounterChannel * channel = ConstCache::getInstance().channelMap.value(key); + QString channelCode = channel->getChannelCode(); // 钟编号 + QString channelNo = channel->getChannelNo(); // 通道号 + + if (channelNo == "00" || channelNo == "01" || channelCode.isEmpty()) { + continue; + } + + // B主路参考通道在主路的测量通道 + CounterChannel * standbyRefChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(ConstCache::getInstance().loopInfos.at(0).at(1)).arg(ConstCache::getInstance().loopInfos.at(0).at(3))); + + // 3. 获得通道的钟编号、通道号,找到对应钟编号、通道号在备路对应的通道 + // C对应的主路测量通道 + QString standbyKey = ""; + CounterChannel * standbyChannel = nullptr; + if (ConstCache::getInstance().standbyMap.contains(key) == false) { + // 在对路计数器中找 并存入standbyMap + for (QString standbyDevId : ConstCache::getInstance().deviceIdLoopA) { + // 通道号和钟编号都匹配 + standbyChannel = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(standbyDevId).arg(channelNo)); + if (standbyChannel != nullptr && standbyChannel->getChannelCode() == channelCode) { + standbyKey = QString("%1-%2").arg(standbyDevId).arg(channelNo); + ConstCache::getInstance().standbyMap.insert(key, standbyKey); + } + } + } else { + standbyKey = ConstCache::getInstance().standbyMap.value(key); + standbyChannel = ConstCache::getInstance().channelMap.value(standbyKey); + } + + // 4. 取当前通道的最后10个历史数据 channel + QList thisChannelDataList; + if (channel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + thisChannelDataList = channel->getHisData().mid(channel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 5. 取主路参考通道最后10个历史数据 standbyRefChannel + QList standbyRefChannelDataList; + if (standbyRefChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyRefChannelDataList = standbyRefChannel->getHisData().mid(standbyRefChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 6. 取主路计数器对应通道的最后10个历史数据 standbyChannel + QList standbyChannelDataList; + if (standbyChannel->getHisData().size() >= SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND) { + standbyChannelDataList = standbyChannel->getHisData().mid(standbyChannel->getHisData().size() - SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND, + SettingConfig::getInstance().STANDBY_CONSISTENCY_SECOND); + } + + // 7. 计算当前通道相对主路参考钟的时差 与主路对应通道的时差做差 + if (thisChannelDataList.isEmpty() || standbyChannelDataList.isEmpty()) { + continue; + } + double avgTimeDiff = calculateAvgStandbyTimeDiff(thisChannelDataList, standbyRefChannelDataList, standbyChannelDataList); + + // 8. 显示在界面上 + CounterDevice * devicePtr = ConstCache::getInstance().deviceMap.value(devBId); + if (devicePtr != nullptr && SettingConfig::getInstance().MASTER == devicePtr->getIsUse()) + { + int devIdx = devicePtr->getFormColIndex(); + + // 通道Label的序号 + int channelIdx = devIdx * 16 + channelNo.toInt() - 1; + computeValueList.at(channelIdx)->setText(QString::number(avgTimeDiff * 1E9, 'f', 3)); + } + } + } + } + } +} + void CounterWindowRT::on_btnMenuSetting_clicked() { settingForm->setWindowModality(Qt::ApplicationModal); @@ -600,8 +908,10 @@ // 将lab列表的数量置0 devTitleList.resize(0); devRefList.resize(0); + devCompRefList.resize(0); channelNameList.resize(0); channelValueList.resize(0); + computeValueList.resize(0); initDevAndChannelForm(SettingConfig::getInstance().DISPLAY_COUNT); } @@ -620,14 +930,20 @@ devTitleList.at(i)->setText(dev->getDeviceName()); // 设备名称 dev->setFormColIndex(i); } + for (int j = 1; j < 16; j++) + { + computeValueList.at(i * 16 + j)->setText("-"); + } } else { devTitleList.at(i)->setText(""); devRefList.at(i)->setText(""); + devCompRefList.at(i)->setText(""); for (int j = 0; j < 16; j++) { channelNameList.at(i * 16 + j)->setText(""); channelValueList.at(i * 16 + j)->setText(""); + computeValueList.at(i * 16 + j)->setText(""); } } } @@ -685,7 +1001,7 @@ // 参考通道 int refChNo = messageArray.at(0).toObject().value("data").toObject().value("channelRefNo").toInt(); - CounterChannel * refChann = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo)); + CounterChannel * refChann = ConstCache::getInstance().channelMap.value(QString("%1-%2").arg(deviceId).arg(refChNo, 2, 10, QLatin1Char('0'))); if (refChann != nullptr) { if (devIdx < devRefList.size()) { @@ -704,7 +1020,7 @@ void CounterWindowRT::onKafkaMessageReceived(QJsonObject message) { qDebug() << message; - std::cout << QString(QJsonDocument(message).toJson(QJsonDocument::Compact)).toStdString() << std::endl; + std::cout << "kafka message received: " << std::endl << QString(QJsonDocument(message).toJson(QJsonDocument::Compact)).toStdString() << std::endl; // 找不到deviceId deviceType operation三个必填项 直接返回 if (message.contains("deviceId") == false || message.contains("operation") == false || message.contains("deviceType") == false) { @@ -732,7 +1048,7 @@ void CounterWindowRT::onAlarmMessageReceived(QJsonObject alarmMsg) { qDebug() << alarmMsg; - std::cout << QString(QJsonDocument(alarmMsg).toJson(QJsonDocument::Compact)).toStdString() << std::endl; + std::cout << "alarm message received: " << std::endl << QString(QJsonDocument(alarmMsg).toJson(QJsonDocument::Compact)).toStdString() << std::endl; QString deviceId = alarmMsg.value("deviceId").toString(); QString channelId = alarmMsg.value("channelId").toString(); diff --git a/CounterRealTime/CounterWindowRT.h b/CounterRealTime/CounterWindowRT.h index b672cfc..b4eea96 100644 --- a/CounterRealTime/CounterWindowRT.h +++ b/CounterRealTime/CounterWindowRT.h @@ -17,10 +17,13 @@ #include "CounterSettingForm.h" #include "common/utils/SettingConfig.h" #include "common/utils/TimerCounterUtil.h" -#include "common/utils/QKafkaConsumer.h" #include "common/HttpRequestController.h" #include "common/HttpServer.h" +#ifdef unix +#include "common/utils/QKafkaConsumer.h" +#endif + QT_BEGIN_NAMESPACE namespace Ui { class CounterWindowRT; } QT_END_NAMESPACE @@ -47,12 +50,17 @@ QVector devTitleList; // 计数器设备标题的QLabel集合 QVector devRefList; // Ref通道 + QVector devCompRefList; // 归算Ref通道 QVector channelNameList; // 通道名的QLabel集合 QVector channelValueList; // 通道测量值的QLabel集合 + QVector computeValueList; // 通道归算值的QLabel集合 HttpRequestController * httpReq; + +#ifdef unix QKafkaConsumer * kafkaConsumer; QKafkaConsumer * alarmMsgConsumer; +#endif QVector alarmDev; QVector offlineDev; @@ -67,9 +75,13 @@ void initDevAndChannelForm(int count); void updateChannelDataForm(QJsonArray messageArray); void updateDeviceAlarm(QJsonArray alarmList); + void findRefAndMeasureChannel(); // 查找主备路的测量参考通道以及各自的测量通道 + double calculateAvgStandbyTimeDiff(QList thisChannel, QList refChannel, QList standbyChannel); + private slots: void updateDateAndTime(); + void watchStandbyConsistency(); int initHttpToken(); diff --git a/CounterRealTime/common/ConstCache.h b/CounterRealTime/common/ConstCache.h index 25a97d4..c5af508 100644 --- a/CounterRealTime/common/ConstCache.h +++ b/CounterRealTime/common/ConstCache.h @@ -31,6 +31,9 @@ QList deviceIdLoopB; // B路计数器对象集合 key=deviceId QMap channelMap; // 通道对象集合 key=deviceId-channelNo + QList loopInfos; // 存储主备路关键信息 参考钟编号;在对路的测量计数器ID;在对路的测量计数器所在通道ID;对路计数器所在的通道号 + QMap standbyMap; // 主路/备路通道的备路/主路对应通道key key=deviceId-channelNo value=deviceId-channelNo + QMap alarmDeviceMap; // 报警设备 QMap alarmChannelMap; // 报警通道 diff --git a/CounterRealTime/common/HttpRequestController.cpp b/CounterRealTime/common/HttpRequestController.cpp index 58ac632..0b8a3e4 100644 --- a/CounterRealTime/common/HttpRequestController.cpp +++ b/CounterRealTime/common/HttpRequestController.cpp @@ -130,7 +130,7 @@ } delete reply; - qDebug() << resultObj; +// qDebug() << resultObj; return resultObj; } @@ -239,7 +239,7 @@ } delete reply; - qDebug() << resultObj; +// qDebug() << "alarm List: " << resultObj; return resultObj; } diff --git a/CounterRealTime/common/common.pri b/CounterRealTime/common/common.pri index aa3f245..9d51c30 100644 --- a/CounterRealTime/common/common.pri +++ b/CounterRealTime/common/common.pri @@ -1,10 +1,7 @@ - SOURCES += $$PWD/utils/SettingConfig.cpp SOURCES += $$PWD/utils/QByteUtil.cpp SOURCES += $$PWD/utils/QSerialPortUtil.cpp SOURCES += $$PWD/utils/QLogUtil.cpp -SOURCES += $$PWD/utils/QKafkaUtil.cpp -SOURCES += $$PWD/utils/QKafkaConsumer.cpp SOURCES += $$PWD/utils/HttpRequestUtil.cpp SOURCES += $$PWD/utils/MD5.cpp SOURCES += $$PWD/LinearRegression.cpp @@ -16,8 +13,6 @@ HEADERS += $$PWD/utils/QByteUtil.h HEADERS += $$PWD/utils/QSerialPortUtil.h HEADERS += $$PWD/utils/QLogUtil.h -HEADERS += $$PWD/utils/QKafkaUtil.h -HEADERS += $$PWD/utils/QKafkaConsumer.h HEADERS += $$PWD/utils/HttpRequestUtil.h HEADERS += $$PWD/utils/DefHead.h HEADERS += $$PWD/utils/MD5.h @@ -25,3 +20,11 @@ HEADERS += $$PWD/HttpRequestController.h HEADERS += $$PWD/HttpServer.h HEADERS += $$PWD/ConstCache.h + +unix { + SOURCES += $$PWD/utils/QKafkaUtil.cpp + SOURCES += $$PWD/utils/QKafkaConsumer.cpp + + HEADERS += $$PWD/utils/QKafkaUtil.h + HEADERS += $$PWD/utils/QKafkaConsumer.h +} diff --git a/CounterRealTime/common/utils/SettingConfig.cpp b/CounterRealTime/common/utils/SettingConfig.cpp index b6c72d7..f94a918 100644 --- a/CounterRealTime/common/utils/SettingConfig.cpp +++ b/CounterRealTime/common/utils/SettingConfig.cpp @@ -51,6 +51,7 @@ PASSWORD = getProperty("client", "password").toString(); SERVER_PORT = getProperty("client", "serverPort").toInt(); CLIENT_TITLE = getProperty("client", "title").toString(); + STANDBY_CONSISTENCY_SECOND = getProperty("client", "standbyConsistencySecond").toUInt(); DEVICE_ALARM_CODES = getProperty("alarm", "deviceAlarmCodes").toString().split(","); CHANNEL_ALARM_CODES = getProperty("alarm", "channelAlarmCodes").toString().split(","); diff --git a/CounterRealTime/common/utils/SettingConfig.h b/CounterRealTime/common/utils/SettingConfig.h index 5b8735a..64e11f3 100644 --- a/CounterRealTime/common/utils/SettingConfig.h +++ b/CounterRealTime/common/utils/SettingConfig.h @@ -75,6 +75,8 @@ // 服务监听端口号 quint16 SERVER_PORT; QString CLIENT_TITLE; + // 主备一致性监测执行频次 + quint8 STANDBY_CONSISTENCY_SECOND; // 设备报警类型 QStringList DEVICE_ALARM_CODES; diff --git a/CounterRealTime/conf/config.ini b/CounterRealTime/conf/config.ini index 1df42d8..56424fe 100644 --- a/CounterRealTime/conf/config.ini +++ b/CounterRealTime/conf/config.ini @@ -28,6 +28,8 @@ displayCount=4 password=MTIzNDU2 serverPort=5905 +title=钟差测量数据采集软件 +standbyConsistencySecond=10 [alarm] deviceAlarmCodes="DEVICE_OFFLINE,DEVICE_ALARM" diff --git a/CounterRealTime/qss/mainClock.css b/CounterRealTime/qss/mainClock.css index b850753..4b7606e 100644 --- a/CounterRealTime/qss/mainClock.css +++ b/CounterRealTime/qss/mainClock.css @@ -39,7 +39,7 @@ font-weight: bold; } QLabel[labType='devTitle4'] { - font-size: 28px; + font-size: 26px; color: #62D8FF; background-color: #1E5A7C; border-top-left-radius: 10px; @@ -58,26 +58,45 @@ } QLabel[labType='devRef4'] { - font-size: 28px; + font-size: 26px; color: #62D8FF; background-color: #1E5A7C; - border-top-right-radius: 10px; +/* border-top-right-radius: 10px;*/ } QLabel[labType='devRef6'] { font-size: 24px; color: #62D8FF; background-color: #1E5A7C; - border-top-right-radius: 10px; +/* border-top-right-radius: 10px;*/ } QLabel[labType='devRef8'] { font-size: 18px; color: #62D8FF; background-color: #1E5A7C; +/* border-top-right-radius: 10px;*/ +} + +QLabel[labType='devCompRef4'] { + font-size: 20px; + color: #62D8FF; + background-color: #1E5A7C; + border-top-right-radius: 10px; +} +QLabel[labType='devCompRef6'] { + font-size: 16px; + color: #62D8FF; + background-color: #1E5A7C; + border-top-right-radius: 10px; +} +QLabel[labType='devCompRef8'] { + font-size: 12px; + color: #62D8FF; + background-color: #1E5A7C; border-top-right-radius: 10px; } QLabel[labType='channelNameEven4'] { - font-size: 28px; + font-size: 26px; color: #62D8FF; background-color: #194B6C; } @@ -93,7 +112,7 @@ } QLabel[labType='channelValueEven4'] { - font-size: 28px; + font-size: 26px; color: #FFFFFF; background-color: #194B6C; } @@ -108,8 +127,24 @@ background-color: #194B6C; } +QLabel[labType='computeValueEven4'] { + font-size: 20px; + color: #00FF1E; + background-color: #194B6C; +} +QLabel[labType='computeValueEven6'] { + font-size: 16px; + color: #00FF1E; + background-color: #194B6C; +} +QLabel[labType='computeValueEven8'] { + font-size: 12px; + color: #00FF1E; + background-color: #194B6C; +} + QLabel[labType='channelNameOdd4'] { - font-size: 28px; + font-size: 26px; color: #62D8FF; background-color: #123553; } @@ -125,7 +160,7 @@ } QLabel[labType='channelValueOdd4'] { - font-size: 28px; + font-size: 26px; color: #FFFFFF; background-color: #123553; } @@ -140,6 +175,22 @@ background-color: #123553; } +QLabel[labType='computeValueOdd4'] { + font-size: 20px; + color: #00FF1E; + background-color: #123553; +} +QLabel[labType='computeValueOdd6'] { + font-size: 16px; + color: #00FF1E; + background-color: #123553; +} +QLabel[labType='computeValueOdd8'] { + font-size: 12px; + color: #00FF1E; + background-color: #123553; +} + QLabel[labType='channelAlarm'] { color: #FFF000; background-color: #9F1919;