diff --git a/CounterAcq/CounterDevice.cpp b/CounterAcq/CounterDevice.cpp index 1aef95a..a6f0bd1 100644 --- a/CounterAcq/CounterDevice.cpp +++ b/CounterAcq/CounterDevice.cpp @@ -2,12 +2,16 @@ #include #include +#include CounterDevice::CounterDevice(QObject *parent) : QObject(parent) { connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &CounterDevice::dataReceivedHandler); + connect(this, &CounterDevice::successDataCalculate, + this, &CounterDevice::afterFramePhase); + // kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); // kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); // kafkaUtil.createProducer(); @@ -35,6 +39,10 @@ { this->devCode = devCode; } +void CounterDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool CounterDevice::isSerialOpen() { @@ -55,7 +63,7 @@ if (CounterProtocolBM::checkFrame(this->dataBuff) == true) { counterData->rawFrame = this->dataBuff; - std::cout << counterData->rawFrame.toStdString() << std::endl; +// std::cout << counterData->rawFrame.toStdString() << std::endl; // ★解析成数据对象 bool parse = CounterProtocolBM::parseMessureData(this->dataBuff, counterData); @@ -63,36 +71,38 @@ // 解析成功 if (parse == true) { + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 补充其他字段 QDateTime now = QDateTime::currentDateTime(); counterData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); counterData->milisecond = now.toMSecsSinceEpoch(); - this->afterFramePhase(counterData); + counterData->devCode = devCode; + + // 3 计算数据ID一样的测量数据的时差值,通道值-参考通道值 + this->pushChannelRawFrame(counterData); } } // 在此处释放内存,不影响后续显示 // 不在此处释放内存则会导致内存持续增加 - // 具体原因不明 delete counterData; } void CounterDevice::afterFramePhase(CounterDataDto * counterData) { - // 1. 清空dataBuff,等待下一帧的数据 - this->dataBuff.clear(); + // 0. 输出到日志文件中 + QString date = counterData->timestamp.mid(0, 10); - // 2. 输出到日志文件中 - QString filePostfix = counterData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; - - // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + // 1. 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; QString content = counterData->timestamp + " " + counterData->rawFrame.left(counterData->rawFrame.size() - COUNTER_FRAME_TAIL.size()); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); - // 2.2 各个通道的clock diff数据 - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + // 2. 各个通道的clock diff数据 + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (counterData->channelId < 10) { chFilename = chFilename.arg(QString("0%1").arg(counterData->channelId)); @@ -100,20 +110,76 @@ { chFilename = chFilename.arg(counterData->channelId); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(counterData->timestamp).arg(counterData->channelClockValue).arg(counterData->frameId); - - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QString channelDataStr = QString("%1 [%2] %3 %4") + .arg(counterData->timestamp) + .arg(counterData->frameId) + .arg(counterData->channelData) + .arg(counterData->channelClockValue); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) { QJsonObject jsonObj = counterData->toJSON(); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); - jsonObj.insert("deviceId", devCode); + jsonObj.insert("deviceId", deviceId); // kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } // 4. 在界面上简单显示相差数据结果 emit this->sendDataToDraw(counterData); } + +void CounterDevice::pushChannelRawFrame(CounterDataDto * counterData) +{ + QString currentFrameId = counterData->frameId; + QString currentChannelId = QString("%1").arg(counterData->channelId); + + if (counterData->channelId == counterData->channelRefId) + { + // 自身是参考通道 + bench.insert(currentFrameId, counterData->channelData); + counterData->channelClockValue = 0; + + emit successDataCalculate(counterData); + + qlonglong thisBench = counterData->channelData; + // 遍历temp,处理之前的临时暂存的队列 + if (hisList.isEmpty() == false) + { + for (int i = 0; i < hisList.size(); i++) + { + CounterDataDto * hisItem = hisList.at(i); + if (hisItem->frameId == currentFrameId) + { + hisItem->channelClockValue = (hisItem->channelData - thisBench) * 10; + + emit successDataCalculate(hisItem); + delete hisItem; + } + } + + hisList.clear(); + } + } else + { + // 自身不是参考通道,减去相同frameId的参考通道值 + if (bench.contains(currentFrameId) == true) + { + // 在参考基准中能找到 + qlonglong currentBench = bench.find(currentFrameId).value(); + counterData->channelClockValue = (counterData->channelData - currentBench) * 10; // 10ps + + emit successDataCalculate(counterData); + } else + { + // 暂存,等收到基准之后再处置 + CounterDataDto * copyPoint = new CounterDataDto(); + + // ★clone一份对象,存入缓存队列 + counterData->clone(copyPoint); + + hisList.append(copyPoint); + } + } +} diff --git a/CounterAcq/CounterDevice.cpp b/CounterAcq/CounterDevice.cpp index 1aef95a..a6f0bd1 100644 --- a/CounterAcq/CounterDevice.cpp +++ b/CounterAcq/CounterDevice.cpp @@ -2,12 +2,16 @@ #include #include +#include CounterDevice::CounterDevice(QObject *parent) : QObject(parent) { connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &CounterDevice::dataReceivedHandler); + connect(this, &CounterDevice::successDataCalculate, + this, &CounterDevice::afterFramePhase); + // kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); // kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); // kafkaUtil.createProducer(); @@ -35,6 +39,10 @@ { this->devCode = devCode; } +void CounterDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool CounterDevice::isSerialOpen() { @@ -55,7 +63,7 @@ if (CounterProtocolBM::checkFrame(this->dataBuff) == true) { counterData->rawFrame = this->dataBuff; - std::cout << counterData->rawFrame.toStdString() << std::endl; +// std::cout << counterData->rawFrame.toStdString() << std::endl; // ★解析成数据对象 bool parse = CounterProtocolBM::parseMessureData(this->dataBuff, counterData); @@ -63,36 +71,38 @@ // 解析成功 if (parse == true) { + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 补充其他字段 QDateTime now = QDateTime::currentDateTime(); counterData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); counterData->milisecond = now.toMSecsSinceEpoch(); - this->afterFramePhase(counterData); + counterData->devCode = devCode; + + // 3 计算数据ID一样的测量数据的时差值,通道值-参考通道值 + this->pushChannelRawFrame(counterData); } } // 在此处释放内存,不影响后续显示 // 不在此处释放内存则会导致内存持续增加 - // 具体原因不明 delete counterData; } void CounterDevice::afterFramePhase(CounterDataDto * counterData) { - // 1. 清空dataBuff,等待下一帧的数据 - this->dataBuff.clear(); + // 0. 输出到日志文件中 + QString date = counterData->timestamp.mid(0, 10); - // 2. 输出到日志文件中 - QString filePostfix = counterData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; - - // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + // 1. 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; QString content = counterData->timestamp + " " + counterData->rawFrame.left(counterData->rawFrame.size() - COUNTER_FRAME_TAIL.size()); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); - // 2.2 各个通道的clock diff数据 - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + // 2. 各个通道的clock diff数据 + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (counterData->channelId < 10) { chFilename = chFilename.arg(QString("0%1").arg(counterData->channelId)); @@ -100,20 +110,76 @@ { chFilename = chFilename.arg(counterData->channelId); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(counterData->timestamp).arg(counterData->channelClockValue).arg(counterData->frameId); - - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QString channelDataStr = QString("%1 [%2] %3 %4") + .arg(counterData->timestamp) + .arg(counterData->frameId) + .arg(counterData->channelData) + .arg(counterData->channelClockValue); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) { QJsonObject jsonObj = counterData->toJSON(); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); - jsonObj.insert("deviceId", devCode); + jsonObj.insert("deviceId", deviceId); // kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } // 4. 在界面上简单显示相差数据结果 emit this->sendDataToDraw(counterData); } + +void CounterDevice::pushChannelRawFrame(CounterDataDto * counterData) +{ + QString currentFrameId = counterData->frameId; + QString currentChannelId = QString("%1").arg(counterData->channelId); + + if (counterData->channelId == counterData->channelRefId) + { + // 自身是参考通道 + bench.insert(currentFrameId, counterData->channelData); + counterData->channelClockValue = 0; + + emit successDataCalculate(counterData); + + qlonglong thisBench = counterData->channelData; + // 遍历temp,处理之前的临时暂存的队列 + if (hisList.isEmpty() == false) + { + for (int i = 0; i < hisList.size(); i++) + { + CounterDataDto * hisItem = hisList.at(i); + if (hisItem->frameId == currentFrameId) + { + hisItem->channelClockValue = (hisItem->channelData - thisBench) * 10; + + emit successDataCalculate(hisItem); + delete hisItem; + } + } + + hisList.clear(); + } + } else + { + // 自身不是参考通道,减去相同frameId的参考通道值 + if (bench.contains(currentFrameId) == true) + { + // 在参考基准中能找到 + qlonglong currentBench = bench.find(currentFrameId).value(); + counterData->channelClockValue = (counterData->channelData - currentBench) * 10; // 10ps + + emit successDataCalculate(counterData); + } else + { + // 暂存,等收到基准之后再处置 + CounterDataDto * copyPoint = new CounterDataDto(); + + // ★clone一份对象,存入缓存队列 + counterData->clone(copyPoint); + + hisList.append(copyPoint); + } + } +} diff --git a/CounterAcq/CounterDevice.h b/CounterAcq/CounterDevice.h index 3572d69..b15e44f 100644 --- a/CounterAcq/CounterDevice.h +++ b/CounterAcq/CounterDevice.h @@ -19,16 +19,16 @@ void initSerialPort(); - void afterFramePhase(CounterDataDto * counterData); - void setComName(QString comName); void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; @@ -37,11 +37,18 @@ // QKafkaUtil kafkaUtil; QByteArray dataBuff; + QMap bench; + QList hisList; + + void pushChannelRawFrame(CounterDataDto * counterData); + signals: void sendDataToDraw(CounterDataDto * counterData); + void successDataCalculate(CounterDataDto * counterData); public slots: void dataReceivedHandler(QByteArray data); + void afterFramePhase(CounterDataDto * counterData); }; #endif // COUNTERDEVICE_H diff --git a/CounterAcq/CounterDevice.cpp b/CounterAcq/CounterDevice.cpp index 1aef95a..a6f0bd1 100644 --- a/CounterAcq/CounterDevice.cpp +++ b/CounterAcq/CounterDevice.cpp @@ -2,12 +2,16 @@ #include #include +#include CounterDevice::CounterDevice(QObject *parent) : QObject(parent) { connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &CounterDevice::dataReceivedHandler); + connect(this, &CounterDevice::successDataCalculate, + this, &CounterDevice::afterFramePhase); + // kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); // kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); // kafkaUtil.createProducer(); @@ -35,6 +39,10 @@ { this->devCode = devCode; } +void CounterDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool CounterDevice::isSerialOpen() { @@ -55,7 +63,7 @@ if (CounterProtocolBM::checkFrame(this->dataBuff) == true) { counterData->rawFrame = this->dataBuff; - std::cout << counterData->rawFrame.toStdString() << std::endl; +// std::cout << counterData->rawFrame.toStdString() << std::endl; // ★解析成数据对象 bool parse = CounterProtocolBM::parseMessureData(this->dataBuff, counterData); @@ -63,36 +71,38 @@ // 解析成功 if (parse == true) { + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 补充其他字段 QDateTime now = QDateTime::currentDateTime(); counterData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); counterData->milisecond = now.toMSecsSinceEpoch(); - this->afterFramePhase(counterData); + counterData->devCode = devCode; + + // 3 计算数据ID一样的测量数据的时差值,通道值-参考通道值 + this->pushChannelRawFrame(counterData); } } // 在此处释放内存,不影响后续显示 // 不在此处释放内存则会导致内存持续增加 - // 具体原因不明 delete counterData; } void CounterDevice::afterFramePhase(CounterDataDto * counterData) { - // 1. 清空dataBuff,等待下一帧的数据 - this->dataBuff.clear(); + // 0. 输出到日志文件中 + QString date = counterData->timestamp.mid(0, 10); - // 2. 输出到日志文件中 - QString filePostfix = counterData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; - - // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + // 1. 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; QString content = counterData->timestamp + " " + counterData->rawFrame.left(counterData->rawFrame.size() - COUNTER_FRAME_TAIL.size()); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); - // 2.2 各个通道的clock diff数据 - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + // 2. 各个通道的clock diff数据 + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (counterData->channelId < 10) { chFilename = chFilename.arg(QString("0%1").arg(counterData->channelId)); @@ -100,20 +110,76 @@ { chFilename = chFilename.arg(counterData->channelId); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(counterData->timestamp).arg(counterData->channelClockValue).arg(counterData->frameId); - - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QString channelDataStr = QString("%1 [%2] %3 %4") + .arg(counterData->timestamp) + .arg(counterData->frameId) + .arg(counterData->channelData) + .arg(counterData->channelClockValue); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) { QJsonObject jsonObj = counterData->toJSON(); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); - jsonObj.insert("deviceId", devCode); + jsonObj.insert("deviceId", deviceId); // kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } // 4. 在界面上简单显示相差数据结果 emit this->sendDataToDraw(counterData); } + +void CounterDevice::pushChannelRawFrame(CounterDataDto * counterData) +{ + QString currentFrameId = counterData->frameId; + QString currentChannelId = QString("%1").arg(counterData->channelId); + + if (counterData->channelId == counterData->channelRefId) + { + // 自身是参考通道 + bench.insert(currentFrameId, counterData->channelData); + counterData->channelClockValue = 0; + + emit successDataCalculate(counterData); + + qlonglong thisBench = counterData->channelData; + // 遍历temp,处理之前的临时暂存的队列 + if (hisList.isEmpty() == false) + { + for (int i = 0; i < hisList.size(); i++) + { + CounterDataDto * hisItem = hisList.at(i); + if (hisItem->frameId == currentFrameId) + { + hisItem->channelClockValue = (hisItem->channelData - thisBench) * 10; + + emit successDataCalculate(hisItem); + delete hisItem; + } + } + + hisList.clear(); + } + } else + { + // 自身不是参考通道,减去相同frameId的参考通道值 + if (bench.contains(currentFrameId) == true) + { + // 在参考基准中能找到 + qlonglong currentBench = bench.find(currentFrameId).value(); + counterData->channelClockValue = (counterData->channelData - currentBench) * 10; // 10ps + + emit successDataCalculate(counterData); + } else + { + // 暂存,等收到基准之后再处置 + CounterDataDto * copyPoint = new CounterDataDto(); + + // ★clone一份对象,存入缓存队列 + counterData->clone(copyPoint); + + hisList.append(copyPoint); + } + } +} diff --git a/CounterAcq/CounterDevice.h b/CounterAcq/CounterDevice.h index 3572d69..b15e44f 100644 --- a/CounterAcq/CounterDevice.h +++ b/CounterAcq/CounterDevice.h @@ -19,16 +19,16 @@ void initSerialPort(); - void afterFramePhase(CounterDataDto * counterData); - void setComName(QString comName); void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; @@ -37,11 +37,18 @@ // QKafkaUtil kafkaUtil; QByteArray dataBuff; + QMap bench; + QList hisList; + + void pushChannelRawFrame(CounterDataDto * counterData); + signals: void sendDataToDraw(CounterDataDto * counterData); + void successDataCalculate(CounterDataDto * counterData); public slots: void dataReceivedHandler(QByteArray data); + void afterFramePhase(CounterDataDto * counterData); }; #endif // COUNTERDEVICE_H diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 31d43fd..f8278f6 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -5,12 +5,12 @@ #include #include #include +#include +#include #include -#include -#include #include -#include #include +#include CounterWindow::CounterWindow(QWidget *parent) : QWidget(parent), @@ -18,56 +18,74 @@ { ui->setupUi(this); + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), 700); + resize(screenRect.width(), screenRect.height()); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); - - for (int i = 0; i < comDevList.size(); i++) - { - CounterDevice * device = new CounterDevice(this); - - // - connect(device, &CounterDevice::sendDataToDraw, - this, &CounterWindow::drawCounterDataOnPage); - - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); - - device->setDevCode(devCodeList.at(i)); - - this->deviceList.append(device); - -// device->initSerialPort(); -// device->startWork(); - } - - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget = new QWidget(this->ui->stackedWidget); - ui->stackedWidget->addWidget(devWidget); - devWidgetList.append(devWidget); - - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); httpReq = new HttpRequestController(this); - QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, - SettingConfig::getInstance().APP_KEY); - if (response.find("code")->toInt() == 200) + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - httpReq->initDictDeviceType(); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - httpReq->initDeviceList(); + QApplication::exit(0); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); + + // 3. 获取计数器设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); + + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i =0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); + + CounterDevice * device = new CounterDevice(this); + deviceList.append(device); + + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &CounterDevice::sendDataToDraw, + this, &CounterWindow::drawCounterDataOnPage); + + device->initSerialPort(); + + QThread::msleep(200); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } -// timer = new QTimer(this); -// timer->start(1000 * 10); + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } CounterWindow::~CounterWindow() @@ -75,110 +93,153 @@ delete ui; } -void CounterWindow::generateWidgetForDevice(QString devCode, int index) +void CounterWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(75); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(75); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * refChLabel = new QLabel(); + refChLabel->setText("参考通道"); + refChLabel->setFont(labelFont); + refChLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(refChLabel); + QLineEdit * refChValue = new QLineEdit(); + refChValue->setFixedWidth(60); + refChValue->setFont(labelFont); + vbox->addWidget(refChValue); + + QLabel * loadLabel = new QLabel(); + loadLabel->setText("负载"); + loadLabel->setFont(labelFont); + loadLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(loadLabel); + QLineEdit * loadValue = new QLineEdit(); + loadValue->setFixedWidth(60); + loadValue->setFont(labelFont); + vbox->addWidget(loadValue); + + QLabel * levelLabel = new QLabel(); + levelLabel->setText("触发电平"); + levelLabel->setFont(labelFont); + levelLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(levelLabel); + QLineEdit * levelValue = new QLineEdit(); + levelValue->setFixedWidth(60); + levelValue->setFont(labelFont); + vbox->addWidget(levelValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,clock").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } void CounterWindow::drawCounterDataOnPage(CounterDataDto * counterData) { // 1. 判断数据属于哪个设备,显示在不同的widget上 +// qDebug() << counterData->toJSON() << counterData->devCode << "---" << counterData->frameId; - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - QList row; - QStandardItem * itemTm = 0; - QStandardItem * itemData = 0; - itemTm = new QStandardItem(QString("%1").arg(counterData->timestamp.mid(11, 12))); - itemData = new QStandardItem(QString("%1").arg(counterData->channelData)); + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - row.append(itemTm); - row.append(itemData); - - QStandardItemModel * model; - model = devChannels.at(counterData->channelId - 1); - if (model->rowCount() >= 20) + // 如果不是当前设备的帧,直接返回 + if (counterData->devCode != currentDevCode) { - model->removeRows(0, model->rowCount()); + return; } - model->insertRow(0, row); + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(counterData->channelId); + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(counterData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 ps").arg(counterData->channelClockValue)); + ((QLineEdit *)channelBox->children().at(6))->setText(counterData->frameId); + ((QLineEdit *)channelBox->children().at(8))->setText(QString("%1").arg(counterData->channelRefId)); + ((QLineEdit *)channelBox->children().at(10))->setText(QString("%1 Ω").arg(counterData->load == 1 ? "1M" : "50")); + ((QLineEdit *)channelBox->children().at(12))->setText(QString("%1 V").arg(counterData->level)); + ((QLabel *)channelBox->children().at(13))->setText(counterData->channelActive == 1 ? "有效" : "无效"); +} -// for (int i = 0; i < counterData->channelData.size(); i++) -// { -// if (counterData->channelActive.at(i).toInt() == 1) -// { -// QList row; -// QStandardItem * item = 0; -// QStandardItem * item2 = 0; -// item = new QStandardItem(QString("%1").arg(counterData->timestamp.mid(11, 12))); -// item2 = new QStandardItem(QString("%1").arg(counterData->channelData.at(i))); +int CounterWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int CounterWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject CounterWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("计数器"); + return response; +} -// row.append(item); -// row.append(item2); +void CounterWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} -// QStandardItemModel * model; -// model = devChannels.at(i); -// if (model->rowCount() >= 60) -// { -// model->removeRows(0, model->rowCount()); -// } - -// model->insertRow(0, row); -// } -// } +void CounterWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); } diff --git a/CounterAcq/CounterDevice.cpp b/CounterAcq/CounterDevice.cpp index 1aef95a..a6f0bd1 100644 --- a/CounterAcq/CounterDevice.cpp +++ b/CounterAcq/CounterDevice.cpp @@ -2,12 +2,16 @@ #include #include +#include CounterDevice::CounterDevice(QObject *parent) : QObject(parent) { connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &CounterDevice::dataReceivedHandler); + connect(this, &CounterDevice::successDataCalculate, + this, &CounterDevice::afterFramePhase); + // kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); // kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); // kafkaUtil.createProducer(); @@ -35,6 +39,10 @@ { this->devCode = devCode; } +void CounterDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool CounterDevice::isSerialOpen() { @@ -55,7 +63,7 @@ if (CounterProtocolBM::checkFrame(this->dataBuff) == true) { counterData->rawFrame = this->dataBuff; - std::cout << counterData->rawFrame.toStdString() << std::endl; +// std::cout << counterData->rawFrame.toStdString() << std::endl; // ★解析成数据对象 bool parse = CounterProtocolBM::parseMessureData(this->dataBuff, counterData); @@ -63,36 +71,38 @@ // 解析成功 if (parse == true) { + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 补充其他字段 QDateTime now = QDateTime::currentDateTime(); counterData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); counterData->milisecond = now.toMSecsSinceEpoch(); - this->afterFramePhase(counterData); + counterData->devCode = devCode; + + // 3 计算数据ID一样的测量数据的时差值,通道值-参考通道值 + this->pushChannelRawFrame(counterData); } } // 在此处释放内存,不影响后续显示 // 不在此处释放内存则会导致内存持续增加 - // 具体原因不明 delete counterData; } void CounterDevice::afterFramePhase(CounterDataDto * counterData) { - // 1. 清空dataBuff,等待下一帧的数据 - this->dataBuff.clear(); + // 0. 输出到日志文件中 + QString date = counterData->timestamp.mid(0, 10); - // 2. 输出到日志文件中 - QString filePostfix = counterData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; - - // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + // 1. 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; QString content = counterData->timestamp + " " + counterData->rawFrame.left(counterData->rawFrame.size() - COUNTER_FRAME_TAIL.size()); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); - // 2.2 各个通道的clock diff数据 - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + // 2. 各个通道的clock diff数据 + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (counterData->channelId < 10) { chFilename = chFilename.arg(QString("0%1").arg(counterData->channelId)); @@ -100,20 +110,76 @@ { chFilename = chFilename.arg(counterData->channelId); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(counterData->timestamp).arg(counterData->channelClockValue).arg(counterData->frameId); - - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QString channelDataStr = QString("%1 [%2] %3 %4") + .arg(counterData->timestamp) + .arg(counterData->frameId) + .arg(counterData->channelData) + .arg(counterData->channelClockValue); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) { QJsonObject jsonObj = counterData->toJSON(); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); - jsonObj.insert("deviceId", devCode); + jsonObj.insert("deviceId", deviceId); // kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } // 4. 在界面上简单显示相差数据结果 emit this->sendDataToDraw(counterData); } + +void CounterDevice::pushChannelRawFrame(CounterDataDto * counterData) +{ + QString currentFrameId = counterData->frameId; + QString currentChannelId = QString("%1").arg(counterData->channelId); + + if (counterData->channelId == counterData->channelRefId) + { + // 自身是参考通道 + bench.insert(currentFrameId, counterData->channelData); + counterData->channelClockValue = 0; + + emit successDataCalculate(counterData); + + qlonglong thisBench = counterData->channelData; + // 遍历temp,处理之前的临时暂存的队列 + if (hisList.isEmpty() == false) + { + for (int i = 0; i < hisList.size(); i++) + { + CounterDataDto * hisItem = hisList.at(i); + if (hisItem->frameId == currentFrameId) + { + hisItem->channelClockValue = (hisItem->channelData - thisBench) * 10; + + emit successDataCalculate(hisItem); + delete hisItem; + } + } + + hisList.clear(); + } + } else + { + // 自身不是参考通道,减去相同frameId的参考通道值 + if (bench.contains(currentFrameId) == true) + { + // 在参考基准中能找到 + qlonglong currentBench = bench.find(currentFrameId).value(); + counterData->channelClockValue = (counterData->channelData - currentBench) * 10; // 10ps + + emit successDataCalculate(counterData); + } else + { + // 暂存,等收到基准之后再处置 + CounterDataDto * copyPoint = new CounterDataDto(); + + // ★clone一份对象,存入缓存队列 + counterData->clone(copyPoint); + + hisList.append(copyPoint); + } + } +} diff --git a/CounterAcq/CounterDevice.h b/CounterAcq/CounterDevice.h index 3572d69..b15e44f 100644 --- a/CounterAcq/CounterDevice.h +++ b/CounterAcq/CounterDevice.h @@ -19,16 +19,16 @@ void initSerialPort(); - void afterFramePhase(CounterDataDto * counterData); - void setComName(QString comName); void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; @@ -37,11 +37,18 @@ // QKafkaUtil kafkaUtil; QByteArray dataBuff; + QMap bench; + QList hisList; + + void pushChannelRawFrame(CounterDataDto * counterData); + signals: void sendDataToDraw(CounterDataDto * counterData); + void successDataCalculate(CounterDataDto * counterData); public slots: void dataReceivedHandler(QByteArray data); + void afterFramePhase(CounterDataDto * counterData); }; #endif // COUNTERDEVICE_H diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 31d43fd..f8278f6 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -5,12 +5,12 @@ #include #include #include +#include +#include #include -#include -#include #include -#include #include +#include CounterWindow::CounterWindow(QWidget *parent) : QWidget(parent), @@ -18,56 +18,74 @@ { ui->setupUi(this); + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), 700); + resize(screenRect.width(), screenRect.height()); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); - - for (int i = 0; i < comDevList.size(); i++) - { - CounterDevice * device = new CounterDevice(this); - - // - connect(device, &CounterDevice::sendDataToDraw, - this, &CounterWindow::drawCounterDataOnPage); - - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); - - device->setDevCode(devCodeList.at(i)); - - this->deviceList.append(device); - -// device->initSerialPort(); -// device->startWork(); - } - - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget = new QWidget(this->ui->stackedWidget); - ui->stackedWidget->addWidget(devWidget); - devWidgetList.append(devWidget); - - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); httpReq = new HttpRequestController(this); - QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, - SettingConfig::getInstance().APP_KEY); - if (response.find("code")->toInt() == 200) + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - httpReq->initDictDeviceType(); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - httpReq->initDeviceList(); + QApplication::exit(0); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); + + // 3. 获取计数器设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); + + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i =0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); + + CounterDevice * device = new CounterDevice(this); + deviceList.append(device); + + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &CounterDevice::sendDataToDraw, + this, &CounterWindow::drawCounterDataOnPage); + + device->initSerialPort(); + + QThread::msleep(200); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } -// timer = new QTimer(this); -// timer->start(1000 * 10); + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } CounterWindow::~CounterWindow() @@ -75,110 +93,153 @@ delete ui; } -void CounterWindow::generateWidgetForDevice(QString devCode, int index) +void CounterWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(75); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(75); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * refChLabel = new QLabel(); + refChLabel->setText("参考通道"); + refChLabel->setFont(labelFont); + refChLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(refChLabel); + QLineEdit * refChValue = new QLineEdit(); + refChValue->setFixedWidth(60); + refChValue->setFont(labelFont); + vbox->addWidget(refChValue); + + QLabel * loadLabel = new QLabel(); + loadLabel->setText("负载"); + loadLabel->setFont(labelFont); + loadLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(loadLabel); + QLineEdit * loadValue = new QLineEdit(); + loadValue->setFixedWidth(60); + loadValue->setFont(labelFont); + vbox->addWidget(loadValue); + + QLabel * levelLabel = new QLabel(); + levelLabel->setText("触发电平"); + levelLabel->setFont(labelFont); + levelLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(levelLabel); + QLineEdit * levelValue = new QLineEdit(); + levelValue->setFixedWidth(60); + levelValue->setFont(labelFont); + vbox->addWidget(levelValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,clock").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } void CounterWindow::drawCounterDataOnPage(CounterDataDto * counterData) { // 1. 判断数据属于哪个设备,显示在不同的widget上 +// qDebug() << counterData->toJSON() << counterData->devCode << "---" << counterData->frameId; - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - QList row; - QStandardItem * itemTm = 0; - QStandardItem * itemData = 0; - itemTm = new QStandardItem(QString("%1").arg(counterData->timestamp.mid(11, 12))); - itemData = new QStandardItem(QString("%1").arg(counterData->channelData)); + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - row.append(itemTm); - row.append(itemData); - - QStandardItemModel * model; - model = devChannels.at(counterData->channelId - 1); - if (model->rowCount() >= 20) + // 如果不是当前设备的帧,直接返回 + if (counterData->devCode != currentDevCode) { - model->removeRows(0, model->rowCount()); + return; } - model->insertRow(0, row); + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(counterData->channelId); + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(counterData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 ps").arg(counterData->channelClockValue)); + ((QLineEdit *)channelBox->children().at(6))->setText(counterData->frameId); + ((QLineEdit *)channelBox->children().at(8))->setText(QString("%1").arg(counterData->channelRefId)); + ((QLineEdit *)channelBox->children().at(10))->setText(QString("%1 Ω").arg(counterData->load == 1 ? "1M" : "50")); + ((QLineEdit *)channelBox->children().at(12))->setText(QString("%1 V").arg(counterData->level)); + ((QLabel *)channelBox->children().at(13))->setText(counterData->channelActive == 1 ? "有效" : "无效"); +} -// for (int i = 0; i < counterData->channelData.size(); i++) -// { -// if (counterData->channelActive.at(i).toInt() == 1) -// { -// QList row; -// QStandardItem * item = 0; -// QStandardItem * item2 = 0; -// item = new QStandardItem(QString("%1").arg(counterData->timestamp.mid(11, 12))); -// item2 = new QStandardItem(QString("%1").arg(counterData->channelData.at(i))); +int CounterWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int CounterWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject CounterWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("计数器"); + return response; +} -// row.append(item); -// row.append(item2); +void CounterWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} -// QStandardItemModel * model; -// model = devChannels.at(i); -// if (model->rowCount() >= 60) -// { -// model->removeRows(0, model->rowCount()); -// } - -// model->insertRow(0, row); -// } -// } +void CounterWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); } diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 88ec496..3273433 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -2,7 +2,9 @@ #define COUNTERWINDOW_H #include +#include #include +#include #include "common/utils/SettingConfig.h" //#include "common/utils/QKafkaUtil.h" @@ -26,18 +28,24 @@ public slots: void drawCounterDataOnPage(CounterDataDto * counterData); +private slots: + void on_exitButt_clicked(); + + void on_minButt_clicked(); + private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + Ui::CounterWindow *ui; QTimer * timer; HttpRequestController * httpReq; - QList devWidgetList; - QList deviceList; - QList> tableModelList; - void generateWidgetForDevice(QString devCode, int index); + void generateWidgetForDevice(); }; #endif // COUNTERWINDOW_H diff --git a/CounterAcq/CounterDevice.cpp b/CounterAcq/CounterDevice.cpp index 1aef95a..a6f0bd1 100644 --- a/CounterAcq/CounterDevice.cpp +++ b/CounterAcq/CounterDevice.cpp @@ -2,12 +2,16 @@ #include #include +#include CounterDevice::CounterDevice(QObject *parent) : QObject(parent) { connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &CounterDevice::dataReceivedHandler); + connect(this, &CounterDevice::successDataCalculate, + this, &CounterDevice::afterFramePhase); + // kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); // kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); // kafkaUtil.createProducer(); @@ -35,6 +39,10 @@ { this->devCode = devCode; } +void CounterDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool CounterDevice::isSerialOpen() { @@ -55,7 +63,7 @@ if (CounterProtocolBM::checkFrame(this->dataBuff) == true) { counterData->rawFrame = this->dataBuff; - std::cout << counterData->rawFrame.toStdString() << std::endl; +// std::cout << counterData->rawFrame.toStdString() << std::endl; // ★解析成数据对象 bool parse = CounterProtocolBM::parseMessureData(this->dataBuff, counterData); @@ -63,36 +71,38 @@ // 解析成功 if (parse == true) { + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 补充其他字段 QDateTime now = QDateTime::currentDateTime(); counterData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); counterData->milisecond = now.toMSecsSinceEpoch(); - this->afterFramePhase(counterData); + counterData->devCode = devCode; + + // 3 计算数据ID一样的测量数据的时差值,通道值-参考通道值 + this->pushChannelRawFrame(counterData); } } // 在此处释放内存,不影响后续显示 // 不在此处释放内存则会导致内存持续增加 - // 具体原因不明 delete counterData; } void CounterDevice::afterFramePhase(CounterDataDto * counterData) { - // 1. 清空dataBuff,等待下一帧的数据 - this->dataBuff.clear(); + // 0. 输出到日志文件中 + QString date = counterData->timestamp.mid(0, 10); - // 2. 输出到日志文件中 - QString filePostfix = counterData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; - - // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + // 1. 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; QString content = counterData->timestamp + " " + counterData->rawFrame.left(counterData->rawFrame.size() - COUNTER_FRAME_TAIL.size()); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); - // 2.2 各个通道的clock diff数据 - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + // 2. 各个通道的clock diff数据 + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (counterData->channelId < 10) { chFilename = chFilename.arg(QString("0%1").arg(counterData->channelId)); @@ -100,20 +110,76 @@ { chFilename = chFilename.arg(counterData->channelId); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(counterData->timestamp).arg(counterData->channelClockValue).arg(counterData->frameId); - - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QString channelDataStr = QString("%1 [%2] %3 %4") + .arg(counterData->timestamp) + .arg(counterData->frameId) + .arg(counterData->channelData) + .arg(counterData->channelClockValue); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) { QJsonObject jsonObj = counterData->toJSON(); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); - jsonObj.insert("deviceId", devCode); + jsonObj.insert("deviceId", deviceId); // kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } // 4. 在界面上简单显示相差数据结果 emit this->sendDataToDraw(counterData); } + +void CounterDevice::pushChannelRawFrame(CounterDataDto * counterData) +{ + QString currentFrameId = counterData->frameId; + QString currentChannelId = QString("%1").arg(counterData->channelId); + + if (counterData->channelId == counterData->channelRefId) + { + // 自身是参考通道 + bench.insert(currentFrameId, counterData->channelData); + counterData->channelClockValue = 0; + + emit successDataCalculate(counterData); + + qlonglong thisBench = counterData->channelData; + // 遍历temp,处理之前的临时暂存的队列 + if (hisList.isEmpty() == false) + { + for (int i = 0; i < hisList.size(); i++) + { + CounterDataDto * hisItem = hisList.at(i); + if (hisItem->frameId == currentFrameId) + { + hisItem->channelClockValue = (hisItem->channelData - thisBench) * 10; + + emit successDataCalculate(hisItem); + delete hisItem; + } + } + + hisList.clear(); + } + } else + { + // 自身不是参考通道,减去相同frameId的参考通道值 + if (bench.contains(currentFrameId) == true) + { + // 在参考基准中能找到 + qlonglong currentBench = bench.find(currentFrameId).value(); + counterData->channelClockValue = (counterData->channelData - currentBench) * 10; // 10ps + + emit successDataCalculate(counterData); + } else + { + // 暂存,等收到基准之后再处置 + CounterDataDto * copyPoint = new CounterDataDto(); + + // ★clone一份对象,存入缓存队列 + counterData->clone(copyPoint); + + hisList.append(copyPoint); + } + } +} diff --git a/CounterAcq/CounterDevice.h b/CounterAcq/CounterDevice.h index 3572d69..b15e44f 100644 --- a/CounterAcq/CounterDevice.h +++ b/CounterAcq/CounterDevice.h @@ -19,16 +19,16 @@ void initSerialPort(); - void afterFramePhase(CounterDataDto * counterData); - void setComName(QString comName); void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; @@ -37,11 +37,18 @@ // QKafkaUtil kafkaUtil; QByteArray dataBuff; + QMap bench; + QList hisList; + + void pushChannelRawFrame(CounterDataDto * counterData); + signals: void sendDataToDraw(CounterDataDto * counterData); + void successDataCalculate(CounterDataDto * counterData); public slots: void dataReceivedHandler(QByteArray data); + void afterFramePhase(CounterDataDto * counterData); }; #endif // COUNTERDEVICE_H diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 31d43fd..f8278f6 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -5,12 +5,12 @@ #include #include #include +#include +#include #include -#include -#include #include -#include #include +#include CounterWindow::CounterWindow(QWidget *parent) : QWidget(parent), @@ -18,56 +18,74 @@ { ui->setupUi(this); + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), 700); + resize(screenRect.width(), screenRect.height()); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); - - for (int i = 0; i < comDevList.size(); i++) - { - CounterDevice * device = new CounterDevice(this); - - // - connect(device, &CounterDevice::sendDataToDraw, - this, &CounterWindow::drawCounterDataOnPage); - - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); - - device->setDevCode(devCodeList.at(i)); - - this->deviceList.append(device); - -// device->initSerialPort(); -// device->startWork(); - } - - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget = new QWidget(this->ui->stackedWidget); - ui->stackedWidget->addWidget(devWidget); - devWidgetList.append(devWidget); - - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); httpReq = new HttpRequestController(this); - QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, - SettingConfig::getInstance().APP_KEY); - if (response.find("code")->toInt() == 200) + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - httpReq->initDictDeviceType(); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - httpReq->initDeviceList(); + QApplication::exit(0); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); + + // 3. 获取计数器设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); + + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i =0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); + + CounterDevice * device = new CounterDevice(this); + deviceList.append(device); + + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &CounterDevice::sendDataToDraw, + this, &CounterWindow::drawCounterDataOnPage); + + device->initSerialPort(); + + QThread::msleep(200); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } -// timer = new QTimer(this); -// timer->start(1000 * 10); + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } CounterWindow::~CounterWindow() @@ -75,110 +93,153 @@ delete ui; } -void CounterWindow::generateWidgetForDevice(QString devCode, int index) +void CounterWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(75); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(75); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * refChLabel = new QLabel(); + refChLabel->setText("参考通道"); + refChLabel->setFont(labelFont); + refChLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(refChLabel); + QLineEdit * refChValue = new QLineEdit(); + refChValue->setFixedWidth(60); + refChValue->setFont(labelFont); + vbox->addWidget(refChValue); + + QLabel * loadLabel = new QLabel(); + loadLabel->setText("负载"); + loadLabel->setFont(labelFont); + loadLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(loadLabel); + QLineEdit * loadValue = new QLineEdit(); + loadValue->setFixedWidth(60); + loadValue->setFont(labelFont); + vbox->addWidget(loadValue); + + QLabel * levelLabel = new QLabel(); + levelLabel->setText("触发电平"); + levelLabel->setFont(labelFont); + levelLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(levelLabel); + QLineEdit * levelValue = new QLineEdit(); + levelValue->setFixedWidth(60); + levelValue->setFont(labelFont); + vbox->addWidget(levelValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,clock").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } void CounterWindow::drawCounterDataOnPage(CounterDataDto * counterData) { // 1. 判断数据属于哪个设备,显示在不同的widget上 +// qDebug() << counterData->toJSON() << counterData->devCode << "---" << counterData->frameId; - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - QList row; - QStandardItem * itemTm = 0; - QStandardItem * itemData = 0; - itemTm = new QStandardItem(QString("%1").arg(counterData->timestamp.mid(11, 12))); - itemData = new QStandardItem(QString("%1").arg(counterData->channelData)); + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - row.append(itemTm); - row.append(itemData); - - QStandardItemModel * model; - model = devChannels.at(counterData->channelId - 1); - if (model->rowCount() >= 20) + // 如果不是当前设备的帧,直接返回 + if (counterData->devCode != currentDevCode) { - model->removeRows(0, model->rowCount()); + return; } - model->insertRow(0, row); + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(counterData->channelId); + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(counterData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 ps").arg(counterData->channelClockValue)); + ((QLineEdit *)channelBox->children().at(6))->setText(counterData->frameId); + ((QLineEdit *)channelBox->children().at(8))->setText(QString("%1").arg(counterData->channelRefId)); + ((QLineEdit *)channelBox->children().at(10))->setText(QString("%1 Ω").arg(counterData->load == 1 ? "1M" : "50")); + ((QLineEdit *)channelBox->children().at(12))->setText(QString("%1 V").arg(counterData->level)); + ((QLabel *)channelBox->children().at(13))->setText(counterData->channelActive == 1 ? "有效" : "无效"); +} -// for (int i = 0; i < counterData->channelData.size(); i++) -// { -// if (counterData->channelActive.at(i).toInt() == 1) -// { -// QList row; -// QStandardItem * item = 0; -// QStandardItem * item2 = 0; -// item = new QStandardItem(QString("%1").arg(counterData->timestamp.mid(11, 12))); -// item2 = new QStandardItem(QString("%1").arg(counterData->channelData.at(i))); +int CounterWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int CounterWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject CounterWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("计数器"); + return response; +} -// row.append(item); -// row.append(item2); +void CounterWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} -// QStandardItemModel * model; -// model = devChannels.at(i); -// if (model->rowCount() >= 60) -// { -// model->removeRows(0, model->rowCount()); -// } - -// model->insertRow(0, row); -// } -// } +void CounterWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); } diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 88ec496..3273433 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -2,7 +2,9 @@ #define COUNTERWINDOW_H #include +#include #include +#include #include "common/utils/SettingConfig.h" //#include "common/utils/QKafkaUtil.h" @@ -26,18 +28,24 @@ public slots: void drawCounterDataOnPage(CounterDataDto * counterData); +private slots: + void on_exitButt_clicked(); + + void on_minButt_clicked(); + private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + Ui::CounterWindow *ui; QTimer * timer; HttpRequestController * httpReq; - QList devWidgetList; - QList deviceList; - QList> tableModelList; - void generateWidgetForDevice(QString devCode, int index); + void generateWidgetForDevice(); }; #endif // COUNTERWINDOW_H diff --git a/CounterAcq/CounterWindow.ui b/CounterAcq/CounterWindow.ui index bcf9570..9ac6eb3 100644 --- a/CounterAcq/CounterWindow.ui +++ b/CounterAcq/CounterWindow.ui @@ -1,29 +1,156 @@ - - CounterWindow - - - - 0 - 0 - 1024 - 720 - - - - 多通道计数器数据采集 - - - - - 0 - 0 - 1024 - 720 - - - - - - - + + CounterWindow + + + + 0 + 0 + 1024 + 720 + + + + 多通道计数器数据采集 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 400 + 10 + 250 + 40 + + + + + + + 250 + 0 + 150 + 60 + + + + + 微软雅黑 + 12 + + + + Qt::LeftToRight + + + 请选择计数器 + + + Qt::AlignCenter + + + + + + 880 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 20 + 0 + 200 + 60 + + + + + 微软雅黑 + 14 + + + + 多通道计数器数据采集 + + + + + + 0 + 59 + 1024 + 1 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 830 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + diff --git a/CounterAcq/CounterDevice.cpp b/CounterAcq/CounterDevice.cpp index 1aef95a..a6f0bd1 100644 --- a/CounterAcq/CounterDevice.cpp +++ b/CounterAcq/CounterDevice.cpp @@ -2,12 +2,16 @@ #include #include +#include CounterDevice::CounterDevice(QObject *parent) : QObject(parent) { connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &CounterDevice::dataReceivedHandler); + connect(this, &CounterDevice::successDataCalculate, + this, &CounterDevice::afterFramePhase); + // kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); // kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); // kafkaUtil.createProducer(); @@ -35,6 +39,10 @@ { this->devCode = devCode; } +void CounterDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool CounterDevice::isSerialOpen() { @@ -55,7 +63,7 @@ if (CounterProtocolBM::checkFrame(this->dataBuff) == true) { counterData->rawFrame = this->dataBuff; - std::cout << counterData->rawFrame.toStdString() << std::endl; +// std::cout << counterData->rawFrame.toStdString() << std::endl; // ★解析成数据对象 bool parse = CounterProtocolBM::parseMessureData(this->dataBuff, counterData); @@ -63,36 +71,38 @@ // 解析成功 if (parse == true) { + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 补充其他字段 QDateTime now = QDateTime::currentDateTime(); counterData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); counterData->milisecond = now.toMSecsSinceEpoch(); - this->afterFramePhase(counterData); + counterData->devCode = devCode; + + // 3 计算数据ID一样的测量数据的时差值,通道值-参考通道值 + this->pushChannelRawFrame(counterData); } } // 在此处释放内存,不影响后续显示 // 不在此处释放内存则会导致内存持续增加 - // 具体原因不明 delete counterData; } void CounterDevice::afterFramePhase(CounterDataDto * counterData) { - // 1. 清空dataBuff,等待下一帧的数据 - this->dataBuff.clear(); + // 0. 输出到日志文件中 + QString date = counterData->timestamp.mid(0, 10); - // 2. 输出到日志文件中 - QString filePostfix = counterData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; - - // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + // 1. 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; QString content = counterData->timestamp + " " + counterData->rawFrame.left(counterData->rawFrame.size() - COUNTER_FRAME_TAIL.size()); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); - // 2.2 各个通道的clock diff数据 - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + // 2. 各个通道的clock diff数据 + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (counterData->channelId < 10) { chFilename = chFilename.arg(QString("0%1").arg(counterData->channelId)); @@ -100,20 +110,76 @@ { chFilename = chFilename.arg(counterData->channelId); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(counterData->timestamp).arg(counterData->channelClockValue).arg(counterData->frameId); - - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QString channelDataStr = QString("%1 [%2] %3 %4") + .arg(counterData->timestamp) + .arg(counterData->frameId) + .arg(counterData->channelData) + .arg(counterData->channelClockValue); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) { QJsonObject jsonObj = counterData->toJSON(); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); - jsonObj.insert("deviceId", devCode); + jsonObj.insert("deviceId", deviceId); // kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } // 4. 在界面上简单显示相差数据结果 emit this->sendDataToDraw(counterData); } + +void CounterDevice::pushChannelRawFrame(CounterDataDto * counterData) +{ + QString currentFrameId = counterData->frameId; + QString currentChannelId = QString("%1").arg(counterData->channelId); + + if (counterData->channelId == counterData->channelRefId) + { + // 自身是参考通道 + bench.insert(currentFrameId, counterData->channelData); + counterData->channelClockValue = 0; + + emit successDataCalculate(counterData); + + qlonglong thisBench = counterData->channelData; + // 遍历temp,处理之前的临时暂存的队列 + if (hisList.isEmpty() == false) + { + for (int i = 0; i < hisList.size(); i++) + { + CounterDataDto * hisItem = hisList.at(i); + if (hisItem->frameId == currentFrameId) + { + hisItem->channelClockValue = (hisItem->channelData - thisBench) * 10; + + emit successDataCalculate(hisItem); + delete hisItem; + } + } + + hisList.clear(); + } + } else + { + // 自身不是参考通道,减去相同frameId的参考通道值 + if (bench.contains(currentFrameId) == true) + { + // 在参考基准中能找到 + qlonglong currentBench = bench.find(currentFrameId).value(); + counterData->channelClockValue = (counterData->channelData - currentBench) * 10; // 10ps + + emit successDataCalculate(counterData); + } else + { + // 暂存,等收到基准之后再处置 + CounterDataDto * copyPoint = new CounterDataDto(); + + // ★clone一份对象,存入缓存队列 + counterData->clone(copyPoint); + + hisList.append(copyPoint); + } + } +} diff --git a/CounterAcq/CounterDevice.h b/CounterAcq/CounterDevice.h index 3572d69..b15e44f 100644 --- a/CounterAcq/CounterDevice.h +++ b/CounterAcq/CounterDevice.h @@ -19,16 +19,16 @@ void initSerialPort(); - void afterFramePhase(CounterDataDto * counterData); - void setComName(QString comName); void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; @@ -37,11 +37,18 @@ // QKafkaUtil kafkaUtil; QByteArray dataBuff; + QMap bench; + QList hisList; + + void pushChannelRawFrame(CounterDataDto * counterData); + signals: void sendDataToDraw(CounterDataDto * counterData); + void successDataCalculate(CounterDataDto * counterData); public slots: void dataReceivedHandler(QByteArray data); + void afterFramePhase(CounterDataDto * counterData); }; #endif // COUNTERDEVICE_H diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 31d43fd..f8278f6 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -5,12 +5,12 @@ #include #include #include +#include +#include #include -#include -#include #include -#include #include +#include CounterWindow::CounterWindow(QWidget *parent) : QWidget(parent), @@ -18,56 +18,74 @@ { ui->setupUi(this); + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), 700); + resize(screenRect.width(), screenRect.height()); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); - - for (int i = 0; i < comDevList.size(); i++) - { - CounterDevice * device = new CounterDevice(this); - - // - connect(device, &CounterDevice::sendDataToDraw, - this, &CounterWindow::drawCounterDataOnPage); - - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); - - device->setDevCode(devCodeList.at(i)); - - this->deviceList.append(device); - -// device->initSerialPort(); -// device->startWork(); - } - - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget = new QWidget(this->ui->stackedWidget); - ui->stackedWidget->addWidget(devWidget); - devWidgetList.append(devWidget); - - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); httpReq = new HttpRequestController(this); - QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, - SettingConfig::getInstance().APP_KEY); - if (response.find("code")->toInt() == 200) + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - httpReq->initDictDeviceType(); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - httpReq->initDeviceList(); + QApplication::exit(0); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); + + // 3. 获取计数器设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); + + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i =0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); + + CounterDevice * device = new CounterDevice(this); + deviceList.append(device); + + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &CounterDevice::sendDataToDraw, + this, &CounterWindow::drawCounterDataOnPage); + + device->initSerialPort(); + + QThread::msleep(200); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } -// timer = new QTimer(this); -// timer->start(1000 * 10); + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } CounterWindow::~CounterWindow() @@ -75,110 +93,153 @@ delete ui; } -void CounterWindow::generateWidgetForDevice(QString devCode, int index) +void CounterWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(75); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(75); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * refChLabel = new QLabel(); + refChLabel->setText("参考通道"); + refChLabel->setFont(labelFont); + refChLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(refChLabel); + QLineEdit * refChValue = new QLineEdit(); + refChValue->setFixedWidth(60); + refChValue->setFont(labelFont); + vbox->addWidget(refChValue); + + QLabel * loadLabel = new QLabel(); + loadLabel->setText("负载"); + loadLabel->setFont(labelFont); + loadLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(loadLabel); + QLineEdit * loadValue = new QLineEdit(); + loadValue->setFixedWidth(60); + loadValue->setFont(labelFont); + vbox->addWidget(loadValue); + + QLabel * levelLabel = new QLabel(); + levelLabel->setText("触发电平"); + levelLabel->setFont(labelFont); + levelLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(levelLabel); + QLineEdit * levelValue = new QLineEdit(); + levelValue->setFixedWidth(60); + levelValue->setFont(labelFont); + vbox->addWidget(levelValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,clock").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } void CounterWindow::drawCounterDataOnPage(CounterDataDto * counterData) { // 1. 判断数据属于哪个设备,显示在不同的widget上 +// qDebug() << counterData->toJSON() << counterData->devCode << "---" << counterData->frameId; - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - QList row; - QStandardItem * itemTm = 0; - QStandardItem * itemData = 0; - itemTm = new QStandardItem(QString("%1").arg(counterData->timestamp.mid(11, 12))); - itemData = new QStandardItem(QString("%1").arg(counterData->channelData)); + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - row.append(itemTm); - row.append(itemData); - - QStandardItemModel * model; - model = devChannels.at(counterData->channelId - 1); - if (model->rowCount() >= 20) + // 如果不是当前设备的帧,直接返回 + if (counterData->devCode != currentDevCode) { - model->removeRows(0, model->rowCount()); + return; } - model->insertRow(0, row); + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(counterData->channelId); + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(counterData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 ps").arg(counterData->channelClockValue)); + ((QLineEdit *)channelBox->children().at(6))->setText(counterData->frameId); + ((QLineEdit *)channelBox->children().at(8))->setText(QString("%1").arg(counterData->channelRefId)); + ((QLineEdit *)channelBox->children().at(10))->setText(QString("%1 Ω").arg(counterData->load == 1 ? "1M" : "50")); + ((QLineEdit *)channelBox->children().at(12))->setText(QString("%1 V").arg(counterData->level)); + ((QLabel *)channelBox->children().at(13))->setText(counterData->channelActive == 1 ? "有效" : "无效"); +} -// for (int i = 0; i < counterData->channelData.size(); i++) -// { -// if (counterData->channelActive.at(i).toInt() == 1) -// { -// QList row; -// QStandardItem * item = 0; -// QStandardItem * item2 = 0; -// item = new QStandardItem(QString("%1").arg(counterData->timestamp.mid(11, 12))); -// item2 = new QStandardItem(QString("%1").arg(counterData->channelData.at(i))); +int CounterWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int CounterWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject CounterWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("计数器"); + return response; +} -// row.append(item); -// row.append(item2); +void CounterWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} -// QStandardItemModel * model; -// model = devChannels.at(i); -// if (model->rowCount() >= 60) -// { -// model->removeRows(0, model->rowCount()); -// } - -// model->insertRow(0, row); -// } -// } +void CounterWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); } diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 88ec496..3273433 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -2,7 +2,9 @@ #define COUNTERWINDOW_H #include +#include #include +#include #include "common/utils/SettingConfig.h" //#include "common/utils/QKafkaUtil.h" @@ -26,18 +28,24 @@ public slots: void drawCounterDataOnPage(CounterDataDto * counterData); +private slots: + void on_exitButt_clicked(); + + void on_minButt_clicked(); + private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + Ui::CounterWindow *ui; QTimer * timer; HttpRequestController * httpReq; - QList devWidgetList; - QList deviceList; - QList> tableModelList; - void generateWidgetForDevice(QString devCode, int index); + void generateWidgetForDevice(); }; #endif // COUNTERWINDOW_H diff --git a/CounterAcq/CounterWindow.ui b/CounterAcq/CounterWindow.ui index bcf9570..9ac6eb3 100644 --- a/CounterAcq/CounterWindow.ui +++ b/CounterAcq/CounterWindow.ui @@ -1,29 +1,156 @@ - - CounterWindow - - - - 0 - 0 - 1024 - 720 - - - - 多通道计数器数据采集 - - - - - 0 - 0 - 1024 - 720 - - - - - - - + + CounterWindow + + + + 0 + 0 + 1024 + 720 + + + + 多通道计数器数据采集 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 400 + 10 + 250 + 40 + + + + + + + 250 + 0 + 150 + 60 + + + + + 微软雅黑 + 12 + + + + Qt::LeftToRight + + + 请选择计数器 + + + Qt::AlignCenter + + + + + + 880 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 20 + 0 + 200 + 60 + + + + + 微软雅黑 + 14 + + + + 多通道计数器数据采集 + + + + + + 0 + 59 + 1024 + 1 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 830 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + diff --git a/CounterAcq/common/HttpRequestController.cpp b/CounterAcq/common/HttpRequestController.cpp index 500f902..d4912b8 100644 --- a/CounterAcq/common/HttpRequestController.cpp +++ b/CounterAcq/common/HttpRequestController.cpp @@ -38,18 +38,21 @@ document.setObject(paramObj); QByteArray content = document.toJson(QJsonDocument::Compact); - QNetworkReply *reply = httpUtil->sendPostRequest(request, content); + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); - } - if (resultObj.find("code")->toInt() == 200) + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else { - QString token = resultObj.find("data")->toString(); - this->token = token; + resultObj.insert("code", -1); } return resultObj; @@ -72,36 +75,39 @@ QNetworkReply * reply = httpUtil->sendGetRequest(request); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); - } - if (resultObj.find("code")->toInt() == 200) - { - ConstCache::getInstance().deviceTypes.clear(); - - QJsonArray data = resultObj.find("data")->toArray(); - for (int i = 0; i < data.size(); i++) + if (resultObj.find("code")->toInt() == 200) { - QJsonObject item = data.at(i).toObject(); + ConstCache::getInstance().deviceTypes.clear(); - ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } } + } else + { + resultObj.insert("code", -1); } return resultObj; } -QJsonObject HttpRequestController::initDeviceList() +QJsonObject HttpRequestController::initDeviceList(QString devType) { QJsonObject resultObj; - QString counterDevType = "01"; + QString counterDevType = ""; QMapIterator it(ConstCache::getInstance().deviceTypes); while (it.hasNext()) { it.next(); - if (it.value().contains("计数器") == true) + if (it.value().contains(devType) == true) { counterDevType = it.key(); break; @@ -120,26 +126,32 @@ request.setRawHeader("token", token.toLocal8Bit()); request.setRawHeader("system", system.toLocal8Bit()); + qDebug() << url; + QNetworkReply * reply = httpUtil->sendGetRequest(request); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); } qDebug() << resultObj; - if (resultObj.find("code")->toInt() == 200) - { - ConstCache::getInstance().deviceList.clear(); - - QJsonArray data = resultObj.find("data")->toArray(); - for (int i = 0; i < data.size(); i++) - { - QJsonObject item = data.at(i).toObject(); - - ConstCache::getInstance().deviceList.append(item); - } - } return resultObj; } diff --git a/CounterAcq/CounterDevice.cpp b/CounterAcq/CounterDevice.cpp index 1aef95a..a6f0bd1 100644 --- a/CounterAcq/CounterDevice.cpp +++ b/CounterAcq/CounterDevice.cpp @@ -2,12 +2,16 @@ #include #include +#include CounterDevice::CounterDevice(QObject *parent) : QObject(parent) { connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &CounterDevice::dataReceivedHandler); + connect(this, &CounterDevice::successDataCalculate, + this, &CounterDevice::afterFramePhase); + // kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); // kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); // kafkaUtil.createProducer(); @@ -35,6 +39,10 @@ { this->devCode = devCode; } +void CounterDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool CounterDevice::isSerialOpen() { @@ -55,7 +63,7 @@ if (CounterProtocolBM::checkFrame(this->dataBuff) == true) { counterData->rawFrame = this->dataBuff; - std::cout << counterData->rawFrame.toStdString() << std::endl; +// std::cout << counterData->rawFrame.toStdString() << std::endl; // ★解析成数据对象 bool parse = CounterProtocolBM::parseMessureData(this->dataBuff, counterData); @@ -63,36 +71,38 @@ // 解析成功 if (parse == true) { + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 补充其他字段 QDateTime now = QDateTime::currentDateTime(); counterData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); counterData->milisecond = now.toMSecsSinceEpoch(); - this->afterFramePhase(counterData); + counterData->devCode = devCode; + + // 3 计算数据ID一样的测量数据的时差值,通道值-参考通道值 + this->pushChannelRawFrame(counterData); } } // 在此处释放内存,不影响后续显示 // 不在此处释放内存则会导致内存持续增加 - // 具体原因不明 delete counterData; } void CounterDevice::afterFramePhase(CounterDataDto * counterData) { - // 1. 清空dataBuff,等待下一帧的数据 - this->dataBuff.clear(); + // 0. 输出到日志文件中 + QString date = counterData->timestamp.mid(0, 10); - // 2. 输出到日志文件中 - QString filePostfix = counterData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; - - // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + // 1. 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; QString content = counterData->timestamp + " " + counterData->rawFrame.left(counterData->rawFrame.size() - COUNTER_FRAME_TAIL.size()); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); - // 2.2 各个通道的clock diff数据 - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + // 2. 各个通道的clock diff数据 + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (counterData->channelId < 10) { chFilename = chFilename.arg(QString("0%1").arg(counterData->channelId)); @@ -100,20 +110,76 @@ { chFilename = chFilename.arg(counterData->channelId); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(counterData->timestamp).arg(counterData->channelClockValue).arg(counterData->frameId); - - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QString channelDataStr = QString("%1 [%2] %3 %4") + .arg(counterData->timestamp) + .arg(counterData->frameId) + .arg(counterData->channelData) + .arg(counterData->channelClockValue); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) { QJsonObject jsonObj = counterData->toJSON(); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); - jsonObj.insert("deviceId", devCode); + jsonObj.insert("deviceId", deviceId); // kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } // 4. 在界面上简单显示相差数据结果 emit this->sendDataToDraw(counterData); } + +void CounterDevice::pushChannelRawFrame(CounterDataDto * counterData) +{ + QString currentFrameId = counterData->frameId; + QString currentChannelId = QString("%1").arg(counterData->channelId); + + if (counterData->channelId == counterData->channelRefId) + { + // 自身是参考通道 + bench.insert(currentFrameId, counterData->channelData); + counterData->channelClockValue = 0; + + emit successDataCalculate(counterData); + + qlonglong thisBench = counterData->channelData; + // 遍历temp,处理之前的临时暂存的队列 + if (hisList.isEmpty() == false) + { + for (int i = 0; i < hisList.size(); i++) + { + CounterDataDto * hisItem = hisList.at(i); + if (hisItem->frameId == currentFrameId) + { + hisItem->channelClockValue = (hisItem->channelData - thisBench) * 10; + + emit successDataCalculate(hisItem); + delete hisItem; + } + } + + hisList.clear(); + } + } else + { + // 自身不是参考通道,减去相同frameId的参考通道值 + if (bench.contains(currentFrameId) == true) + { + // 在参考基准中能找到 + qlonglong currentBench = bench.find(currentFrameId).value(); + counterData->channelClockValue = (counterData->channelData - currentBench) * 10; // 10ps + + emit successDataCalculate(counterData); + } else + { + // 暂存,等收到基准之后再处置 + CounterDataDto * copyPoint = new CounterDataDto(); + + // ★clone一份对象,存入缓存队列 + counterData->clone(copyPoint); + + hisList.append(copyPoint); + } + } +} diff --git a/CounterAcq/CounterDevice.h b/CounterAcq/CounterDevice.h index 3572d69..b15e44f 100644 --- a/CounterAcq/CounterDevice.h +++ b/CounterAcq/CounterDevice.h @@ -19,16 +19,16 @@ void initSerialPort(); - void afterFramePhase(CounterDataDto * counterData); - void setComName(QString comName); void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; @@ -37,11 +37,18 @@ // QKafkaUtil kafkaUtil; QByteArray dataBuff; + QMap bench; + QList hisList; + + void pushChannelRawFrame(CounterDataDto * counterData); + signals: void sendDataToDraw(CounterDataDto * counterData); + void successDataCalculate(CounterDataDto * counterData); public slots: void dataReceivedHandler(QByteArray data); + void afterFramePhase(CounterDataDto * counterData); }; #endif // COUNTERDEVICE_H diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 31d43fd..f8278f6 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -5,12 +5,12 @@ #include #include #include +#include +#include #include -#include -#include #include -#include #include +#include CounterWindow::CounterWindow(QWidget *parent) : QWidget(parent), @@ -18,56 +18,74 @@ { ui->setupUi(this); + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), 700); + resize(screenRect.width(), screenRect.height()); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); - - for (int i = 0; i < comDevList.size(); i++) - { - CounterDevice * device = new CounterDevice(this); - - // - connect(device, &CounterDevice::sendDataToDraw, - this, &CounterWindow::drawCounterDataOnPage); - - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); - - device->setDevCode(devCodeList.at(i)); - - this->deviceList.append(device); - -// device->initSerialPort(); -// device->startWork(); - } - - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget = new QWidget(this->ui->stackedWidget); - ui->stackedWidget->addWidget(devWidget); - devWidgetList.append(devWidget); - - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); httpReq = new HttpRequestController(this); - QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, - SettingConfig::getInstance().APP_KEY); - if (response.find("code")->toInt() == 200) + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - httpReq->initDictDeviceType(); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - httpReq->initDeviceList(); + QApplication::exit(0); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); + + // 3. 获取计数器设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); + + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i =0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); + + CounterDevice * device = new CounterDevice(this); + deviceList.append(device); + + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &CounterDevice::sendDataToDraw, + this, &CounterWindow::drawCounterDataOnPage); + + device->initSerialPort(); + + QThread::msleep(200); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } -// timer = new QTimer(this); -// timer->start(1000 * 10); + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } CounterWindow::~CounterWindow() @@ -75,110 +93,153 @@ delete ui; } -void CounterWindow::generateWidgetForDevice(QString devCode, int index) +void CounterWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(75); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(75); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * refChLabel = new QLabel(); + refChLabel->setText("参考通道"); + refChLabel->setFont(labelFont); + refChLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(refChLabel); + QLineEdit * refChValue = new QLineEdit(); + refChValue->setFixedWidth(60); + refChValue->setFont(labelFont); + vbox->addWidget(refChValue); + + QLabel * loadLabel = new QLabel(); + loadLabel->setText("负载"); + loadLabel->setFont(labelFont); + loadLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(loadLabel); + QLineEdit * loadValue = new QLineEdit(); + loadValue->setFixedWidth(60); + loadValue->setFont(labelFont); + vbox->addWidget(loadValue); + + QLabel * levelLabel = new QLabel(); + levelLabel->setText("触发电平"); + levelLabel->setFont(labelFont); + levelLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(levelLabel); + QLineEdit * levelValue = new QLineEdit(); + levelValue->setFixedWidth(60); + levelValue->setFont(labelFont); + vbox->addWidget(levelValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,clock").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } void CounterWindow::drawCounterDataOnPage(CounterDataDto * counterData) { // 1. 判断数据属于哪个设备,显示在不同的widget上 +// qDebug() << counterData->toJSON() << counterData->devCode << "---" << counterData->frameId; - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - QList row; - QStandardItem * itemTm = 0; - QStandardItem * itemData = 0; - itemTm = new QStandardItem(QString("%1").arg(counterData->timestamp.mid(11, 12))); - itemData = new QStandardItem(QString("%1").arg(counterData->channelData)); + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - row.append(itemTm); - row.append(itemData); - - QStandardItemModel * model; - model = devChannels.at(counterData->channelId - 1); - if (model->rowCount() >= 20) + // 如果不是当前设备的帧,直接返回 + if (counterData->devCode != currentDevCode) { - model->removeRows(0, model->rowCount()); + return; } - model->insertRow(0, row); + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(counterData->channelId); + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(counterData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 ps").arg(counterData->channelClockValue)); + ((QLineEdit *)channelBox->children().at(6))->setText(counterData->frameId); + ((QLineEdit *)channelBox->children().at(8))->setText(QString("%1").arg(counterData->channelRefId)); + ((QLineEdit *)channelBox->children().at(10))->setText(QString("%1 Ω").arg(counterData->load == 1 ? "1M" : "50")); + ((QLineEdit *)channelBox->children().at(12))->setText(QString("%1 V").arg(counterData->level)); + ((QLabel *)channelBox->children().at(13))->setText(counterData->channelActive == 1 ? "有效" : "无效"); +} -// for (int i = 0; i < counterData->channelData.size(); i++) -// { -// if (counterData->channelActive.at(i).toInt() == 1) -// { -// QList row; -// QStandardItem * item = 0; -// QStandardItem * item2 = 0; -// item = new QStandardItem(QString("%1").arg(counterData->timestamp.mid(11, 12))); -// item2 = new QStandardItem(QString("%1").arg(counterData->channelData.at(i))); +int CounterWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int CounterWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject CounterWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("计数器"); + return response; +} -// row.append(item); -// row.append(item2); +void CounterWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} -// QStandardItemModel * model; -// model = devChannels.at(i); -// if (model->rowCount() >= 60) -// { -// model->removeRows(0, model->rowCount()); -// } - -// model->insertRow(0, row); -// } -// } +void CounterWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); } diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 88ec496..3273433 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -2,7 +2,9 @@ #define COUNTERWINDOW_H #include +#include #include +#include #include "common/utils/SettingConfig.h" //#include "common/utils/QKafkaUtil.h" @@ -26,18 +28,24 @@ public slots: void drawCounterDataOnPage(CounterDataDto * counterData); +private slots: + void on_exitButt_clicked(); + + void on_minButt_clicked(); + private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + Ui::CounterWindow *ui; QTimer * timer; HttpRequestController * httpReq; - QList devWidgetList; - QList deviceList; - QList> tableModelList; - void generateWidgetForDevice(QString devCode, int index); + void generateWidgetForDevice(); }; #endif // COUNTERWINDOW_H diff --git a/CounterAcq/CounterWindow.ui b/CounterAcq/CounterWindow.ui index bcf9570..9ac6eb3 100644 --- a/CounterAcq/CounterWindow.ui +++ b/CounterAcq/CounterWindow.ui @@ -1,29 +1,156 @@ - - CounterWindow - - - - 0 - 0 - 1024 - 720 - - - - 多通道计数器数据采集 - - - - - 0 - 0 - 1024 - 720 - - - - - - - + + CounterWindow + + + + 0 + 0 + 1024 + 720 + + + + 多通道计数器数据采集 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 400 + 10 + 250 + 40 + + + + + + + 250 + 0 + 150 + 60 + + + + + 微软雅黑 + 12 + + + + Qt::LeftToRight + + + 请选择计数器 + + + Qt::AlignCenter + + + + + + 880 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 20 + 0 + 200 + 60 + + + + + 微软雅黑 + 14 + + + + 多通道计数器数据采集 + + + + + + 0 + 59 + 1024 + 1 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 830 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + diff --git a/CounterAcq/common/HttpRequestController.cpp b/CounterAcq/common/HttpRequestController.cpp index 500f902..d4912b8 100644 --- a/CounterAcq/common/HttpRequestController.cpp +++ b/CounterAcq/common/HttpRequestController.cpp @@ -38,18 +38,21 @@ document.setObject(paramObj); QByteArray content = document.toJson(QJsonDocument::Compact); - QNetworkReply *reply = httpUtil->sendPostRequest(request, content); + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); - } - if (resultObj.find("code")->toInt() == 200) + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else { - QString token = resultObj.find("data")->toString(); - this->token = token; + resultObj.insert("code", -1); } return resultObj; @@ -72,36 +75,39 @@ QNetworkReply * reply = httpUtil->sendGetRequest(request); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); - } - if (resultObj.find("code")->toInt() == 200) - { - ConstCache::getInstance().deviceTypes.clear(); - - QJsonArray data = resultObj.find("data")->toArray(); - for (int i = 0; i < data.size(); i++) + if (resultObj.find("code")->toInt() == 200) { - QJsonObject item = data.at(i).toObject(); + ConstCache::getInstance().deviceTypes.clear(); - ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } } + } else + { + resultObj.insert("code", -1); } return resultObj; } -QJsonObject HttpRequestController::initDeviceList() +QJsonObject HttpRequestController::initDeviceList(QString devType) { QJsonObject resultObj; - QString counterDevType = "01"; + QString counterDevType = ""; QMapIterator it(ConstCache::getInstance().deviceTypes); while (it.hasNext()) { it.next(); - if (it.value().contains("计数器") == true) + if (it.value().contains(devType) == true) { counterDevType = it.key(); break; @@ -120,26 +126,32 @@ request.setRawHeader("token", token.toLocal8Bit()); request.setRawHeader("system", system.toLocal8Bit()); + qDebug() << url; + QNetworkReply * reply = httpUtil->sendGetRequest(request); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); } qDebug() << resultObj; - if (resultObj.find("code")->toInt() == 200) - { - ConstCache::getInstance().deviceList.clear(); - - QJsonArray data = resultObj.find("data")->toArray(); - for (int i = 0; i < data.size(); i++) - { - QJsonObject item = data.at(i).toObject(); - - ConstCache::getInstance().deviceList.append(item); - } - } return resultObj; } diff --git a/CounterAcq/common/HttpRequestController.h b/CounterAcq/common/HttpRequestController.h index 46d9b84..77fc3db 100644 --- a/CounterAcq/common/HttpRequestController.h +++ b/CounterAcq/common/HttpRequestController.h @@ -18,7 +18,7 @@ QJsonObject getTokenByClientId(QString clientId, QString key); QJsonObject initDictDeviceType(); - QJsonObject initDeviceList(); + QJsonObject initDeviceList(QString devType); private: HttpRequestUtil * httpUtil; diff --git a/CounterAcq/CounterDevice.cpp b/CounterAcq/CounterDevice.cpp index 1aef95a..a6f0bd1 100644 --- a/CounterAcq/CounterDevice.cpp +++ b/CounterAcq/CounterDevice.cpp @@ -2,12 +2,16 @@ #include #include +#include CounterDevice::CounterDevice(QObject *parent) : QObject(parent) { connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &CounterDevice::dataReceivedHandler); + connect(this, &CounterDevice::successDataCalculate, + this, &CounterDevice::afterFramePhase); + // kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); // kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); // kafkaUtil.createProducer(); @@ -35,6 +39,10 @@ { this->devCode = devCode; } +void CounterDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool CounterDevice::isSerialOpen() { @@ -55,7 +63,7 @@ if (CounterProtocolBM::checkFrame(this->dataBuff) == true) { counterData->rawFrame = this->dataBuff; - std::cout << counterData->rawFrame.toStdString() << std::endl; +// std::cout << counterData->rawFrame.toStdString() << std::endl; // ★解析成数据对象 bool parse = CounterProtocolBM::parseMessureData(this->dataBuff, counterData); @@ -63,36 +71,38 @@ // 解析成功 if (parse == true) { + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 补充其他字段 QDateTime now = QDateTime::currentDateTime(); counterData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); counterData->milisecond = now.toMSecsSinceEpoch(); - this->afterFramePhase(counterData); + counterData->devCode = devCode; + + // 3 计算数据ID一样的测量数据的时差值,通道值-参考通道值 + this->pushChannelRawFrame(counterData); } } // 在此处释放内存,不影响后续显示 // 不在此处释放内存则会导致内存持续增加 - // 具体原因不明 delete counterData; } void CounterDevice::afterFramePhase(CounterDataDto * counterData) { - // 1. 清空dataBuff,等待下一帧的数据 - this->dataBuff.clear(); + // 0. 输出到日志文件中 + QString date = counterData->timestamp.mid(0, 10); - // 2. 输出到日志文件中 - QString filePostfix = counterData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; - - // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + // 1. 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; QString content = counterData->timestamp + " " + counterData->rawFrame.left(counterData->rawFrame.size() - COUNTER_FRAME_TAIL.size()); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); - // 2.2 各个通道的clock diff数据 - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + // 2. 各个通道的clock diff数据 + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (counterData->channelId < 10) { chFilename = chFilename.arg(QString("0%1").arg(counterData->channelId)); @@ -100,20 +110,76 @@ { chFilename = chFilename.arg(counterData->channelId); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(counterData->timestamp).arg(counterData->channelClockValue).arg(counterData->frameId); - - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QString channelDataStr = QString("%1 [%2] %3 %4") + .arg(counterData->timestamp) + .arg(counterData->frameId) + .arg(counterData->channelData) + .arg(counterData->channelClockValue); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) { QJsonObject jsonObj = counterData->toJSON(); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); - jsonObj.insert("deviceId", devCode); + jsonObj.insert("deviceId", deviceId); // kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } // 4. 在界面上简单显示相差数据结果 emit this->sendDataToDraw(counterData); } + +void CounterDevice::pushChannelRawFrame(CounterDataDto * counterData) +{ + QString currentFrameId = counterData->frameId; + QString currentChannelId = QString("%1").arg(counterData->channelId); + + if (counterData->channelId == counterData->channelRefId) + { + // 自身是参考通道 + bench.insert(currentFrameId, counterData->channelData); + counterData->channelClockValue = 0; + + emit successDataCalculate(counterData); + + qlonglong thisBench = counterData->channelData; + // 遍历temp,处理之前的临时暂存的队列 + if (hisList.isEmpty() == false) + { + for (int i = 0; i < hisList.size(); i++) + { + CounterDataDto * hisItem = hisList.at(i); + if (hisItem->frameId == currentFrameId) + { + hisItem->channelClockValue = (hisItem->channelData - thisBench) * 10; + + emit successDataCalculate(hisItem); + delete hisItem; + } + } + + hisList.clear(); + } + } else + { + // 自身不是参考通道,减去相同frameId的参考通道值 + if (bench.contains(currentFrameId) == true) + { + // 在参考基准中能找到 + qlonglong currentBench = bench.find(currentFrameId).value(); + counterData->channelClockValue = (counterData->channelData - currentBench) * 10; // 10ps + + emit successDataCalculate(counterData); + } else + { + // 暂存,等收到基准之后再处置 + CounterDataDto * copyPoint = new CounterDataDto(); + + // ★clone一份对象,存入缓存队列 + counterData->clone(copyPoint); + + hisList.append(copyPoint); + } + } +} diff --git a/CounterAcq/CounterDevice.h b/CounterAcq/CounterDevice.h index 3572d69..b15e44f 100644 --- a/CounterAcq/CounterDevice.h +++ b/CounterAcq/CounterDevice.h @@ -19,16 +19,16 @@ void initSerialPort(); - void afterFramePhase(CounterDataDto * counterData); - void setComName(QString comName); void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; @@ -37,11 +37,18 @@ // QKafkaUtil kafkaUtil; QByteArray dataBuff; + QMap bench; + QList hisList; + + void pushChannelRawFrame(CounterDataDto * counterData); + signals: void sendDataToDraw(CounterDataDto * counterData); + void successDataCalculate(CounterDataDto * counterData); public slots: void dataReceivedHandler(QByteArray data); + void afterFramePhase(CounterDataDto * counterData); }; #endif // COUNTERDEVICE_H diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 31d43fd..f8278f6 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -5,12 +5,12 @@ #include #include #include +#include +#include #include -#include -#include #include -#include #include +#include CounterWindow::CounterWindow(QWidget *parent) : QWidget(parent), @@ -18,56 +18,74 @@ { ui->setupUi(this); + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), 700); + resize(screenRect.width(), screenRect.height()); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); - - for (int i = 0; i < comDevList.size(); i++) - { - CounterDevice * device = new CounterDevice(this); - - // - connect(device, &CounterDevice::sendDataToDraw, - this, &CounterWindow::drawCounterDataOnPage); - - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); - - device->setDevCode(devCodeList.at(i)); - - this->deviceList.append(device); - -// device->initSerialPort(); -// device->startWork(); - } - - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget = new QWidget(this->ui->stackedWidget); - ui->stackedWidget->addWidget(devWidget); - devWidgetList.append(devWidget); - - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); httpReq = new HttpRequestController(this); - QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, - SettingConfig::getInstance().APP_KEY); - if (response.find("code")->toInt() == 200) + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - httpReq->initDictDeviceType(); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - httpReq->initDeviceList(); + QApplication::exit(0); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); + + // 3. 获取计数器设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); + + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i =0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); + + CounterDevice * device = new CounterDevice(this); + deviceList.append(device); + + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &CounterDevice::sendDataToDraw, + this, &CounterWindow::drawCounterDataOnPage); + + device->initSerialPort(); + + QThread::msleep(200); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } -// timer = new QTimer(this); -// timer->start(1000 * 10); + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } CounterWindow::~CounterWindow() @@ -75,110 +93,153 @@ delete ui; } -void CounterWindow::generateWidgetForDevice(QString devCode, int index) +void CounterWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(75); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(75); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * refChLabel = new QLabel(); + refChLabel->setText("参考通道"); + refChLabel->setFont(labelFont); + refChLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(refChLabel); + QLineEdit * refChValue = new QLineEdit(); + refChValue->setFixedWidth(60); + refChValue->setFont(labelFont); + vbox->addWidget(refChValue); + + QLabel * loadLabel = new QLabel(); + loadLabel->setText("负载"); + loadLabel->setFont(labelFont); + loadLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(loadLabel); + QLineEdit * loadValue = new QLineEdit(); + loadValue->setFixedWidth(60); + loadValue->setFont(labelFont); + vbox->addWidget(loadValue); + + QLabel * levelLabel = new QLabel(); + levelLabel->setText("触发电平"); + levelLabel->setFont(labelFont); + levelLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(levelLabel); + QLineEdit * levelValue = new QLineEdit(); + levelValue->setFixedWidth(60); + levelValue->setFont(labelFont); + vbox->addWidget(levelValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,clock").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } void CounterWindow::drawCounterDataOnPage(CounterDataDto * counterData) { // 1. 判断数据属于哪个设备,显示在不同的widget上 +// qDebug() << counterData->toJSON() << counterData->devCode << "---" << counterData->frameId; - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - QList row; - QStandardItem * itemTm = 0; - QStandardItem * itemData = 0; - itemTm = new QStandardItem(QString("%1").arg(counterData->timestamp.mid(11, 12))); - itemData = new QStandardItem(QString("%1").arg(counterData->channelData)); + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - row.append(itemTm); - row.append(itemData); - - QStandardItemModel * model; - model = devChannels.at(counterData->channelId - 1); - if (model->rowCount() >= 20) + // 如果不是当前设备的帧,直接返回 + if (counterData->devCode != currentDevCode) { - model->removeRows(0, model->rowCount()); + return; } - model->insertRow(0, row); + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(counterData->channelId); + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(counterData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 ps").arg(counterData->channelClockValue)); + ((QLineEdit *)channelBox->children().at(6))->setText(counterData->frameId); + ((QLineEdit *)channelBox->children().at(8))->setText(QString("%1").arg(counterData->channelRefId)); + ((QLineEdit *)channelBox->children().at(10))->setText(QString("%1 Ω").arg(counterData->load == 1 ? "1M" : "50")); + ((QLineEdit *)channelBox->children().at(12))->setText(QString("%1 V").arg(counterData->level)); + ((QLabel *)channelBox->children().at(13))->setText(counterData->channelActive == 1 ? "有效" : "无效"); +} -// for (int i = 0; i < counterData->channelData.size(); i++) -// { -// if (counterData->channelActive.at(i).toInt() == 1) -// { -// QList row; -// QStandardItem * item = 0; -// QStandardItem * item2 = 0; -// item = new QStandardItem(QString("%1").arg(counterData->timestamp.mid(11, 12))); -// item2 = new QStandardItem(QString("%1").arg(counterData->channelData.at(i))); +int CounterWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int CounterWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject CounterWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("计数器"); + return response; +} -// row.append(item); -// row.append(item2); +void CounterWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} -// QStandardItemModel * model; -// model = devChannels.at(i); -// if (model->rowCount() >= 60) -// { -// model->removeRows(0, model->rowCount()); -// } - -// model->insertRow(0, row); -// } -// } +void CounterWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); } diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 88ec496..3273433 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -2,7 +2,9 @@ #define COUNTERWINDOW_H #include +#include #include +#include #include "common/utils/SettingConfig.h" //#include "common/utils/QKafkaUtil.h" @@ -26,18 +28,24 @@ public slots: void drawCounterDataOnPage(CounterDataDto * counterData); +private slots: + void on_exitButt_clicked(); + + void on_minButt_clicked(); + private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + Ui::CounterWindow *ui; QTimer * timer; HttpRequestController * httpReq; - QList devWidgetList; - QList deviceList; - QList> tableModelList; - void generateWidgetForDevice(QString devCode, int index); + void generateWidgetForDevice(); }; #endif // COUNTERWINDOW_H diff --git a/CounterAcq/CounterWindow.ui b/CounterAcq/CounterWindow.ui index bcf9570..9ac6eb3 100644 --- a/CounterAcq/CounterWindow.ui +++ b/CounterAcq/CounterWindow.ui @@ -1,29 +1,156 @@ - - CounterWindow - - - - 0 - 0 - 1024 - 720 - - - - 多通道计数器数据采集 - - - - - 0 - 0 - 1024 - 720 - - - - - - - + + CounterWindow + + + + 0 + 0 + 1024 + 720 + + + + 多通道计数器数据采集 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 400 + 10 + 250 + 40 + + + + + + + 250 + 0 + 150 + 60 + + + + + 微软雅黑 + 12 + + + + Qt::LeftToRight + + + 请选择计数器 + + + Qt::AlignCenter + + + + + + 880 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 20 + 0 + 200 + 60 + + + + + 微软雅黑 + 14 + + + + 多通道计数器数据采集 + + + + + + 0 + 59 + 1024 + 1 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 830 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + diff --git a/CounterAcq/common/HttpRequestController.cpp b/CounterAcq/common/HttpRequestController.cpp index 500f902..d4912b8 100644 --- a/CounterAcq/common/HttpRequestController.cpp +++ b/CounterAcq/common/HttpRequestController.cpp @@ -38,18 +38,21 @@ document.setObject(paramObj); QByteArray content = document.toJson(QJsonDocument::Compact); - QNetworkReply *reply = httpUtil->sendPostRequest(request, content); + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); - } - if (resultObj.find("code")->toInt() == 200) + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else { - QString token = resultObj.find("data")->toString(); - this->token = token; + resultObj.insert("code", -1); } return resultObj; @@ -72,36 +75,39 @@ QNetworkReply * reply = httpUtil->sendGetRequest(request); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); - } - if (resultObj.find("code")->toInt() == 200) - { - ConstCache::getInstance().deviceTypes.clear(); - - QJsonArray data = resultObj.find("data")->toArray(); - for (int i = 0; i < data.size(); i++) + if (resultObj.find("code")->toInt() == 200) { - QJsonObject item = data.at(i).toObject(); + ConstCache::getInstance().deviceTypes.clear(); - ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } } + } else + { + resultObj.insert("code", -1); } return resultObj; } -QJsonObject HttpRequestController::initDeviceList() +QJsonObject HttpRequestController::initDeviceList(QString devType) { QJsonObject resultObj; - QString counterDevType = "01"; + QString counterDevType = ""; QMapIterator it(ConstCache::getInstance().deviceTypes); while (it.hasNext()) { it.next(); - if (it.value().contains("计数器") == true) + if (it.value().contains(devType) == true) { counterDevType = it.key(); break; @@ -120,26 +126,32 @@ request.setRawHeader("token", token.toLocal8Bit()); request.setRawHeader("system", system.toLocal8Bit()); + qDebug() << url; + QNetworkReply * reply = httpUtil->sendGetRequest(request); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); } qDebug() << resultObj; - if (resultObj.find("code")->toInt() == 200) - { - ConstCache::getInstance().deviceList.clear(); - - QJsonArray data = resultObj.find("data")->toArray(); - for (int i = 0; i < data.size(); i++) - { - QJsonObject item = data.at(i).toObject(); - - ConstCache::getInstance().deviceList.append(item); - } - } return resultObj; } diff --git a/CounterAcq/common/HttpRequestController.h b/CounterAcq/common/HttpRequestController.h index 46d9b84..77fc3db 100644 --- a/CounterAcq/common/HttpRequestController.h +++ b/CounterAcq/common/HttpRequestController.h @@ -18,7 +18,7 @@ QJsonObject getTokenByClientId(QString clientId, QString key); QJsonObject initDictDeviceType(); - QJsonObject initDeviceList(); + QJsonObject initDeviceList(QString devType); private: HttpRequestUtil * httpUtil; diff --git a/CounterAcq/common/utils/QLogUtil.cpp b/CounterAcq/common/utils/QLogUtil.cpp index 458ac15..6ec3d80 100644 --- a/CounterAcq/common/utils/QLogUtil.cpp +++ b/CounterAcq/common/utils/QLogUtil.cpp @@ -34,3 +34,59 @@ } +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "\\"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "\\"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/CounterAcq/CounterDevice.cpp b/CounterAcq/CounterDevice.cpp index 1aef95a..a6f0bd1 100644 --- a/CounterAcq/CounterDevice.cpp +++ b/CounterAcq/CounterDevice.cpp @@ -2,12 +2,16 @@ #include #include +#include CounterDevice::CounterDevice(QObject *parent) : QObject(parent) { connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &CounterDevice::dataReceivedHandler); + connect(this, &CounterDevice::successDataCalculate, + this, &CounterDevice::afterFramePhase); + // kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); // kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); // kafkaUtil.createProducer(); @@ -35,6 +39,10 @@ { this->devCode = devCode; } +void CounterDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool CounterDevice::isSerialOpen() { @@ -55,7 +63,7 @@ if (CounterProtocolBM::checkFrame(this->dataBuff) == true) { counterData->rawFrame = this->dataBuff; - std::cout << counterData->rawFrame.toStdString() << std::endl; +// std::cout << counterData->rawFrame.toStdString() << std::endl; // ★解析成数据对象 bool parse = CounterProtocolBM::parseMessureData(this->dataBuff, counterData); @@ -63,36 +71,38 @@ // 解析成功 if (parse == true) { + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 补充其他字段 QDateTime now = QDateTime::currentDateTime(); counterData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); counterData->milisecond = now.toMSecsSinceEpoch(); - this->afterFramePhase(counterData); + counterData->devCode = devCode; + + // 3 计算数据ID一样的测量数据的时差值,通道值-参考通道值 + this->pushChannelRawFrame(counterData); } } // 在此处释放内存,不影响后续显示 // 不在此处释放内存则会导致内存持续增加 - // 具体原因不明 delete counterData; } void CounterDevice::afterFramePhase(CounterDataDto * counterData) { - // 1. 清空dataBuff,等待下一帧的数据 - this->dataBuff.clear(); + // 0. 输出到日志文件中 + QString date = counterData->timestamp.mid(0, 10); - // 2. 输出到日志文件中 - QString filePostfix = counterData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; - - // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + // 1. 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; QString content = counterData->timestamp + " " + counterData->rawFrame.left(counterData->rawFrame.size() - COUNTER_FRAME_TAIL.size()); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); - // 2.2 各个通道的clock diff数据 - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + // 2. 各个通道的clock diff数据 + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (counterData->channelId < 10) { chFilename = chFilename.arg(QString("0%1").arg(counterData->channelId)); @@ -100,20 +110,76 @@ { chFilename = chFilename.arg(counterData->channelId); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(counterData->timestamp).arg(counterData->channelClockValue).arg(counterData->frameId); - - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QString channelDataStr = QString("%1 [%2] %3 %4") + .arg(counterData->timestamp) + .arg(counterData->frameId) + .arg(counterData->channelData) + .arg(counterData->channelClockValue); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) { QJsonObject jsonObj = counterData->toJSON(); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); - jsonObj.insert("deviceId", devCode); + jsonObj.insert("deviceId", deviceId); // kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } // 4. 在界面上简单显示相差数据结果 emit this->sendDataToDraw(counterData); } + +void CounterDevice::pushChannelRawFrame(CounterDataDto * counterData) +{ + QString currentFrameId = counterData->frameId; + QString currentChannelId = QString("%1").arg(counterData->channelId); + + if (counterData->channelId == counterData->channelRefId) + { + // 自身是参考通道 + bench.insert(currentFrameId, counterData->channelData); + counterData->channelClockValue = 0; + + emit successDataCalculate(counterData); + + qlonglong thisBench = counterData->channelData; + // 遍历temp,处理之前的临时暂存的队列 + if (hisList.isEmpty() == false) + { + for (int i = 0; i < hisList.size(); i++) + { + CounterDataDto * hisItem = hisList.at(i); + if (hisItem->frameId == currentFrameId) + { + hisItem->channelClockValue = (hisItem->channelData - thisBench) * 10; + + emit successDataCalculate(hisItem); + delete hisItem; + } + } + + hisList.clear(); + } + } else + { + // 自身不是参考通道,减去相同frameId的参考通道值 + if (bench.contains(currentFrameId) == true) + { + // 在参考基准中能找到 + qlonglong currentBench = bench.find(currentFrameId).value(); + counterData->channelClockValue = (counterData->channelData - currentBench) * 10; // 10ps + + emit successDataCalculate(counterData); + } else + { + // 暂存,等收到基准之后再处置 + CounterDataDto * copyPoint = new CounterDataDto(); + + // ★clone一份对象,存入缓存队列 + counterData->clone(copyPoint); + + hisList.append(copyPoint); + } + } +} diff --git a/CounterAcq/CounterDevice.h b/CounterAcq/CounterDevice.h index 3572d69..b15e44f 100644 --- a/CounterAcq/CounterDevice.h +++ b/CounterAcq/CounterDevice.h @@ -19,16 +19,16 @@ void initSerialPort(); - void afterFramePhase(CounterDataDto * counterData); - void setComName(QString comName); void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; @@ -37,11 +37,18 @@ // QKafkaUtil kafkaUtil; QByteArray dataBuff; + QMap bench; + QList hisList; + + void pushChannelRawFrame(CounterDataDto * counterData); + signals: void sendDataToDraw(CounterDataDto * counterData); + void successDataCalculate(CounterDataDto * counterData); public slots: void dataReceivedHandler(QByteArray data); + void afterFramePhase(CounterDataDto * counterData); }; #endif // COUNTERDEVICE_H diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 31d43fd..f8278f6 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -5,12 +5,12 @@ #include #include #include +#include +#include #include -#include -#include #include -#include #include +#include CounterWindow::CounterWindow(QWidget *parent) : QWidget(parent), @@ -18,56 +18,74 @@ { ui->setupUi(this); + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), 700); + resize(screenRect.width(), screenRect.height()); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); - - for (int i = 0; i < comDevList.size(); i++) - { - CounterDevice * device = new CounterDevice(this); - - // - connect(device, &CounterDevice::sendDataToDraw, - this, &CounterWindow::drawCounterDataOnPage); - - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); - - device->setDevCode(devCodeList.at(i)); - - this->deviceList.append(device); - -// device->initSerialPort(); -// device->startWork(); - } - - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget = new QWidget(this->ui->stackedWidget); - ui->stackedWidget->addWidget(devWidget); - devWidgetList.append(devWidget); - - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); httpReq = new HttpRequestController(this); - QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, - SettingConfig::getInstance().APP_KEY); - if (response.find("code")->toInt() == 200) + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - httpReq->initDictDeviceType(); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - httpReq->initDeviceList(); + QApplication::exit(0); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); + + // 3. 获取计数器设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); + + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i =0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); + + CounterDevice * device = new CounterDevice(this); + deviceList.append(device); + + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &CounterDevice::sendDataToDraw, + this, &CounterWindow::drawCounterDataOnPage); + + device->initSerialPort(); + + QThread::msleep(200); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } -// timer = new QTimer(this); -// timer->start(1000 * 10); + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } CounterWindow::~CounterWindow() @@ -75,110 +93,153 @@ delete ui; } -void CounterWindow::generateWidgetForDevice(QString devCode, int index) +void CounterWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(75); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(75); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * refChLabel = new QLabel(); + refChLabel->setText("参考通道"); + refChLabel->setFont(labelFont); + refChLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(refChLabel); + QLineEdit * refChValue = new QLineEdit(); + refChValue->setFixedWidth(60); + refChValue->setFont(labelFont); + vbox->addWidget(refChValue); + + QLabel * loadLabel = new QLabel(); + loadLabel->setText("负载"); + loadLabel->setFont(labelFont); + loadLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(loadLabel); + QLineEdit * loadValue = new QLineEdit(); + loadValue->setFixedWidth(60); + loadValue->setFont(labelFont); + vbox->addWidget(loadValue); + + QLabel * levelLabel = new QLabel(); + levelLabel->setText("触发电平"); + levelLabel->setFont(labelFont); + levelLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(levelLabel); + QLineEdit * levelValue = new QLineEdit(); + levelValue->setFixedWidth(60); + levelValue->setFont(labelFont); + vbox->addWidget(levelValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,clock").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } void CounterWindow::drawCounterDataOnPage(CounterDataDto * counterData) { // 1. 判断数据属于哪个设备,显示在不同的widget上 +// qDebug() << counterData->toJSON() << counterData->devCode << "---" << counterData->frameId; - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - QList row; - QStandardItem * itemTm = 0; - QStandardItem * itemData = 0; - itemTm = new QStandardItem(QString("%1").arg(counterData->timestamp.mid(11, 12))); - itemData = new QStandardItem(QString("%1").arg(counterData->channelData)); + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - row.append(itemTm); - row.append(itemData); - - QStandardItemModel * model; - model = devChannels.at(counterData->channelId - 1); - if (model->rowCount() >= 20) + // 如果不是当前设备的帧,直接返回 + if (counterData->devCode != currentDevCode) { - model->removeRows(0, model->rowCount()); + return; } - model->insertRow(0, row); + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(counterData->channelId); + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(counterData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 ps").arg(counterData->channelClockValue)); + ((QLineEdit *)channelBox->children().at(6))->setText(counterData->frameId); + ((QLineEdit *)channelBox->children().at(8))->setText(QString("%1").arg(counterData->channelRefId)); + ((QLineEdit *)channelBox->children().at(10))->setText(QString("%1 Ω").arg(counterData->load == 1 ? "1M" : "50")); + ((QLineEdit *)channelBox->children().at(12))->setText(QString("%1 V").arg(counterData->level)); + ((QLabel *)channelBox->children().at(13))->setText(counterData->channelActive == 1 ? "有效" : "无效"); +} -// for (int i = 0; i < counterData->channelData.size(); i++) -// { -// if (counterData->channelActive.at(i).toInt() == 1) -// { -// QList row; -// QStandardItem * item = 0; -// QStandardItem * item2 = 0; -// item = new QStandardItem(QString("%1").arg(counterData->timestamp.mid(11, 12))); -// item2 = new QStandardItem(QString("%1").arg(counterData->channelData.at(i))); +int CounterWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int CounterWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject CounterWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("计数器"); + return response; +} -// row.append(item); -// row.append(item2); +void CounterWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} -// QStandardItemModel * model; -// model = devChannels.at(i); -// if (model->rowCount() >= 60) -// { -// model->removeRows(0, model->rowCount()); -// } - -// model->insertRow(0, row); -// } -// } +void CounterWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); } diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 88ec496..3273433 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -2,7 +2,9 @@ #define COUNTERWINDOW_H #include +#include #include +#include #include "common/utils/SettingConfig.h" //#include "common/utils/QKafkaUtil.h" @@ -26,18 +28,24 @@ public slots: void drawCounterDataOnPage(CounterDataDto * counterData); +private slots: + void on_exitButt_clicked(); + + void on_minButt_clicked(); + private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + Ui::CounterWindow *ui; QTimer * timer; HttpRequestController * httpReq; - QList devWidgetList; - QList deviceList; - QList> tableModelList; - void generateWidgetForDevice(QString devCode, int index); + void generateWidgetForDevice(); }; #endif // COUNTERWINDOW_H diff --git a/CounterAcq/CounterWindow.ui b/CounterAcq/CounterWindow.ui index bcf9570..9ac6eb3 100644 --- a/CounterAcq/CounterWindow.ui +++ b/CounterAcq/CounterWindow.ui @@ -1,29 +1,156 @@ - - CounterWindow - - - - 0 - 0 - 1024 - 720 - - - - 多通道计数器数据采集 - - - - - 0 - 0 - 1024 - 720 - - - - - - - + + CounterWindow + + + + 0 + 0 + 1024 + 720 + + + + 多通道计数器数据采集 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 400 + 10 + 250 + 40 + + + + + + + 250 + 0 + 150 + 60 + + + + + 微软雅黑 + 12 + + + + Qt::LeftToRight + + + 请选择计数器 + + + Qt::AlignCenter + + + + + + 880 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 20 + 0 + 200 + 60 + + + + + 微软雅黑 + 14 + + + + 多通道计数器数据采集 + + + + + + 0 + 59 + 1024 + 1 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 830 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + diff --git a/CounterAcq/common/HttpRequestController.cpp b/CounterAcq/common/HttpRequestController.cpp index 500f902..d4912b8 100644 --- a/CounterAcq/common/HttpRequestController.cpp +++ b/CounterAcq/common/HttpRequestController.cpp @@ -38,18 +38,21 @@ document.setObject(paramObj); QByteArray content = document.toJson(QJsonDocument::Compact); - QNetworkReply *reply = httpUtil->sendPostRequest(request, content); + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); - } - if (resultObj.find("code")->toInt() == 200) + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else { - QString token = resultObj.find("data")->toString(); - this->token = token; + resultObj.insert("code", -1); } return resultObj; @@ -72,36 +75,39 @@ QNetworkReply * reply = httpUtil->sendGetRequest(request); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); - } - if (resultObj.find("code")->toInt() == 200) - { - ConstCache::getInstance().deviceTypes.clear(); - - QJsonArray data = resultObj.find("data")->toArray(); - for (int i = 0; i < data.size(); i++) + if (resultObj.find("code")->toInt() == 200) { - QJsonObject item = data.at(i).toObject(); + ConstCache::getInstance().deviceTypes.clear(); - ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } } + } else + { + resultObj.insert("code", -1); } return resultObj; } -QJsonObject HttpRequestController::initDeviceList() +QJsonObject HttpRequestController::initDeviceList(QString devType) { QJsonObject resultObj; - QString counterDevType = "01"; + QString counterDevType = ""; QMapIterator it(ConstCache::getInstance().deviceTypes); while (it.hasNext()) { it.next(); - if (it.value().contains("计数器") == true) + if (it.value().contains(devType) == true) { counterDevType = it.key(); break; @@ -120,26 +126,32 @@ request.setRawHeader("token", token.toLocal8Bit()); request.setRawHeader("system", system.toLocal8Bit()); + qDebug() << url; + QNetworkReply * reply = httpUtil->sendGetRequest(request); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); } qDebug() << resultObj; - if (resultObj.find("code")->toInt() == 200) - { - ConstCache::getInstance().deviceList.clear(); - - QJsonArray data = resultObj.find("data")->toArray(); - for (int i = 0; i < data.size(); i++) - { - QJsonObject item = data.at(i).toObject(); - - ConstCache::getInstance().deviceList.append(item); - } - } return resultObj; } diff --git a/CounterAcq/common/HttpRequestController.h b/CounterAcq/common/HttpRequestController.h index 46d9b84..77fc3db 100644 --- a/CounterAcq/common/HttpRequestController.h +++ b/CounterAcq/common/HttpRequestController.h @@ -18,7 +18,7 @@ QJsonObject getTokenByClientId(QString clientId, QString key); QJsonObject initDictDeviceType(); - QJsonObject initDeviceList(); + QJsonObject initDeviceList(QString devType); private: HttpRequestUtil * httpUtil; diff --git a/CounterAcq/common/utils/QLogUtil.cpp b/CounterAcq/common/utils/QLogUtil.cpp index 458ac15..6ec3d80 100644 --- a/CounterAcq/common/utils/QLogUtil.cpp +++ b/CounterAcq/common/utils/QLogUtil.cpp @@ -34,3 +34,59 @@ } +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "\\"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "\\"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/CounterAcq/common/utils/QLogUtil.h b/CounterAcq/common/utils/QLogUtil.h index 8da0fcd..1d1ef0f 100644 --- a/CounterAcq/common/utils/QLogUtil.h +++ b/CounterAcq/common/utils/QLogUtil.h @@ -3,7 +3,9 @@ #include #include +#include #include +#include "SettingConfig.h" class QLogUtil : public QObject { @@ -16,6 +18,11 @@ static void writeInfoLog(QString message); static void writeDebugLog(QString message); + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); signals: }; diff --git a/CounterAcq/CounterDevice.cpp b/CounterAcq/CounterDevice.cpp index 1aef95a..a6f0bd1 100644 --- a/CounterAcq/CounterDevice.cpp +++ b/CounterAcq/CounterDevice.cpp @@ -2,12 +2,16 @@ #include #include +#include CounterDevice::CounterDevice(QObject *parent) : QObject(parent) { connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &CounterDevice::dataReceivedHandler); + connect(this, &CounterDevice::successDataCalculate, + this, &CounterDevice::afterFramePhase); + // kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); // kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); // kafkaUtil.createProducer(); @@ -35,6 +39,10 @@ { this->devCode = devCode; } +void CounterDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool CounterDevice::isSerialOpen() { @@ -55,7 +63,7 @@ if (CounterProtocolBM::checkFrame(this->dataBuff) == true) { counterData->rawFrame = this->dataBuff; - std::cout << counterData->rawFrame.toStdString() << std::endl; +// std::cout << counterData->rawFrame.toStdString() << std::endl; // ★解析成数据对象 bool parse = CounterProtocolBM::parseMessureData(this->dataBuff, counterData); @@ -63,36 +71,38 @@ // 解析成功 if (parse == true) { + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 补充其他字段 QDateTime now = QDateTime::currentDateTime(); counterData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); counterData->milisecond = now.toMSecsSinceEpoch(); - this->afterFramePhase(counterData); + counterData->devCode = devCode; + + // 3 计算数据ID一样的测量数据的时差值,通道值-参考通道值 + this->pushChannelRawFrame(counterData); } } // 在此处释放内存,不影响后续显示 // 不在此处释放内存则会导致内存持续增加 - // 具体原因不明 delete counterData; } void CounterDevice::afterFramePhase(CounterDataDto * counterData) { - // 1. 清空dataBuff,等待下一帧的数据 - this->dataBuff.clear(); + // 0. 输出到日志文件中 + QString date = counterData->timestamp.mid(0, 10); - // 2. 输出到日志文件中 - QString filePostfix = counterData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; - - // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + // 1. 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; QString content = counterData->timestamp + " " + counterData->rawFrame.left(counterData->rawFrame.size() - COUNTER_FRAME_TAIL.size()); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); - // 2.2 各个通道的clock diff数据 - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + // 2. 各个通道的clock diff数据 + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (counterData->channelId < 10) { chFilename = chFilename.arg(QString("0%1").arg(counterData->channelId)); @@ -100,20 +110,76 @@ { chFilename = chFilename.arg(counterData->channelId); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(counterData->timestamp).arg(counterData->channelClockValue).arg(counterData->frameId); - - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QString channelDataStr = QString("%1 [%2] %3 %4") + .arg(counterData->timestamp) + .arg(counterData->frameId) + .arg(counterData->channelData) + .arg(counterData->channelClockValue); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) { QJsonObject jsonObj = counterData->toJSON(); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); - jsonObj.insert("deviceId", devCode); + jsonObj.insert("deviceId", deviceId); // kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } // 4. 在界面上简单显示相差数据结果 emit this->sendDataToDraw(counterData); } + +void CounterDevice::pushChannelRawFrame(CounterDataDto * counterData) +{ + QString currentFrameId = counterData->frameId; + QString currentChannelId = QString("%1").arg(counterData->channelId); + + if (counterData->channelId == counterData->channelRefId) + { + // 自身是参考通道 + bench.insert(currentFrameId, counterData->channelData); + counterData->channelClockValue = 0; + + emit successDataCalculate(counterData); + + qlonglong thisBench = counterData->channelData; + // 遍历temp,处理之前的临时暂存的队列 + if (hisList.isEmpty() == false) + { + for (int i = 0; i < hisList.size(); i++) + { + CounterDataDto * hisItem = hisList.at(i); + if (hisItem->frameId == currentFrameId) + { + hisItem->channelClockValue = (hisItem->channelData - thisBench) * 10; + + emit successDataCalculate(hisItem); + delete hisItem; + } + } + + hisList.clear(); + } + } else + { + // 自身不是参考通道,减去相同frameId的参考通道值 + if (bench.contains(currentFrameId) == true) + { + // 在参考基准中能找到 + qlonglong currentBench = bench.find(currentFrameId).value(); + counterData->channelClockValue = (counterData->channelData - currentBench) * 10; // 10ps + + emit successDataCalculate(counterData); + } else + { + // 暂存,等收到基准之后再处置 + CounterDataDto * copyPoint = new CounterDataDto(); + + // ★clone一份对象,存入缓存队列 + counterData->clone(copyPoint); + + hisList.append(copyPoint); + } + } +} diff --git a/CounterAcq/CounterDevice.h b/CounterAcq/CounterDevice.h index 3572d69..b15e44f 100644 --- a/CounterAcq/CounterDevice.h +++ b/CounterAcq/CounterDevice.h @@ -19,16 +19,16 @@ void initSerialPort(); - void afterFramePhase(CounterDataDto * counterData); - void setComName(QString comName); void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; @@ -37,11 +37,18 @@ // QKafkaUtil kafkaUtil; QByteArray dataBuff; + QMap bench; + QList hisList; + + void pushChannelRawFrame(CounterDataDto * counterData); + signals: void sendDataToDraw(CounterDataDto * counterData); + void successDataCalculate(CounterDataDto * counterData); public slots: void dataReceivedHandler(QByteArray data); + void afterFramePhase(CounterDataDto * counterData); }; #endif // COUNTERDEVICE_H diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 31d43fd..f8278f6 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -5,12 +5,12 @@ #include #include #include +#include +#include #include -#include -#include #include -#include #include +#include CounterWindow::CounterWindow(QWidget *parent) : QWidget(parent), @@ -18,56 +18,74 @@ { ui->setupUi(this); + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), 700); + resize(screenRect.width(), screenRect.height()); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); - - for (int i = 0; i < comDevList.size(); i++) - { - CounterDevice * device = new CounterDevice(this); - - // - connect(device, &CounterDevice::sendDataToDraw, - this, &CounterWindow::drawCounterDataOnPage); - - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); - - device->setDevCode(devCodeList.at(i)); - - this->deviceList.append(device); - -// device->initSerialPort(); -// device->startWork(); - } - - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget = new QWidget(this->ui->stackedWidget); - ui->stackedWidget->addWidget(devWidget); - devWidgetList.append(devWidget); - - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); httpReq = new HttpRequestController(this); - QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, - SettingConfig::getInstance().APP_KEY); - if (response.find("code")->toInt() == 200) + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - httpReq->initDictDeviceType(); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - httpReq->initDeviceList(); + QApplication::exit(0); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); + + // 3. 获取计数器设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); + + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i =0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); + + CounterDevice * device = new CounterDevice(this); + deviceList.append(device); + + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &CounterDevice::sendDataToDraw, + this, &CounterWindow::drawCounterDataOnPage); + + device->initSerialPort(); + + QThread::msleep(200); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } -// timer = new QTimer(this); -// timer->start(1000 * 10); + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } CounterWindow::~CounterWindow() @@ -75,110 +93,153 @@ delete ui; } -void CounterWindow::generateWidgetForDevice(QString devCode, int index) +void CounterWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(75); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(75); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * refChLabel = new QLabel(); + refChLabel->setText("参考通道"); + refChLabel->setFont(labelFont); + refChLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(refChLabel); + QLineEdit * refChValue = new QLineEdit(); + refChValue->setFixedWidth(60); + refChValue->setFont(labelFont); + vbox->addWidget(refChValue); + + QLabel * loadLabel = new QLabel(); + loadLabel->setText("负载"); + loadLabel->setFont(labelFont); + loadLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(loadLabel); + QLineEdit * loadValue = new QLineEdit(); + loadValue->setFixedWidth(60); + loadValue->setFont(labelFont); + vbox->addWidget(loadValue); + + QLabel * levelLabel = new QLabel(); + levelLabel->setText("触发电平"); + levelLabel->setFont(labelFont); + levelLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(levelLabel); + QLineEdit * levelValue = new QLineEdit(); + levelValue->setFixedWidth(60); + levelValue->setFont(labelFont); + vbox->addWidget(levelValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,clock").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } void CounterWindow::drawCounterDataOnPage(CounterDataDto * counterData) { // 1. 判断数据属于哪个设备,显示在不同的widget上 +// qDebug() << counterData->toJSON() << counterData->devCode << "---" << counterData->frameId; - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - QList row; - QStandardItem * itemTm = 0; - QStandardItem * itemData = 0; - itemTm = new QStandardItem(QString("%1").arg(counterData->timestamp.mid(11, 12))); - itemData = new QStandardItem(QString("%1").arg(counterData->channelData)); + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - row.append(itemTm); - row.append(itemData); - - QStandardItemModel * model; - model = devChannels.at(counterData->channelId - 1); - if (model->rowCount() >= 20) + // 如果不是当前设备的帧,直接返回 + if (counterData->devCode != currentDevCode) { - model->removeRows(0, model->rowCount()); + return; } - model->insertRow(0, row); + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(counterData->channelId); + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(counterData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 ps").arg(counterData->channelClockValue)); + ((QLineEdit *)channelBox->children().at(6))->setText(counterData->frameId); + ((QLineEdit *)channelBox->children().at(8))->setText(QString("%1").arg(counterData->channelRefId)); + ((QLineEdit *)channelBox->children().at(10))->setText(QString("%1 Ω").arg(counterData->load == 1 ? "1M" : "50")); + ((QLineEdit *)channelBox->children().at(12))->setText(QString("%1 V").arg(counterData->level)); + ((QLabel *)channelBox->children().at(13))->setText(counterData->channelActive == 1 ? "有效" : "无效"); +} -// for (int i = 0; i < counterData->channelData.size(); i++) -// { -// if (counterData->channelActive.at(i).toInt() == 1) -// { -// QList row; -// QStandardItem * item = 0; -// QStandardItem * item2 = 0; -// item = new QStandardItem(QString("%1").arg(counterData->timestamp.mid(11, 12))); -// item2 = new QStandardItem(QString("%1").arg(counterData->channelData.at(i))); +int CounterWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int CounterWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject CounterWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("计数器"); + return response; +} -// row.append(item); -// row.append(item2); +void CounterWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} -// QStandardItemModel * model; -// model = devChannels.at(i); -// if (model->rowCount() >= 60) -// { -// model->removeRows(0, model->rowCount()); -// } - -// model->insertRow(0, row); -// } -// } +void CounterWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); } diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 88ec496..3273433 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -2,7 +2,9 @@ #define COUNTERWINDOW_H #include +#include #include +#include #include "common/utils/SettingConfig.h" //#include "common/utils/QKafkaUtil.h" @@ -26,18 +28,24 @@ public slots: void drawCounterDataOnPage(CounterDataDto * counterData); +private slots: + void on_exitButt_clicked(); + + void on_minButt_clicked(); + private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + Ui::CounterWindow *ui; QTimer * timer; HttpRequestController * httpReq; - QList devWidgetList; - QList deviceList; - QList> tableModelList; - void generateWidgetForDevice(QString devCode, int index); + void generateWidgetForDevice(); }; #endif // COUNTERWINDOW_H diff --git a/CounterAcq/CounterWindow.ui b/CounterAcq/CounterWindow.ui index bcf9570..9ac6eb3 100644 --- a/CounterAcq/CounterWindow.ui +++ b/CounterAcq/CounterWindow.ui @@ -1,29 +1,156 @@ - - CounterWindow - - - - 0 - 0 - 1024 - 720 - - - - 多通道计数器数据采集 - - - - - 0 - 0 - 1024 - 720 - - - - - - - + + CounterWindow + + + + 0 + 0 + 1024 + 720 + + + + 多通道计数器数据采集 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 400 + 10 + 250 + 40 + + + + + + + 250 + 0 + 150 + 60 + + + + + 微软雅黑 + 12 + + + + Qt::LeftToRight + + + 请选择计数器 + + + Qt::AlignCenter + + + + + + 880 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 20 + 0 + 200 + 60 + + + + + 微软雅黑 + 14 + + + + 多通道计数器数据采集 + + + + + + 0 + 59 + 1024 + 1 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 830 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + diff --git a/CounterAcq/common/HttpRequestController.cpp b/CounterAcq/common/HttpRequestController.cpp index 500f902..d4912b8 100644 --- a/CounterAcq/common/HttpRequestController.cpp +++ b/CounterAcq/common/HttpRequestController.cpp @@ -38,18 +38,21 @@ document.setObject(paramObj); QByteArray content = document.toJson(QJsonDocument::Compact); - QNetworkReply *reply = httpUtil->sendPostRequest(request, content); + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); - } - if (resultObj.find("code")->toInt() == 200) + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else { - QString token = resultObj.find("data")->toString(); - this->token = token; + resultObj.insert("code", -1); } return resultObj; @@ -72,36 +75,39 @@ QNetworkReply * reply = httpUtil->sendGetRequest(request); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); - } - if (resultObj.find("code")->toInt() == 200) - { - ConstCache::getInstance().deviceTypes.clear(); - - QJsonArray data = resultObj.find("data")->toArray(); - for (int i = 0; i < data.size(); i++) + if (resultObj.find("code")->toInt() == 200) { - QJsonObject item = data.at(i).toObject(); + ConstCache::getInstance().deviceTypes.clear(); - ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } } + } else + { + resultObj.insert("code", -1); } return resultObj; } -QJsonObject HttpRequestController::initDeviceList() +QJsonObject HttpRequestController::initDeviceList(QString devType) { QJsonObject resultObj; - QString counterDevType = "01"; + QString counterDevType = ""; QMapIterator it(ConstCache::getInstance().deviceTypes); while (it.hasNext()) { it.next(); - if (it.value().contains("计数器") == true) + if (it.value().contains(devType) == true) { counterDevType = it.key(); break; @@ -120,26 +126,32 @@ request.setRawHeader("token", token.toLocal8Bit()); request.setRawHeader("system", system.toLocal8Bit()); + qDebug() << url; + QNetworkReply * reply = httpUtil->sendGetRequest(request); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); } qDebug() << resultObj; - if (resultObj.find("code")->toInt() == 200) - { - ConstCache::getInstance().deviceList.clear(); - - QJsonArray data = resultObj.find("data")->toArray(); - for (int i = 0; i < data.size(); i++) - { - QJsonObject item = data.at(i).toObject(); - - ConstCache::getInstance().deviceList.append(item); - } - } return resultObj; } diff --git a/CounterAcq/common/HttpRequestController.h b/CounterAcq/common/HttpRequestController.h index 46d9b84..77fc3db 100644 --- a/CounterAcq/common/HttpRequestController.h +++ b/CounterAcq/common/HttpRequestController.h @@ -18,7 +18,7 @@ QJsonObject getTokenByClientId(QString clientId, QString key); QJsonObject initDictDeviceType(); - QJsonObject initDeviceList(); + QJsonObject initDeviceList(QString devType); private: HttpRequestUtil * httpUtil; diff --git a/CounterAcq/common/utils/QLogUtil.cpp b/CounterAcq/common/utils/QLogUtil.cpp index 458ac15..6ec3d80 100644 --- a/CounterAcq/common/utils/QLogUtil.cpp +++ b/CounterAcq/common/utils/QLogUtil.cpp @@ -34,3 +34,59 @@ } +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "\\"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "\\"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/CounterAcq/common/utils/QLogUtil.h b/CounterAcq/common/utils/QLogUtil.h index 8da0fcd..1d1ef0f 100644 --- a/CounterAcq/common/utils/QLogUtil.h +++ b/CounterAcq/common/utils/QLogUtil.h @@ -3,7 +3,9 @@ #include #include +#include #include +#include "SettingConfig.h" class QLogUtil : public QObject { @@ -16,6 +18,11 @@ static void writeInfoLog(QString message); static void writeDebugLog(QString message); + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); signals: }; diff --git a/CounterAcq/common/utils/QSerialPortUtil.cpp b/CounterAcq/common/utils/QSerialPortUtil.cpp index 2da13b2..7af0555 100644 --- a/CounterAcq/common/utils/QSerialPortUtil.cpp +++ b/CounterAcq/common/utils/QSerialPortUtil.cpp @@ -63,7 +63,7 @@ QByteArray buffer; QString channel = QString("%1").arg(i); - QString channelRef = "1"; + QString channelRef = "3"; QString dataValue = QString("%1").arg(qrand() % 400); QString level = QString("%1").arg(qrand() % 4 / (double) 10); QString frameId = QString("%1").arg(now.toSecsSinceEpoch() % 10000); diff --git a/CounterAcq/CounterDevice.cpp b/CounterAcq/CounterDevice.cpp index 1aef95a..a6f0bd1 100644 --- a/CounterAcq/CounterDevice.cpp +++ b/CounterAcq/CounterDevice.cpp @@ -2,12 +2,16 @@ #include #include +#include CounterDevice::CounterDevice(QObject *parent) : QObject(parent) { connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &CounterDevice::dataReceivedHandler); + connect(this, &CounterDevice::successDataCalculate, + this, &CounterDevice::afterFramePhase); + // kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); // kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); // kafkaUtil.createProducer(); @@ -35,6 +39,10 @@ { this->devCode = devCode; } +void CounterDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool CounterDevice::isSerialOpen() { @@ -55,7 +63,7 @@ if (CounterProtocolBM::checkFrame(this->dataBuff) == true) { counterData->rawFrame = this->dataBuff; - std::cout << counterData->rawFrame.toStdString() << std::endl; +// std::cout << counterData->rawFrame.toStdString() << std::endl; // ★解析成数据对象 bool parse = CounterProtocolBM::parseMessureData(this->dataBuff, counterData); @@ -63,36 +71,38 @@ // 解析成功 if (parse == true) { + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 补充其他字段 QDateTime now = QDateTime::currentDateTime(); counterData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); counterData->milisecond = now.toMSecsSinceEpoch(); - this->afterFramePhase(counterData); + counterData->devCode = devCode; + + // 3 计算数据ID一样的测量数据的时差值,通道值-参考通道值 + this->pushChannelRawFrame(counterData); } } // 在此处释放内存,不影响后续显示 // 不在此处释放内存则会导致内存持续增加 - // 具体原因不明 delete counterData; } void CounterDevice::afterFramePhase(CounterDataDto * counterData) { - // 1. 清空dataBuff,等待下一帧的数据 - this->dataBuff.clear(); + // 0. 输出到日志文件中 + QString date = counterData->timestamp.mid(0, 10); - // 2. 输出到日志文件中 - QString filePostfix = counterData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; - - // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + // 1. 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; QString content = counterData->timestamp + " " + counterData->rawFrame.left(counterData->rawFrame.size() - COUNTER_FRAME_TAIL.size()); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); - // 2.2 各个通道的clock diff数据 - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + // 2. 各个通道的clock diff数据 + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (counterData->channelId < 10) { chFilename = chFilename.arg(QString("0%1").arg(counterData->channelId)); @@ -100,20 +110,76 @@ { chFilename = chFilename.arg(counterData->channelId); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(counterData->timestamp).arg(counterData->channelClockValue).arg(counterData->frameId); - - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QString channelDataStr = QString("%1 [%2] %3 %4") + .arg(counterData->timestamp) + .arg(counterData->frameId) + .arg(counterData->channelData) + .arg(counterData->channelClockValue); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) { QJsonObject jsonObj = counterData->toJSON(); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); - jsonObj.insert("deviceId", devCode); + jsonObj.insert("deviceId", deviceId); // kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } // 4. 在界面上简单显示相差数据结果 emit this->sendDataToDraw(counterData); } + +void CounterDevice::pushChannelRawFrame(CounterDataDto * counterData) +{ + QString currentFrameId = counterData->frameId; + QString currentChannelId = QString("%1").arg(counterData->channelId); + + if (counterData->channelId == counterData->channelRefId) + { + // 自身是参考通道 + bench.insert(currentFrameId, counterData->channelData); + counterData->channelClockValue = 0; + + emit successDataCalculate(counterData); + + qlonglong thisBench = counterData->channelData; + // 遍历temp,处理之前的临时暂存的队列 + if (hisList.isEmpty() == false) + { + for (int i = 0; i < hisList.size(); i++) + { + CounterDataDto * hisItem = hisList.at(i); + if (hisItem->frameId == currentFrameId) + { + hisItem->channelClockValue = (hisItem->channelData - thisBench) * 10; + + emit successDataCalculate(hisItem); + delete hisItem; + } + } + + hisList.clear(); + } + } else + { + // 自身不是参考通道,减去相同frameId的参考通道值 + if (bench.contains(currentFrameId) == true) + { + // 在参考基准中能找到 + qlonglong currentBench = bench.find(currentFrameId).value(); + counterData->channelClockValue = (counterData->channelData - currentBench) * 10; // 10ps + + emit successDataCalculate(counterData); + } else + { + // 暂存,等收到基准之后再处置 + CounterDataDto * copyPoint = new CounterDataDto(); + + // ★clone一份对象,存入缓存队列 + counterData->clone(copyPoint); + + hisList.append(copyPoint); + } + } +} diff --git a/CounterAcq/CounterDevice.h b/CounterAcq/CounterDevice.h index 3572d69..b15e44f 100644 --- a/CounterAcq/CounterDevice.h +++ b/CounterAcq/CounterDevice.h @@ -19,16 +19,16 @@ void initSerialPort(); - void afterFramePhase(CounterDataDto * counterData); - void setComName(QString comName); void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; @@ -37,11 +37,18 @@ // QKafkaUtil kafkaUtil; QByteArray dataBuff; + QMap bench; + QList hisList; + + void pushChannelRawFrame(CounterDataDto * counterData); + signals: void sendDataToDraw(CounterDataDto * counterData); + void successDataCalculate(CounterDataDto * counterData); public slots: void dataReceivedHandler(QByteArray data); + void afterFramePhase(CounterDataDto * counterData); }; #endif // COUNTERDEVICE_H diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 31d43fd..f8278f6 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -5,12 +5,12 @@ #include #include #include +#include +#include #include -#include -#include #include -#include #include +#include CounterWindow::CounterWindow(QWidget *parent) : QWidget(parent), @@ -18,56 +18,74 @@ { ui->setupUi(this); + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), 700); + resize(screenRect.width(), screenRect.height()); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); - - for (int i = 0; i < comDevList.size(); i++) - { - CounterDevice * device = new CounterDevice(this); - - // - connect(device, &CounterDevice::sendDataToDraw, - this, &CounterWindow::drawCounterDataOnPage); - - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); - - device->setDevCode(devCodeList.at(i)); - - this->deviceList.append(device); - -// device->initSerialPort(); -// device->startWork(); - } - - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget = new QWidget(this->ui->stackedWidget); - ui->stackedWidget->addWidget(devWidget); - devWidgetList.append(devWidget); - - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); httpReq = new HttpRequestController(this); - QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, - SettingConfig::getInstance().APP_KEY); - if (response.find("code")->toInt() == 200) + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - httpReq->initDictDeviceType(); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - httpReq->initDeviceList(); + QApplication::exit(0); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); + + // 3. 获取计数器设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); + + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i =0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); + + CounterDevice * device = new CounterDevice(this); + deviceList.append(device); + + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &CounterDevice::sendDataToDraw, + this, &CounterWindow::drawCounterDataOnPage); + + device->initSerialPort(); + + QThread::msleep(200); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } -// timer = new QTimer(this); -// timer->start(1000 * 10); + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } CounterWindow::~CounterWindow() @@ -75,110 +93,153 @@ delete ui; } -void CounterWindow::generateWidgetForDevice(QString devCode, int index) +void CounterWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(75); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(75); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * refChLabel = new QLabel(); + refChLabel->setText("参考通道"); + refChLabel->setFont(labelFont); + refChLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(refChLabel); + QLineEdit * refChValue = new QLineEdit(); + refChValue->setFixedWidth(60); + refChValue->setFont(labelFont); + vbox->addWidget(refChValue); + + QLabel * loadLabel = new QLabel(); + loadLabel->setText("负载"); + loadLabel->setFont(labelFont); + loadLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(loadLabel); + QLineEdit * loadValue = new QLineEdit(); + loadValue->setFixedWidth(60); + loadValue->setFont(labelFont); + vbox->addWidget(loadValue); + + QLabel * levelLabel = new QLabel(); + levelLabel->setText("触发电平"); + levelLabel->setFont(labelFont); + levelLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(levelLabel); + QLineEdit * levelValue = new QLineEdit(); + levelValue->setFixedWidth(60); + levelValue->setFont(labelFont); + vbox->addWidget(levelValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,clock").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } void CounterWindow::drawCounterDataOnPage(CounterDataDto * counterData) { // 1. 判断数据属于哪个设备,显示在不同的widget上 +// qDebug() << counterData->toJSON() << counterData->devCode << "---" << counterData->frameId; - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - QList row; - QStandardItem * itemTm = 0; - QStandardItem * itemData = 0; - itemTm = new QStandardItem(QString("%1").arg(counterData->timestamp.mid(11, 12))); - itemData = new QStandardItem(QString("%1").arg(counterData->channelData)); + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - row.append(itemTm); - row.append(itemData); - - QStandardItemModel * model; - model = devChannels.at(counterData->channelId - 1); - if (model->rowCount() >= 20) + // 如果不是当前设备的帧,直接返回 + if (counterData->devCode != currentDevCode) { - model->removeRows(0, model->rowCount()); + return; } - model->insertRow(0, row); + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(counterData->channelId); + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(counterData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 ps").arg(counterData->channelClockValue)); + ((QLineEdit *)channelBox->children().at(6))->setText(counterData->frameId); + ((QLineEdit *)channelBox->children().at(8))->setText(QString("%1").arg(counterData->channelRefId)); + ((QLineEdit *)channelBox->children().at(10))->setText(QString("%1 Ω").arg(counterData->load == 1 ? "1M" : "50")); + ((QLineEdit *)channelBox->children().at(12))->setText(QString("%1 V").arg(counterData->level)); + ((QLabel *)channelBox->children().at(13))->setText(counterData->channelActive == 1 ? "有效" : "无效"); +} -// for (int i = 0; i < counterData->channelData.size(); i++) -// { -// if (counterData->channelActive.at(i).toInt() == 1) -// { -// QList row; -// QStandardItem * item = 0; -// QStandardItem * item2 = 0; -// item = new QStandardItem(QString("%1").arg(counterData->timestamp.mid(11, 12))); -// item2 = new QStandardItem(QString("%1").arg(counterData->channelData.at(i))); +int CounterWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int CounterWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject CounterWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("计数器"); + return response; +} -// row.append(item); -// row.append(item2); +void CounterWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} -// QStandardItemModel * model; -// model = devChannels.at(i); -// if (model->rowCount() >= 60) -// { -// model->removeRows(0, model->rowCount()); -// } - -// model->insertRow(0, row); -// } -// } +void CounterWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); } diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 88ec496..3273433 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -2,7 +2,9 @@ #define COUNTERWINDOW_H #include +#include #include +#include #include "common/utils/SettingConfig.h" //#include "common/utils/QKafkaUtil.h" @@ -26,18 +28,24 @@ public slots: void drawCounterDataOnPage(CounterDataDto * counterData); +private slots: + void on_exitButt_clicked(); + + void on_minButt_clicked(); + private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + Ui::CounterWindow *ui; QTimer * timer; HttpRequestController * httpReq; - QList devWidgetList; - QList deviceList; - QList> tableModelList; - void generateWidgetForDevice(QString devCode, int index); + void generateWidgetForDevice(); }; #endif // COUNTERWINDOW_H diff --git a/CounterAcq/CounterWindow.ui b/CounterAcq/CounterWindow.ui index bcf9570..9ac6eb3 100644 --- a/CounterAcq/CounterWindow.ui +++ b/CounterAcq/CounterWindow.ui @@ -1,29 +1,156 @@ - - CounterWindow - - - - 0 - 0 - 1024 - 720 - - - - 多通道计数器数据采集 - - - - - 0 - 0 - 1024 - 720 - - - - - - - + + CounterWindow + + + + 0 + 0 + 1024 + 720 + + + + 多通道计数器数据采集 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 400 + 10 + 250 + 40 + + + + + + + 250 + 0 + 150 + 60 + + + + + 微软雅黑 + 12 + + + + Qt::LeftToRight + + + 请选择计数器 + + + Qt::AlignCenter + + + + + + 880 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 20 + 0 + 200 + 60 + + + + + 微软雅黑 + 14 + + + + 多通道计数器数据采集 + + + + + + 0 + 59 + 1024 + 1 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 830 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + diff --git a/CounterAcq/common/HttpRequestController.cpp b/CounterAcq/common/HttpRequestController.cpp index 500f902..d4912b8 100644 --- a/CounterAcq/common/HttpRequestController.cpp +++ b/CounterAcq/common/HttpRequestController.cpp @@ -38,18 +38,21 @@ document.setObject(paramObj); QByteArray content = document.toJson(QJsonDocument::Compact); - QNetworkReply *reply = httpUtil->sendPostRequest(request, content); + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); - } - if (resultObj.find("code")->toInt() == 200) + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else { - QString token = resultObj.find("data")->toString(); - this->token = token; + resultObj.insert("code", -1); } return resultObj; @@ -72,36 +75,39 @@ QNetworkReply * reply = httpUtil->sendGetRequest(request); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); - } - if (resultObj.find("code")->toInt() == 200) - { - ConstCache::getInstance().deviceTypes.clear(); - - QJsonArray data = resultObj.find("data")->toArray(); - for (int i = 0; i < data.size(); i++) + if (resultObj.find("code")->toInt() == 200) { - QJsonObject item = data.at(i).toObject(); + ConstCache::getInstance().deviceTypes.clear(); - ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } } + } else + { + resultObj.insert("code", -1); } return resultObj; } -QJsonObject HttpRequestController::initDeviceList() +QJsonObject HttpRequestController::initDeviceList(QString devType) { QJsonObject resultObj; - QString counterDevType = "01"; + QString counterDevType = ""; QMapIterator it(ConstCache::getInstance().deviceTypes); while (it.hasNext()) { it.next(); - if (it.value().contains("计数器") == true) + if (it.value().contains(devType) == true) { counterDevType = it.key(); break; @@ -120,26 +126,32 @@ request.setRawHeader("token", token.toLocal8Bit()); request.setRawHeader("system", system.toLocal8Bit()); + qDebug() << url; + QNetworkReply * reply = httpUtil->sendGetRequest(request); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); } qDebug() << resultObj; - if (resultObj.find("code")->toInt() == 200) - { - ConstCache::getInstance().deviceList.clear(); - - QJsonArray data = resultObj.find("data")->toArray(); - for (int i = 0; i < data.size(); i++) - { - QJsonObject item = data.at(i).toObject(); - - ConstCache::getInstance().deviceList.append(item); - } - } return resultObj; } diff --git a/CounterAcq/common/HttpRequestController.h b/CounterAcq/common/HttpRequestController.h index 46d9b84..77fc3db 100644 --- a/CounterAcq/common/HttpRequestController.h +++ b/CounterAcq/common/HttpRequestController.h @@ -18,7 +18,7 @@ QJsonObject getTokenByClientId(QString clientId, QString key); QJsonObject initDictDeviceType(); - QJsonObject initDeviceList(); + QJsonObject initDeviceList(QString devType); private: HttpRequestUtil * httpUtil; diff --git a/CounterAcq/common/utils/QLogUtil.cpp b/CounterAcq/common/utils/QLogUtil.cpp index 458ac15..6ec3d80 100644 --- a/CounterAcq/common/utils/QLogUtil.cpp +++ b/CounterAcq/common/utils/QLogUtil.cpp @@ -34,3 +34,59 @@ } +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "\\"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "\\"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/CounterAcq/common/utils/QLogUtil.h b/CounterAcq/common/utils/QLogUtil.h index 8da0fcd..1d1ef0f 100644 --- a/CounterAcq/common/utils/QLogUtil.h +++ b/CounterAcq/common/utils/QLogUtil.h @@ -3,7 +3,9 @@ #include #include +#include #include +#include "SettingConfig.h" class QLogUtil : public QObject { @@ -16,6 +18,11 @@ static void writeInfoLog(QString message); static void writeDebugLog(QString message); + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); signals: }; diff --git a/CounterAcq/common/utils/QSerialPortUtil.cpp b/CounterAcq/common/utils/QSerialPortUtil.cpp index 2da13b2..7af0555 100644 --- a/CounterAcq/common/utils/QSerialPortUtil.cpp +++ b/CounterAcq/common/utils/QSerialPortUtil.cpp @@ -63,7 +63,7 @@ QByteArray buffer; QString channel = QString("%1").arg(i); - QString channelRef = "1"; + QString channelRef = "3"; QString dataValue = QString("%1").arg(qrand() % 400); QString level = QString("%1").arg(qrand() % 4 / (double) 10); QString frameId = QString("%1").arg(now.toSecsSinceEpoch() % 10000); diff --git a/CounterAcq/common/utils/SettingConfig.cpp b/CounterAcq/common/utils/SettingConfig.cpp index e9d136e..1f2ebb2 100644 --- a/CounterAcq/common/utils/SettingConfig.cpp +++ b/CounterAcq/common/utils/SettingConfig.cpp @@ -5,9 +5,7 @@ filename = QApplication::applicationDirPath() + "/conf/config.ini"; setting = new QSettings(this->filename, QSettings::IniFormat); - PORT_NAMES = getProperty("com", "portNames").toString(); BAUD_RATE = getProperty("com", "baudRate").toUInt(); - DEV_CODES = getProperty("com", "devCodes").toString(); NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); @@ -17,6 +15,8 @@ APP_KEY = getProperty("client", "appKey").toString(); BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); } diff --git a/CounterAcq/CounterDevice.cpp b/CounterAcq/CounterDevice.cpp index 1aef95a..a6f0bd1 100644 --- a/CounterAcq/CounterDevice.cpp +++ b/CounterAcq/CounterDevice.cpp @@ -2,12 +2,16 @@ #include #include +#include CounterDevice::CounterDevice(QObject *parent) : QObject(parent) { connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &CounterDevice::dataReceivedHandler); + connect(this, &CounterDevice::successDataCalculate, + this, &CounterDevice::afterFramePhase); + // kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); // kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); // kafkaUtil.createProducer(); @@ -35,6 +39,10 @@ { this->devCode = devCode; } +void CounterDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool CounterDevice::isSerialOpen() { @@ -55,7 +63,7 @@ if (CounterProtocolBM::checkFrame(this->dataBuff) == true) { counterData->rawFrame = this->dataBuff; - std::cout << counterData->rawFrame.toStdString() << std::endl; +// std::cout << counterData->rawFrame.toStdString() << std::endl; // ★解析成数据对象 bool parse = CounterProtocolBM::parseMessureData(this->dataBuff, counterData); @@ -63,36 +71,38 @@ // 解析成功 if (parse == true) { + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 补充其他字段 QDateTime now = QDateTime::currentDateTime(); counterData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); counterData->milisecond = now.toMSecsSinceEpoch(); - this->afterFramePhase(counterData); + counterData->devCode = devCode; + + // 3 计算数据ID一样的测量数据的时差值,通道值-参考通道值 + this->pushChannelRawFrame(counterData); } } // 在此处释放内存,不影响后续显示 // 不在此处释放内存则会导致内存持续增加 - // 具体原因不明 delete counterData; } void CounterDevice::afterFramePhase(CounterDataDto * counterData) { - // 1. 清空dataBuff,等待下一帧的数据 - this->dataBuff.clear(); + // 0. 输出到日志文件中 + QString date = counterData->timestamp.mid(0, 10); - // 2. 输出到日志文件中 - QString filePostfix = counterData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; - - // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + // 1. 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; QString content = counterData->timestamp + " " + counterData->rawFrame.left(counterData->rawFrame.size() - COUNTER_FRAME_TAIL.size()); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); - // 2.2 各个通道的clock diff数据 - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + // 2. 各个通道的clock diff数据 + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (counterData->channelId < 10) { chFilename = chFilename.arg(QString("0%1").arg(counterData->channelId)); @@ -100,20 +110,76 @@ { chFilename = chFilename.arg(counterData->channelId); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(counterData->timestamp).arg(counterData->channelClockValue).arg(counterData->frameId); - - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QString channelDataStr = QString("%1 [%2] %3 %4") + .arg(counterData->timestamp) + .arg(counterData->frameId) + .arg(counterData->channelData) + .arg(counterData->channelClockValue); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) { QJsonObject jsonObj = counterData->toJSON(); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); - jsonObj.insert("deviceId", devCode); + jsonObj.insert("deviceId", deviceId); // kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } // 4. 在界面上简单显示相差数据结果 emit this->sendDataToDraw(counterData); } + +void CounterDevice::pushChannelRawFrame(CounterDataDto * counterData) +{ + QString currentFrameId = counterData->frameId; + QString currentChannelId = QString("%1").arg(counterData->channelId); + + if (counterData->channelId == counterData->channelRefId) + { + // 自身是参考通道 + bench.insert(currentFrameId, counterData->channelData); + counterData->channelClockValue = 0; + + emit successDataCalculate(counterData); + + qlonglong thisBench = counterData->channelData; + // 遍历temp,处理之前的临时暂存的队列 + if (hisList.isEmpty() == false) + { + for (int i = 0; i < hisList.size(); i++) + { + CounterDataDto * hisItem = hisList.at(i); + if (hisItem->frameId == currentFrameId) + { + hisItem->channelClockValue = (hisItem->channelData - thisBench) * 10; + + emit successDataCalculate(hisItem); + delete hisItem; + } + } + + hisList.clear(); + } + } else + { + // 自身不是参考通道,减去相同frameId的参考通道值 + if (bench.contains(currentFrameId) == true) + { + // 在参考基准中能找到 + qlonglong currentBench = bench.find(currentFrameId).value(); + counterData->channelClockValue = (counterData->channelData - currentBench) * 10; // 10ps + + emit successDataCalculate(counterData); + } else + { + // 暂存,等收到基准之后再处置 + CounterDataDto * copyPoint = new CounterDataDto(); + + // ★clone一份对象,存入缓存队列 + counterData->clone(copyPoint); + + hisList.append(copyPoint); + } + } +} diff --git a/CounterAcq/CounterDevice.h b/CounterAcq/CounterDevice.h index 3572d69..b15e44f 100644 --- a/CounterAcq/CounterDevice.h +++ b/CounterAcq/CounterDevice.h @@ -19,16 +19,16 @@ void initSerialPort(); - void afterFramePhase(CounterDataDto * counterData); - void setComName(QString comName); void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; @@ -37,11 +37,18 @@ // QKafkaUtil kafkaUtil; QByteArray dataBuff; + QMap bench; + QList hisList; + + void pushChannelRawFrame(CounterDataDto * counterData); + signals: void sendDataToDraw(CounterDataDto * counterData); + void successDataCalculate(CounterDataDto * counterData); public slots: void dataReceivedHandler(QByteArray data); + void afterFramePhase(CounterDataDto * counterData); }; #endif // COUNTERDEVICE_H diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 31d43fd..f8278f6 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -5,12 +5,12 @@ #include #include #include +#include +#include #include -#include -#include #include -#include #include +#include CounterWindow::CounterWindow(QWidget *parent) : QWidget(parent), @@ -18,56 +18,74 @@ { ui->setupUi(this); + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), 700); + resize(screenRect.width(), screenRect.height()); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); - - for (int i = 0; i < comDevList.size(); i++) - { - CounterDevice * device = new CounterDevice(this); - - // - connect(device, &CounterDevice::sendDataToDraw, - this, &CounterWindow::drawCounterDataOnPage); - - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); - - device->setDevCode(devCodeList.at(i)); - - this->deviceList.append(device); - -// device->initSerialPort(); -// device->startWork(); - } - - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget = new QWidget(this->ui->stackedWidget); - ui->stackedWidget->addWidget(devWidget); - devWidgetList.append(devWidget); - - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); httpReq = new HttpRequestController(this); - QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, - SettingConfig::getInstance().APP_KEY); - if (response.find("code")->toInt() == 200) + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - httpReq->initDictDeviceType(); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - httpReq->initDeviceList(); + QApplication::exit(0); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); + + // 3. 获取计数器设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); + + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i =0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); + + CounterDevice * device = new CounterDevice(this); + deviceList.append(device); + + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &CounterDevice::sendDataToDraw, + this, &CounterWindow::drawCounterDataOnPage); + + device->initSerialPort(); + + QThread::msleep(200); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } -// timer = new QTimer(this); -// timer->start(1000 * 10); + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } CounterWindow::~CounterWindow() @@ -75,110 +93,153 @@ delete ui; } -void CounterWindow::generateWidgetForDevice(QString devCode, int index) +void CounterWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(75); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(75); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * refChLabel = new QLabel(); + refChLabel->setText("参考通道"); + refChLabel->setFont(labelFont); + refChLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(refChLabel); + QLineEdit * refChValue = new QLineEdit(); + refChValue->setFixedWidth(60); + refChValue->setFont(labelFont); + vbox->addWidget(refChValue); + + QLabel * loadLabel = new QLabel(); + loadLabel->setText("负载"); + loadLabel->setFont(labelFont); + loadLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(loadLabel); + QLineEdit * loadValue = new QLineEdit(); + loadValue->setFixedWidth(60); + loadValue->setFont(labelFont); + vbox->addWidget(loadValue); + + QLabel * levelLabel = new QLabel(); + levelLabel->setText("触发电平"); + levelLabel->setFont(labelFont); + levelLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(levelLabel); + QLineEdit * levelValue = new QLineEdit(); + levelValue->setFixedWidth(60); + levelValue->setFont(labelFont); + vbox->addWidget(levelValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,clock").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } void CounterWindow::drawCounterDataOnPage(CounterDataDto * counterData) { // 1. 判断数据属于哪个设备,显示在不同的widget上 +// qDebug() << counterData->toJSON() << counterData->devCode << "---" << counterData->frameId; - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - QList row; - QStandardItem * itemTm = 0; - QStandardItem * itemData = 0; - itemTm = new QStandardItem(QString("%1").arg(counterData->timestamp.mid(11, 12))); - itemData = new QStandardItem(QString("%1").arg(counterData->channelData)); + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - row.append(itemTm); - row.append(itemData); - - QStandardItemModel * model; - model = devChannels.at(counterData->channelId - 1); - if (model->rowCount() >= 20) + // 如果不是当前设备的帧,直接返回 + if (counterData->devCode != currentDevCode) { - model->removeRows(0, model->rowCount()); + return; } - model->insertRow(0, row); + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(counterData->channelId); + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(counterData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 ps").arg(counterData->channelClockValue)); + ((QLineEdit *)channelBox->children().at(6))->setText(counterData->frameId); + ((QLineEdit *)channelBox->children().at(8))->setText(QString("%1").arg(counterData->channelRefId)); + ((QLineEdit *)channelBox->children().at(10))->setText(QString("%1 Ω").arg(counterData->load == 1 ? "1M" : "50")); + ((QLineEdit *)channelBox->children().at(12))->setText(QString("%1 V").arg(counterData->level)); + ((QLabel *)channelBox->children().at(13))->setText(counterData->channelActive == 1 ? "有效" : "无效"); +} -// for (int i = 0; i < counterData->channelData.size(); i++) -// { -// if (counterData->channelActive.at(i).toInt() == 1) -// { -// QList row; -// QStandardItem * item = 0; -// QStandardItem * item2 = 0; -// item = new QStandardItem(QString("%1").arg(counterData->timestamp.mid(11, 12))); -// item2 = new QStandardItem(QString("%1").arg(counterData->channelData.at(i))); +int CounterWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int CounterWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject CounterWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("计数器"); + return response; +} -// row.append(item); -// row.append(item2); +void CounterWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} -// QStandardItemModel * model; -// model = devChannels.at(i); -// if (model->rowCount() >= 60) -// { -// model->removeRows(0, model->rowCount()); -// } - -// model->insertRow(0, row); -// } -// } +void CounterWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); } diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 88ec496..3273433 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -2,7 +2,9 @@ #define COUNTERWINDOW_H #include +#include #include +#include #include "common/utils/SettingConfig.h" //#include "common/utils/QKafkaUtil.h" @@ -26,18 +28,24 @@ public slots: void drawCounterDataOnPage(CounterDataDto * counterData); +private slots: + void on_exitButt_clicked(); + + void on_minButt_clicked(); + private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + Ui::CounterWindow *ui; QTimer * timer; HttpRequestController * httpReq; - QList devWidgetList; - QList deviceList; - QList> tableModelList; - void generateWidgetForDevice(QString devCode, int index); + void generateWidgetForDevice(); }; #endif // COUNTERWINDOW_H diff --git a/CounterAcq/CounterWindow.ui b/CounterAcq/CounterWindow.ui index bcf9570..9ac6eb3 100644 --- a/CounterAcq/CounterWindow.ui +++ b/CounterAcq/CounterWindow.ui @@ -1,29 +1,156 @@ - - CounterWindow - - - - 0 - 0 - 1024 - 720 - - - - 多通道计数器数据采集 - - - - - 0 - 0 - 1024 - 720 - - - - - - - + + CounterWindow + + + + 0 + 0 + 1024 + 720 + + + + 多通道计数器数据采集 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 400 + 10 + 250 + 40 + + + + + + + 250 + 0 + 150 + 60 + + + + + 微软雅黑 + 12 + + + + Qt::LeftToRight + + + 请选择计数器 + + + Qt::AlignCenter + + + + + + 880 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 20 + 0 + 200 + 60 + + + + + 微软雅黑 + 14 + + + + 多通道计数器数据采集 + + + + + + 0 + 59 + 1024 + 1 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 830 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + diff --git a/CounterAcq/common/HttpRequestController.cpp b/CounterAcq/common/HttpRequestController.cpp index 500f902..d4912b8 100644 --- a/CounterAcq/common/HttpRequestController.cpp +++ b/CounterAcq/common/HttpRequestController.cpp @@ -38,18 +38,21 @@ document.setObject(paramObj); QByteArray content = document.toJson(QJsonDocument::Compact); - QNetworkReply *reply = httpUtil->sendPostRequest(request, content); + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); - } - if (resultObj.find("code")->toInt() == 200) + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else { - QString token = resultObj.find("data")->toString(); - this->token = token; + resultObj.insert("code", -1); } return resultObj; @@ -72,36 +75,39 @@ QNetworkReply * reply = httpUtil->sendGetRequest(request); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); - } - if (resultObj.find("code")->toInt() == 200) - { - ConstCache::getInstance().deviceTypes.clear(); - - QJsonArray data = resultObj.find("data")->toArray(); - for (int i = 0; i < data.size(); i++) + if (resultObj.find("code")->toInt() == 200) { - QJsonObject item = data.at(i).toObject(); + ConstCache::getInstance().deviceTypes.clear(); - ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } } + } else + { + resultObj.insert("code", -1); } return resultObj; } -QJsonObject HttpRequestController::initDeviceList() +QJsonObject HttpRequestController::initDeviceList(QString devType) { QJsonObject resultObj; - QString counterDevType = "01"; + QString counterDevType = ""; QMapIterator it(ConstCache::getInstance().deviceTypes); while (it.hasNext()) { it.next(); - if (it.value().contains("计数器") == true) + if (it.value().contains(devType) == true) { counterDevType = it.key(); break; @@ -120,26 +126,32 @@ request.setRawHeader("token", token.toLocal8Bit()); request.setRawHeader("system", system.toLocal8Bit()); + qDebug() << url; + QNetworkReply * reply = httpUtil->sendGetRequest(request); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); } qDebug() << resultObj; - if (resultObj.find("code")->toInt() == 200) - { - ConstCache::getInstance().deviceList.clear(); - - QJsonArray data = resultObj.find("data")->toArray(); - for (int i = 0; i < data.size(); i++) - { - QJsonObject item = data.at(i).toObject(); - - ConstCache::getInstance().deviceList.append(item); - } - } return resultObj; } diff --git a/CounterAcq/common/HttpRequestController.h b/CounterAcq/common/HttpRequestController.h index 46d9b84..77fc3db 100644 --- a/CounterAcq/common/HttpRequestController.h +++ b/CounterAcq/common/HttpRequestController.h @@ -18,7 +18,7 @@ QJsonObject getTokenByClientId(QString clientId, QString key); QJsonObject initDictDeviceType(); - QJsonObject initDeviceList(); + QJsonObject initDeviceList(QString devType); private: HttpRequestUtil * httpUtil; diff --git a/CounterAcq/common/utils/QLogUtil.cpp b/CounterAcq/common/utils/QLogUtil.cpp index 458ac15..6ec3d80 100644 --- a/CounterAcq/common/utils/QLogUtil.cpp +++ b/CounterAcq/common/utils/QLogUtil.cpp @@ -34,3 +34,59 @@ } +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "\\"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "\\"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/CounterAcq/common/utils/QLogUtil.h b/CounterAcq/common/utils/QLogUtil.h index 8da0fcd..1d1ef0f 100644 --- a/CounterAcq/common/utils/QLogUtil.h +++ b/CounterAcq/common/utils/QLogUtil.h @@ -3,7 +3,9 @@ #include #include +#include #include +#include "SettingConfig.h" class QLogUtil : public QObject { @@ -16,6 +18,11 @@ static void writeInfoLog(QString message); static void writeDebugLog(QString message); + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); signals: }; diff --git a/CounterAcq/common/utils/QSerialPortUtil.cpp b/CounterAcq/common/utils/QSerialPortUtil.cpp index 2da13b2..7af0555 100644 --- a/CounterAcq/common/utils/QSerialPortUtil.cpp +++ b/CounterAcq/common/utils/QSerialPortUtil.cpp @@ -63,7 +63,7 @@ QByteArray buffer; QString channel = QString("%1").arg(i); - QString channelRef = "1"; + QString channelRef = "3"; QString dataValue = QString("%1").arg(qrand() % 400); QString level = QString("%1").arg(qrand() % 4 / (double) 10); QString frameId = QString("%1").arg(now.toSecsSinceEpoch() % 10000); diff --git a/CounterAcq/common/utils/SettingConfig.cpp b/CounterAcq/common/utils/SettingConfig.cpp index e9d136e..1f2ebb2 100644 --- a/CounterAcq/common/utils/SettingConfig.cpp +++ b/CounterAcq/common/utils/SettingConfig.cpp @@ -5,9 +5,7 @@ filename = QApplication::applicationDirPath() + "/conf/config.ini"; setting = new QSettings(this->filename, QSettings::IniFormat); - PORT_NAMES = getProperty("com", "portNames").toString(); BAUD_RATE = getProperty("com", "baudRate").toUInt(); - DEV_CODES = getProperty("com", "devCodes").toString(); NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); @@ -17,6 +15,8 @@ APP_KEY = getProperty("client", "appKey").toString(); BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); } diff --git a/CounterAcq/common/utils/SettingConfig.h b/CounterAcq/common/utils/SettingConfig.h index 227d029..ce1e933 100644 --- a/CounterAcq/common/utils/SettingConfig.h +++ b/CounterAcq/common/utils/SettingConfig.h @@ -27,9 +27,7 @@ QVariant getProperty(QString nodeName, QString keyName); /******** 以下为需要的各类参数 ********/ - QString PORT_NAMES; int BAUD_RATE; - QString DEV_CODES; int NEED_KAFKA; QString KAFKA_BROKERS; @@ -40,6 +38,8 @@ QString BASE_URL; + QString BASE_LOG_PATH; + private: SettingConfig(); diff --git a/CounterAcq/CounterDevice.cpp b/CounterAcq/CounterDevice.cpp index 1aef95a..a6f0bd1 100644 --- a/CounterAcq/CounterDevice.cpp +++ b/CounterAcq/CounterDevice.cpp @@ -2,12 +2,16 @@ #include #include +#include CounterDevice::CounterDevice(QObject *parent) : QObject(parent) { connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &CounterDevice::dataReceivedHandler); + connect(this, &CounterDevice::successDataCalculate, + this, &CounterDevice::afterFramePhase); + // kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); // kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); // kafkaUtil.createProducer(); @@ -35,6 +39,10 @@ { this->devCode = devCode; } +void CounterDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool CounterDevice::isSerialOpen() { @@ -55,7 +63,7 @@ if (CounterProtocolBM::checkFrame(this->dataBuff) == true) { counterData->rawFrame = this->dataBuff; - std::cout << counterData->rawFrame.toStdString() << std::endl; +// std::cout << counterData->rawFrame.toStdString() << std::endl; // ★解析成数据对象 bool parse = CounterProtocolBM::parseMessureData(this->dataBuff, counterData); @@ -63,36 +71,38 @@ // 解析成功 if (parse == true) { + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 补充其他字段 QDateTime now = QDateTime::currentDateTime(); counterData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); counterData->milisecond = now.toMSecsSinceEpoch(); - this->afterFramePhase(counterData); + counterData->devCode = devCode; + + // 3 计算数据ID一样的测量数据的时差值,通道值-参考通道值 + this->pushChannelRawFrame(counterData); } } // 在此处释放内存,不影响后续显示 // 不在此处释放内存则会导致内存持续增加 - // 具体原因不明 delete counterData; } void CounterDevice::afterFramePhase(CounterDataDto * counterData) { - // 1. 清空dataBuff,等待下一帧的数据 - this->dataBuff.clear(); + // 0. 输出到日志文件中 + QString date = counterData->timestamp.mid(0, 10); - // 2. 输出到日志文件中 - QString filePostfix = counterData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; - - // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + // 1. 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; QString content = counterData->timestamp + " " + counterData->rawFrame.left(counterData->rawFrame.size() - COUNTER_FRAME_TAIL.size()); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); - // 2.2 各个通道的clock diff数据 - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + // 2. 各个通道的clock diff数据 + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (counterData->channelId < 10) { chFilename = chFilename.arg(QString("0%1").arg(counterData->channelId)); @@ -100,20 +110,76 @@ { chFilename = chFilename.arg(counterData->channelId); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(counterData->timestamp).arg(counterData->channelClockValue).arg(counterData->frameId); - - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QString channelDataStr = QString("%1 [%2] %3 %4") + .arg(counterData->timestamp) + .arg(counterData->frameId) + .arg(counterData->channelData) + .arg(counterData->channelClockValue); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) { QJsonObject jsonObj = counterData->toJSON(); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); - jsonObj.insert("deviceId", devCode); + jsonObj.insert("deviceId", deviceId); // kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } // 4. 在界面上简单显示相差数据结果 emit this->sendDataToDraw(counterData); } + +void CounterDevice::pushChannelRawFrame(CounterDataDto * counterData) +{ + QString currentFrameId = counterData->frameId; + QString currentChannelId = QString("%1").arg(counterData->channelId); + + if (counterData->channelId == counterData->channelRefId) + { + // 自身是参考通道 + bench.insert(currentFrameId, counterData->channelData); + counterData->channelClockValue = 0; + + emit successDataCalculate(counterData); + + qlonglong thisBench = counterData->channelData; + // 遍历temp,处理之前的临时暂存的队列 + if (hisList.isEmpty() == false) + { + for (int i = 0; i < hisList.size(); i++) + { + CounterDataDto * hisItem = hisList.at(i); + if (hisItem->frameId == currentFrameId) + { + hisItem->channelClockValue = (hisItem->channelData - thisBench) * 10; + + emit successDataCalculate(hisItem); + delete hisItem; + } + } + + hisList.clear(); + } + } else + { + // 自身不是参考通道,减去相同frameId的参考通道值 + if (bench.contains(currentFrameId) == true) + { + // 在参考基准中能找到 + qlonglong currentBench = bench.find(currentFrameId).value(); + counterData->channelClockValue = (counterData->channelData - currentBench) * 10; // 10ps + + emit successDataCalculate(counterData); + } else + { + // 暂存,等收到基准之后再处置 + CounterDataDto * copyPoint = new CounterDataDto(); + + // ★clone一份对象,存入缓存队列 + counterData->clone(copyPoint); + + hisList.append(copyPoint); + } + } +} diff --git a/CounterAcq/CounterDevice.h b/CounterAcq/CounterDevice.h index 3572d69..b15e44f 100644 --- a/CounterAcq/CounterDevice.h +++ b/CounterAcq/CounterDevice.h @@ -19,16 +19,16 @@ void initSerialPort(); - void afterFramePhase(CounterDataDto * counterData); - void setComName(QString comName); void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; @@ -37,11 +37,18 @@ // QKafkaUtil kafkaUtil; QByteArray dataBuff; + QMap bench; + QList hisList; + + void pushChannelRawFrame(CounterDataDto * counterData); + signals: void sendDataToDraw(CounterDataDto * counterData); + void successDataCalculate(CounterDataDto * counterData); public slots: void dataReceivedHandler(QByteArray data); + void afterFramePhase(CounterDataDto * counterData); }; #endif // COUNTERDEVICE_H diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 31d43fd..f8278f6 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -5,12 +5,12 @@ #include #include #include +#include +#include #include -#include -#include #include -#include #include +#include CounterWindow::CounterWindow(QWidget *parent) : QWidget(parent), @@ -18,56 +18,74 @@ { ui->setupUi(this); + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), 700); + resize(screenRect.width(), screenRect.height()); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); - - for (int i = 0; i < comDevList.size(); i++) - { - CounterDevice * device = new CounterDevice(this); - - // - connect(device, &CounterDevice::sendDataToDraw, - this, &CounterWindow::drawCounterDataOnPage); - - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); - - device->setDevCode(devCodeList.at(i)); - - this->deviceList.append(device); - -// device->initSerialPort(); -// device->startWork(); - } - - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget = new QWidget(this->ui->stackedWidget); - ui->stackedWidget->addWidget(devWidget); - devWidgetList.append(devWidget); - - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); httpReq = new HttpRequestController(this); - QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, - SettingConfig::getInstance().APP_KEY); - if (response.find("code")->toInt() == 200) + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - httpReq->initDictDeviceType(); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - httpReq->initDeviceList(); + QApplication::exit(0); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); + + // 3. 获取计数器设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); + + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i =0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); + + CounterDevice * device = new CounterDevice(this); + deviceList.append(device); + + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &CounterDevice::sendDataToDraw, + this, &CounterWindow::drawCounterDataOnPage); + + device->initSerialPort(); + + QThread::msleep(200); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } -// timer = new QTimer(this); -// timer->start(1000 * 10); + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } CounterWindow::~CounterWindow() @@ -75,110 +93,153 @@ delete ui; } -void CounterWindow::generateWidgetForDevice(QString devCode, int index) +void CounterWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(75); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(75); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * refChLabel = new QLabel(); + refChLabel->setText("参考通道"); + refChLabel->setFont(labelFont); + refChLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(refChLabel); + QLineEdit * refChValue = new QLineEdit(); + refChValue->setFixedWidth(60); + refChValue->setFont(labelFont); + vbox->addWidget(refChValue); + + QLabel * loadLabel = new QLabel(); + loadLabel->setText("负载"); + loadLabel->setFont(labelFont); + loadLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(loadLabel); + QLineEdit * loadValue = new QLineEdit(); + loadValue->setFixedWidth(60); + loadValue->setFont(labelFont); + vbox->addWidget(loadValue); + + QLabel * levelLabel = new QLabel(); + levelLabel->setText("触发电平"); + levelLabel->setFont(labelFont); + levelLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(levelLabel); + QLineEdit * levelValue = new QLineEdit(); + levelValue->setFixedWidth(60); + levelValue->setFont(labelFont); + vbox->addWidget(levelValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,clock").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } void CounterWindow::drawCounterDataOnPage(CounterDataDto * counterData) { // 1. 判断数据属于哪个设备,显示在不同的widget上 +// qDebug() << counterData->toJSON() << counterData->devCode << "---" << counterData->frameId; - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - QList row; - QStandardItem * itemTm = 0; - QStandardItem * itemData = 0; - itemTm = new QStandardItem(QString("%1").arg(counterData->timestamp.mid(11, 12))); - itemData = new QStandardItem(QString("%1").arg(counterData->channelData)); + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - row.append(itemTm); - row.append(itemData); - - QStandardItemModel * model; - model = devChannels.at(counterData->channelId - 1); - if (model->rowCount() >= 20) + // 如果不是当前设备的帧,直接返回 + if (counterData->devCode != currentDevCode) { - model->removeRows(0, model->rowCount()); + return; } - model->insertRow(0, row); + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(counterData->channelId); + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(counterData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 ps").arg(counterData->channelClockValue)); + ((QLineEdit *)channelBox->children().at(6))->setText(counterData->frameId); + ((QLineEdit *)channelBox->children().at(8))->setText(QString("%1").arg(counterData->channelRefId)); + ((QLineEdit *)channelBox->children().at(10))->setText(QString("%1 Ω").arg(counterData->load == 1 ? "1M" : "50")); + ((QLineEdit *)channelBox->children().at(12))->setText(QString("%1 V").arg(counterData->level)); + ((QLabel *)channelBox->children().at(13))->setText(counterData->channelActive == 1 ? "有效" : "无效"); +} -// for (int i = 0; i < counterData->channelData.size(); i++) -// { -// if (counterData->channelActive.at(i).toInt() == 1) -// { -// QList row; -// QStandardItem * item = 0; -// QStandardItem * item2 = 0; -// item = new QStandardItem(QString("%1").arg(counterData->timestamp.mid(11, 12))); -// item2 = new QStandardItem(QString("%1").arg(counterData->channelData.at(i))); +int CounterWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int CounterWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject CounterWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("计数器"); + return response; +} -// row.append(item); -// row.append(item2); +void CounterWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} -// QStandardItemModel * model; -// model = devChannels.at(i); -// if (model->rowCount() >= 60) -// { -// model->removeRows(0, model->rowCount()); -// } - -// model->insertRow(0, row); -// } -// } +void CounterWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); } diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 88ec496..3273433 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -2,7 +2,9 @@ #define COUNTERWINDOW_H #include +#include #include +#include #include "common/utils/SettingConfig.h" //#include "common/utils/QKafkaUtil.h" @@ -26,18 +28,24 @@ public slots: void drawCounterDataOnPage(CounterDataDto * counterData); +private slots: + void on_exitButt_clicked(); + + void on_minButt_clicked(); + private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + Ui::CounterWindow *ui; QTimer * timer; HttpRequestController * httpReq; - QList devWidgetList; - QList deviceList; - QList> tableModelList; - void generateWidgetForDevice(QString devCode, int index); + void generateWidgetForDevice(); }; #endif // COUNTERWINDOW_H diff --git a/CounterAcq/CounterWindow.ui b/CounterAcq/CounterWindow.ui index bcf9570..9ac6eb3 100644 --- a/CounterAcq/CounterWindow.ui +++ b/CounterAcq/CounterWindow.ui @@ -1,29 +1,156 @@ - - CounterWindow - - - - 0 - 0 - 1024 - 720 - - - - 多通道计数器数据采集 - - - - - 0 - 0 - 1024 - 720 - - - - - - - + + CounterWindow + + + + 0 + 0 + 1024 + 720 + + + + 多通道计数器数据采集 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 400 + 10 + 250 + 40 + + + + + + + 250 + 0 + 150 + 60 + + + + + 微软雅黑 + 12 + + + + Qt::LeftToRight + + + 请选择计数器 + + + Qt::AlignCenter + + + + + + 880 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 20 + 0 + 200 + 60 + + + + + 微软雅黑 + 14 + + + + 多通道计数器数据采集 + + + + + + 0 + 59 + 1024 + 1 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 830 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + diff --git a/CounterAcq/common/HttpRequestController.cpp b/CounterAcq/common/HttpRequestController.cpp index 500f902..d4912b8 100644 --- a/CounterAcq/common/HttpRequestController.cpp +++ b/CounterAcq/common/HttpRequestController.cpp @@ -38,18 +38,21 @@ document.setObject(paramObj); QByteArray content = document.toJson(QJsonDocument::Compact); - QNetworkReply *reply = httpUtil->sendPostRequest(request, content); + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); - } - if (resultObj.find("code")->toInt() == 200) + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else { - QString token = resultObj.find("data")->toString(); - this->token = token; + resultObj.insert("code", -1); } return resultObj; @@ -72,36 +75,39 @@ QNetworkReply * reply = httpUtil->sendGetRequest(request); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); - } - if (resultObj.find("code")->toInt() == 200) - { - ConstCache::getInstance().deviceTypes.clear(); - - QJsonArray data = resultObj.find("data")->toArray(); - for (int i = 0; i < data.size(); i++) + if (resultObj.find("code")->toInt() == 200) { - QJsonObject item = data.at(i).toObject(); + ConstCache::getInstance().deviceTypes.clear(); - ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } } + } else + { + resultObj.insert("code", -1); } return resultObj; } -QJsonObject HttpRequestController::initDeviceList() +QJsonObject HttpRequestController::initDeviceList(QString devType) { QJsonObject resultObj; - QString counterDevType = "01"; + QString counterDevType = ""; QMapIterator it(ConstCache::getInstance().deviceTypes); while (it.hasNext()) { it.next(); - if (it.value().contains("计数器") == true) + if (it.value().contains(devType) == true) { counterDevType = it.key(); break; @@ -120,26 +126,32 @@ request.setRawHeader("token", token.toLocal8Bit()); request.setRawHeader("system", system.toLocal8Bit()); + qDebug() << url; + QNetworkReply * reply = httpUtil->sendGetRequest(request); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); } qDebug() << resultObj; - if (resultObj.find("code")->toInt() == 200) - { - ConstCache::getInstance().deviceList.clear(); - - QJsonArray data = resultObj.find("data")->toArray(); - for (int i = 0; i < data.size(); i++) - { - QJsonObject item = data.at(i).toObject(); - - ConstCache::getInstance().deviceList.append(item); - } - } return resultObj; } diff --git a/CounterAcq/common/HttpRequestController.h b/CounterAcq/common/HttpRequestController.h index 46d9b84..77fc3db 100644 --- a/CounterAcq/common/HttpRequestController.h +++ b/CounterAcq/common/HttpRequestController.h @@ -18,7 +18,7 @@ QJsonObject getTokenByClientId(QString clientId, QString key); QJsonObject initDictDeviceType(); - QJsonObject initDeviceList(); + QJsonObject initDeviceList(QString devType); private: HttpRequestUtil * httpUtil; diff --git a/CounterAcq/common/utils/QLogUtil.cpp b/CounterAcq/common/utils/QLogUtil.cpp index 458ac15..6ec3d80 100644 --- a/CounterAcq/common/utils/QLogUtil.cpp +++ b/CounterAcq/common/utils/QLogUtil.cpp @@ -34,3 +34,59 @@ } +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "\\"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "\\"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/CounterAcq/common/utils/QLogUtil.h b/CounterAcq/common/utils/QLogUtil.h index 8da0fcd..1d1ef0f 100644 --- a/CounterAcq/common/utils/QLogUtil.h +++ b/CounterAcq/common/utils/QLogUtil.h @@ -3,7 +3,9 @@ #include #include +#include #include +#include "SettingConfig.h" class QLogUtil : public QObject { @@ -16,6 +18,11 @@ static void writeInfoLog(QString message); static void writeDebugLog(QString message); + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); signals: }; diff --git a/CounterAcq/common/utils/QSerialPortUtil.cpp b/CounterAcq/common/utils/QSerialPortUtil.cpp index 2da13b2..7af0555 100644 --- a/CounterAcq/common/utils/QSerialPortUtil.cpp +++ b/CounterAcq/common/utils/QSerialPortUtil.cpp @@ -63,7 +63,7 @@ QByteArray buffer; QString channel = QString("%1").arg(i); - QString channelRef = "1"; + QString channelRef = "3"; QString dataValue = QString("%1").arg(qrand() % 400); QString level = QString("%1").arg(qrand() % 4 / (double) 10); QString frameId = QString("%1").arg(now.toSecsSinceEpoch() % 10000); diff --git a/CounterAcq/common/utils/SettingConfig.cpp b/CounterAcq/common/utils/SettingConfig.cpp index e9d136e..1f2ebb2 100644 --- a/CounterAcq/common/utils/SettingConfig.cpp +++ b/CounterAcq/common/utils/SettingConfig.cpp @@ -5,9 +5,7 @@ filename = QApplication::applicationDirPath() + "/conf/config.ini"; setting = new QSettings(this->filename, QSettings::IniFormat); - PORT_NAMES = getProperty("com", "portNames").toString(); BAUD_RATE = getProperty("com", "baudRate").toUInt(); - DEV_CODES = getProperty("com", "devCodes").toString(); NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); @@ -17,6 +15,8 @@ APP_KEY = getProperty("client", "appKey").toString(); BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); } diff --git a/CounterAcq/common/utils/SettingConfig.h b/CounterAcq/common/utils/SettingConfig.h index 227d029..ce1e933 100644 --- a/CounterAcq/common/utils/SettingConfig.h +++ b/CounterAcq/common/utils/SettingConfig.h @@ -27,9 +27,7 @@ QVariant getProperty(QString nodeName, QString keyName); /******** 以下为需要的各类参数 ********/ - QString PORT_NAMES; int BAUD_RATE; - QString DEV_CODES; int NEED_KAFKA; QString KAFKA_BROKERS; @@ -40,6 +38,8 @@ QString BASE_URL; + QString BASE_LOG_PATH; + private: SettingConfig(); diff --git a/CounterAcq/conf/config.ini b/CounterAcq/conf/config.ini index 0321e65..ebe1e82 100644 --- a/CounterAcq/conf/config.ini +++ b/CounterAcq/conf/config.ini @@ -1,10 +1,8 @@ [com] -portNames="COM1,COM2,COM3" -devCodes="9101,9102,9103" baudRate=115200 [kafka] -needKafka=1 +needKafka=0 brokers="111.198.10.15:12502" dataTopic="cppTest" @@ -14,3 +12,6 @@ [http] baseUrl="http://111.198.10.15:11410" + +[log] +basePath="D://Workspace Qt//ZXSSCJ-Release//Counter//logs//" diff --git a/CounterAcq/CounterDevice.cpp b/CounterAcq/CounterDevice.cpp index 1aef95a..a6f0bd1 100644 --- a/CounterAcq/CounterDevice.cpp +++ b/CounterAcq/CounterDevice.cpp @@ -2,12 +2,16 @@ #include #include +#include CounterDevice::CounterDevice(QObject *parent) : QObject(parent) { connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &CounterDevice::dataReceivedHandler); + connect(this, &CounterDevice::successDataCalculate, + this, &CounterDevice::afterFramePhase); + // kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); // kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); // kafkaUtil.createProducer(); @@ -35,6 +39,10 @@ { this->devCode = devCode; } +void CounterDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool CounterDevice::isSerialOpen() { @@ -55,7 +63,7 @@ if (CounterProtocolBM::checkFrame(this->dataBuff) == true) { counterData->rawFrame = this->dataBuff; - std::cout << counterData->rawFrame.toStdString() << std::endl; +// std::cout << counterData->rawFrame.toStdString() << std::endl; // ★解析成数据对象 bool parse = CounterProtocolBM::parseMessureData(this->dataBuff, counterData); @@ -63,36 +71,38 @@ // 解析成功 if (parse == true) { + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 补充其他字段 QDateTime now = QDateTime::currentDateTime(); counterData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); counterData->milisecond = now.toMSecsSinceEpoch(); - this->afterFramePhase(counterData); + counterData->devCode = devCode; + + // 3 计算数据ID一样的测量数据的时差值,通道值-参考通道值 + this->pushChannelRawFrame(counterData); } } // 在此处释放内存,不影响后续显示 // 不在此处释放内存则会导致内存持续增加 - // 具体原因不明 delete counterData; } void CounterDevice::afterFramePhase(CounterDataDto * counterData) { - // 1. 清空dataBuff,等待下一帧的数据 - this->dataBuff.clear(); + // 0. 输出到日志文件中 + QString date = counterData->timestamp.mid(0, 10); - // 2. 输出到日志文件中 - QString filePostfix = counterData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; - - // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + // 1. 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; QString content = counterData->timestamp + " " + counterData->rawFrame.left(counterData->rawFrame.size() - COUNTER_FRAME_TAIL.size()); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); - // 2.2 各个通道的clock diff数据 - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + // 2. 各个通道的clock diff数据 + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (counterData->channelId < 10) { chFilename = chFilename.arg(QString("0%1").arg(counterData->channelId)); @@ -100,20 +110,76 @@ { chFilename = chFilename.arg(counterData->channelId); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(counterData->timestamp).arg(counterData->channelClockValue).arg(counterData->frameId); - - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QString channelDataStr = QString("%1 [%2] %3 %4") + .arg(counterData->timestamp) + .arg(counterData->frameId) + .arg(counterData->channelData) + .arg(counterData->channelClockValue); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) { QJsonObject jsonObj = counterData->toJSON(); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); - jsonObj.insert("deviceId", devCode); + jsonObj.insert("deviceId", deviceId); // kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } // 4. 在界面上简单显示相差数据结果 emit this->sendDataToDraw(counterData); } + +void CounterDevice::pushChannelRawFrame(CounterDataDto * counterData) +{ + QString currentFrameId = counterData->frameId; + QString currentChannelId = QString("%1").arg(counterData->channelId); + + if (counterData->channelId == counterData->channelRefId) + { + // 自身是参考通道 + bench.insert(currentFrameId, counterData->channelData); + counterData->channelClockValue = 0; + + emit successDataCalculate(counterData); + + qlonglong thisBench = counterData->channelData; + // 遍历temp,处理之前的临时暂存的队列 + if (hisList.isEmpty() == false) + { + for (int i = 0; i < hisList.size(); i++) + { + CounterDataDto * hisItem = hisList.at(i); + if (hisItem->frameId == currentFrameId) + { + hisItem->channelClockValue = (hisItem->channelData - thisBench) * 10; + + emit successDataCalculate(hisItem); + delete hisItem; + } + } + + hisList.clear(); + } + } else + { + // 自身不是参考通道,减去相同frameId的参考通道值 + if (bench.contains(currentFrameId) == true) + { + // 在参考基准中能找到 + qlonglong currentBench = bench.find(currentFrameId).value(); + counterData->channelClockValue = (counterData->channelData - currentBench) * 10; // 10ps + + emit successDataCalculate(counterData); + } else + { + // 暂存,等收到基准之后再处置 + CounterDataDto * copyPoint = new CounterDataDto(); + + // ★clone一份对象,存入缓存队列 + counterData->clone(copyPoint); + + hisList.append(copyPoint); + } + } +} diff --git a/CounterAcq/CounterDevice.h b/CounterAcq/CounterDevice.h index 3572d69..b15e44f 100644 --- a/CounterAcq/CounterDevice.h +++ b/CounterAcq/CounterDevice.h @@ -19,16 +19,16 @@ void initSerialPort(); - void afterFramePhase(CounterDataDto * counterData); - void setComName(QString comName); void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; @@ -37,11 +37,18 @@ // QKafkaUtil kafkaUtil; QByteArray dataBuff; + QMap bench; + QList hisList; + + void pushChannelRawFrame(CounterDataDto * counterData); + signals: void sendDataToDraw(CounterDataDto * counterData); + void successDataCalculate(CounterDataDto * counterData); public slots: void dataReceivedHandler(QByteArray data); + void afterFramePhase(CounterDataDto * counterData); }; #endif // COUNTERDEVICE_H diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 31d43fd..f8278f6 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -5,12 +5,12 @@ #include #include #include +#include +#include #include -#include -#include #include -#include #include +#include CounterWindow::CounterWindow(QWidget *parent) : QWidget(parent), @@ -18,56 +18,74 @@ { ui->setupUi(this); + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), 700); + resize(screenRect.width(), screenRect.height()); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); - - for (int i = 0; i < comDevList.size(); i++) - { - CounterDevice * device = new CounterDevice(this); - - // - connect(device, &CounterDevice::sendDataToDraw, - this, &CounterWindow::drawCounterDataOnPage); - - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); - - device->setDevCode(devCodeList.at(i)); - - this->deviceList.append(device); - -// device->initSerialPort(); -// device->startWork(); - } - - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget = new QWidget(this->ui->stackedWidget); - ui->stackedWidget->addWidget(devWidget); - devWidgetList.append(devWidget); - - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); httpReq = new HttpRequestController(this); - QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, - SettingConfig::getInstance().APP_KEY); - if (response.find("code")->toInt() == 200) + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - httpReq->initDictDeviceType(); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - httpReq->initDeviceList(); + QApplication::exit(0); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); + + // 3. 获取计数器设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); + + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i =0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); + + CounterDevice * device = new CounterDevice(this); + deviceList.append(device); + + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &CounterDevice::sendDataToDraw, + this, &CounterWindow::drawCounterDataOnPage); + + device->initSerialPort(); + + QThread::msleep(200); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } -// timer = new QTimer(this); -// timer->start(1000 * 10); + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } CounterWindow::~CounterWindow() @@ -75,110 +93,153 @@ delete ui; } -void CounterWindow::generateWidgetForDevice(QString devCode, int index) +void CounterWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(75); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(75); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * refChLabel = new QLabel(); + refChLabel->setText("参考通道"); + refChLabel->setFont(labelFont); + refChLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(refChLabel); + QLineEdit * refChValue = new QLineEdit(); + refChValue->setFixedWidth(60); + refChValue->setFont(labelFont); + vbox->addWidget(refChValue); + + QLabel * loadLabel = new QLabel(); + loadLabel->setText("负载"); + loadLabel->setFont(labelFont); + loadLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(loadLabel); + QLineEdit * loadValue = new QLineEdit(); + loadValue->setFixedWidth(60); + loadValue->setFont(labelFont); + vbox->addWidget(loadValue); + + QLabel * levelLabel = new QLabel(); + levelLabel->setText("触发电平"); + levelLabel->setFont(labelFont); + levelLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(levelLabel); + QLineEdit * levelValue = new QLineEdit(); + levelValue->setFixedWidth(60); + levelValue->setFont(labelFont); + vbox->addWidget(levelValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,clock").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } void CounterWindow::drawCounterDataOnPage(CounterDataDto * counterData) { // 1. 判断数据属于哪个设备,显示在不同的widget上 +// qDebug() << counterData->toJSON() << counterData->devCode << "---" << counterData->frameId; - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - QList row; - QStandardItem * itemTm = 0; - QStandardItem * itemData = 0; - itemTm = new QStandardItem(QString("%1").arg(counterData->timestamp.mid(11, 12))); - itemData = new QStandardItem(QString("%1").arg(counterData->channelData)); + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - row.append(itemTm); - row.append(itemData); - - QStandardItemModel * model; - model = devChannels.at(counterData->channelId - 1); - if (model->rowCount() >= 20) + // 如果不是当前设备的帧,直接返回 + if (counterData->devCode != currentDevCode) { - model->removeRows(0, model->rowCount()); + return; } - model->insertRow(0, row); + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(counterData->channelId); + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(counterData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 ps").arg(counterData->channelClockValue)); + ((QLineEdit *)channelBox->children().at(6))->setText(counterData->frameId); + ((QLineEdit *)channelBox->children().at(8))->setText(QString("%1").arg(counterData->channelRefId)); + ((QLineEdit *)channelBox->children().at(10))->setText(QString("%1 Ω").arg(counterData->load == 1 ? "1M" : "50")); + ((QLineEdit *)channelBox->children().at(12))->setText(QString("%1 V").arg(counterData->level)); + ((QLabel *)channelBox->children().at(13))->setText(counterData->channelActive == 1 ? "有效" : "无效"); +} -// for (int i = 0; i < counterData->channelData.size(); i++) -// { -// if (counterData->channelActive.at(i).toInt() == 1) -// { -// QList row; -// QStandardItem * item = 0; -// QStandardItem * item2 = 0; -// item = new QStandardItem(QString("%1").arg(counterData->timestamp.mid(11, 12))); -// item2 = new QStandardItem(QString("%1").arg(counterData->channelData.at(i))); +int CounterWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int CounterWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject CounterWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("计数器"); + return response; +} -// row.append(item); -// row.append(item2); +void CounterWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} -// QStandardItemModel * model; -// model = devChannels.at(i); -// if (model->rowCount() >= 60) -// { -// model->removeRows(0, model->rowCount()); -// } - -// model->insertRow(0, row); -// } -// } +void CounterWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); } diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 88ec496..3273433 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -2,7 +2,9 @@ #define COUNTERWINDOW_H #include +#include #include +#include #include "common/utils/SettingConfig.h" //#include "common/utils/QKafkaUtil.h" @@ -26,18 +28,24 @@ public slots: void drawCounterDataOnPage(CounterDataDto * counterData); +private slots: + void on_exitButt_clicked(); + + void on_minButt_clicked(); + private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + Ui::CounterWindow *ui; QTimer * timer; HttpRequestController * httpReq; - QList devWidgetList; - QList deviceList; - QList> tableModelList; - void generateWidgetForDevice(QString devCode, int index); + void generateWidgetForDevice(); }; #endif // COUNTERWINDOW_H diff --git a/CounterAcq/CounterWindow.ui b/CounterAcq/CounterWindow.ui index bcf9570..9ac6eb3 100644 --- a/CounterAcq/CounterWindow.ui +++ b/CounterAcq/CounterWindow.ui @@ -1,29 +1,156 @@ - - CounterWindow - - - - 0 - 0 - 1024 - 720 - - - - 多通道计数器数据采集 - - - - - 0 - 0 - 1024 - 720 - - - - - - - + + CounterWindow + + + + 0 + 0 + 1024 + 720 + + + + 多通道计数器数据采集 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 400 + 10 + 250 + 40 + + + + + + + 250 + 0 + 150 + 60 + + + + + 微软雅黑 + 12 + + + + Qt::LeftToRight + + + 请选择计数器 + + + Qt::AlignCenter + + + + + + 880 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 20 + 0 + 200 + 60 + + + + + 微软雅黑 + 14 + + + + 多通道计数器数据采集 + + + + + + 0 + 59 + 1024 + 1 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 830 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + diff --git a/CounterAcq/common/HttpRequestController.cpp b/CounterAcq/common/HttpRequestController.cpp index 500f902..d4912b8 100644 --- a/CounterAcq/common/HttpRequestController.cpp +++ b/CounterAcq/common/HttpRequestController.cpp @@ -38,18 +38,21 @@ document.setObject(paramObj); QByteArray content = document.toJson(QJsonDocument::Compact); - QNetworkReply *reply = httpUtil->sendPostRequest(request, content); + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); - } - if (resultObj.find("code")->toInt() == 200) + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else { - QString token = resultObj.find("data")->toString(); - this->token = token; + resultObj.insert("code", -1); } return resultObj; @@ -72,36 +75,39 @@ QNetworkReply * reply = httpUtil->sendGetRequest(request); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); - } - if (resultObj.find("code")->toInt() == 200) - { - ConstCache::getInstance().deviceTypes.clear(); - - QJsonArray data = resultObj.find("data")->toArray(); - for (int i = 0; i < data.size(); i++) + if (resultObj.find("code")->toInt() == 200) { - QJsonObject item = data.at(i).toObject(); + ConstCache::getInstance().deviceTypes.clear(); - ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } } + } else + { + resultObj.insert("code", -1); } return resultObj; } -QJsonObject HttpRequestController::initDeviceList() +QJsonObject HttpRequestController::initDeviceList(QString devType) { QJsonObject resultObj; - QString counterDevType = "01"; + QString counterDevType = ""; QMapIterator it(ConstCache::getInstance().deviceTypes); while (it.hasNext()) { it.next(); - if (it.value().contains("计数器") == true) + if (it.value().contains(devType) == true) { counterDevType = it.key(); break; @@ -120,26 +126,32 @@ request.setRawHeader("token", token.toLocal8Bit()); request.setRawHeader("system", system.toLocal8Bit()); + qDebug() << url; + QNetworkReply * reply = httpUtil->sendGetRequest(request); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); } qDebug() << resultObj; - if (resultObj.find("code")->toInt() == 200) - { - ConstCache::getInstance().deviceList.clear(); - - QJsonArray data = resultObj.find("data")->toArray(); - for (int i = 0; i < data.size(); i++) - { - QJsonObject item = data.at(i).toObject(); - - ConstCache::getInstance().deviceList.append(item); - } - } return resultObj; } diff --git a/CounterAcq/common/HttpRequestController.h b/CounterAcq/common/HttpRequestController.h index 46d9b84..77fc3db 100644 --- a/CounterAcq/common/HttpRequestController.h +++ b/CounterAcq/common/HttpRequestController.h @@ -18,7 +18,7 @@ QJsonObject getTokenByClientId(QString clientId, QString key); QJsonObject initDictDeviceType(); - QJsonObject initDeviceList(); + QJsonObject initDeviceList(QString devType); private: HttpRequestUtil * httpUtil; diff --git a/CounterAcq/common/utils/QLogUtil.cpp b/CounterAcq/common/utils/QLogUtil.cpp index 458ac15..6ec3d80 100644 --- a/CounterAcq/common/utils/QLogUtil.cpp +++ b/CounterAcq/common/utils/QLogUtil.cpp @@ -34,3 +34,59 @@ } +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "\\"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "\\"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/CounterAcq/common/utils/QLogUtil.h b/CounterAcq/common/utils/QLogUtil.h index 8da0fcd..1d1ef0f 100644 --- a/CounterAcq/common/utils/QLogUtil.h +++ b/CounterAcq/common/utils/QLogUtil.h @@ -3,7 +3,9 @@ #include #include +#include #include +#include "SettingConfig.h" class QLogUtil : public QObject { @@ -16,6 +18,11 @@ static void writeInfoLog(QString message); static void writeDebugLog(QString message); + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); signals: }; diff --git a/CounterAcq/common/utils/QSerialPortUtil.cpp b/CounterAcq/common/utils/QSerialPortUtil.cpp index 2da13b2..7af0555 100644 --- a/CounterAcq/common/utils/QSerialPortUtil.cpp +++ b/CounterAcq/common/utils/QSerialPortUtil.cpp @@ -63,7 +63,7 @@ QByteArray buffer; QString channel = QString("%1").arg(i); - QString channelRef = "1"; + QString channelRef = "3"; QString dataValue = QString("%1").arg(qrand() % 400); QString level = QString("%1").arg(qrand() % 4 / (double) 10); QString frameId = QString("%1").arg(now.toSecsSinceEpoch() % 10000); diff --git a/CounterAcq/common/utils/SettingConfig.cpp b/CounterAcq/common/utils/SettingConfig.cpp index e9d136e..1f2ebb2 100644 --- a/CounterAcq/common/utils/SettingConfig.cpp +++ b/CounterAcq/common/utils/SettingConfig.cpp @@ -5,9 +5,7 @@ filename = QApplication::applicationDirPath() + "/conf/config.ini"; setting = new QSettings(this->filename, QSettings::IniFormat); - PORT_NAMES = getProperty("com", "portNames").toString(); BAUD_RATE = getProperty("com", "baudRate").toUInt(); - DEV_CODES = getProperty("com", "devCodes").toString(); NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); @@ -17,6 +15,8 @@ APP_KEY = getProperty("client", "appKey").toString(); BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); } diff --git a/CounterAcq/common/utils/SettingConfig.h b/CounterAcq/common/utils/SettingConfig.h index 227d029..ce1e933 100644 --- a/CounterAcq/common/utils/SettingConfig.h +++ b/CounterAcq/common/utils/SettingConfig.h @@ -27,9 +27,7 @@ QVariant getProperty(QString nodeName, QString keyName); /******** 以下为需要的各类参数 ********/ - QString PORT_NAMES; int BAUD_RATE; - QString DEV_CODES; int NEED_KAFKA; QString KAFKA_BROKERS; @@ -40,6 +38,8 @@ QString BASE_URL; + QString BASE_LOG_PATH; + private: SettingConfig(); diff --git a/CounterAcq/conf/config.ini b/CounterAcq/conf/config.ini index 0321e65..ebe1e82 100644 --- a/CounterAcq/conf/config.ini +++ b/CounterAcq/conf/config.ini @@ -1,10 +1,8 @@ [com] -portNames="COM1,COM2,COM3" -devCodes="9101,9102,9103" baudRate=115200 [kafka] -needKafka=1 +needKafka=0 brokers="111.198.10.15:12502" dataTopic="cppTest" @@ -14,3 +12,6 @@ [http] baseUrl="http://111.198.10.15:11410" + +[log] +basePath="D://Workspace Qt//ZXSSCJ-Release//Counter//logs//" diff --git a/CounterAcq/protocol/CounterProtocolBM.cpp b/CounterAcq/protocol/CounterProtocolBM.cpp index b33be0d..2aca849 100644 --- a/CounterAcq/protocol/CounterProtocolBM.cpp +++ b/CounterAcq/protocol/CounterProtocolBM.cpp @@ -25,12 +25,10 @@ counterData->channelActive = subList.at(2).toUInt(); counterData->channelRefId = subList.at(3).toUInt(); counterData->channelData = subList.at(4).toLongLong(); - counterData->load = subList.at(5).toDouble(); + counterData->load = subList.at(5); counterData->level = subList.at(6).toDouble(); counterData->frameId = subList.at(7); - counterData->channelClockValue = counterData->channelData * 1E-11; - return true; } diff --git a/CounterAcq/CounterDevice.cpp b/CounterAcq/CounterDevice.cpp index 1aef95a..a6f0bd1 100644 --- a/CounterAcq/CounterDevice.cpp +++ b/CounterAcq/CounterDevice.cpp @@ -2,12 +2,16 @@ #include #include +#include CounterDevice::CounterDevice(QObject *parent) : QObject(parent) { connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &CounterDevice::dataReceivedHandler); + connect(this, &CounterDevice::successDataCalculate, + this, &CounterDevice::afterFramePhase); + // kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); // kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); // kafkaUtil.createProducer(); @@ -35,6 +39,10 @@ { this->devCode = devCode; } +void CounterDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool CounterDevice::isSerialOpen() { @@ -55,7 +63,7 @@ if (CounterProtocolBM::checkFrame(this->dataBuff) == true) { counterData->rawFrame = this->dataBuff; - std::cout << counterData->rawFrame.toStdString() << std::endl; +// std::cout << counterData->rawFrame.toStdString() << std::endl; // ★解析成数据对象 bool parse = CounterProtocolBM::parseMessureData(this->dataBuff, counterData); @@ -63,36 +71,38 @@ // 解析成功 if (parse == true) { + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 补充其他字段 QDateTime now = QDateTime::currentDateTime(); counterData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); counterData->milisecond = now.toMSecsSinceEpoch(); - this->afterFramePhase(counterData); + counterData->devCode = devCode; + + // 3 计算数据ID一样的测量数据的时差值,通道值-参考通道值 + this->pushChannelRawFrame(counterData); } } // 在此处释放内存,不影响后续显示 // 不在此处释放内存则会导致内存持续增加 - // 具体原因不明 delete counterData; } void CounterDevice::afterFramePhase(CounterDataDto * counterData) { - // 1. 清空dataBuff,等待下一帧的数据 - this->dataBuff.clear(); + // 0. 输出到日志文件中 + QString date = counterData->timestamp.mid(0, 10); - // 2. 输出到日志文件中 - QString filePostfix = counterData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; - - // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + // 1. 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; QString content = counterData->timestamp + " " + counterData->rawFrame.left(counterData->rawFrame.size() - COUNTER_FRAME_TAIL.size()); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); - // 2.2 各个通道的clock diff数据 - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + // 2. 各个通道的clock diff数据 + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (counterData->channelId < 10) { chFilename = chFilename.arg(QString("0%1").arg(counterData->channelId)); @@ -100,20 +110,76 @@ { chFilename = chFilename.arg(counterData->channelId); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(counterData->timestamp).arg(counterData->channelClockValue).arg(counterData->frameId); - - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QString channelDataStr = QString("%1 [%2] %3 %4") + .arg(counterData->timestamp) + .arg(counterData->frameId) + .arg(counterData->channelData) + .arg(counterData->channelClockValue); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) { QJsonObject jsonObj = counterData->toJSON(); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); - jsonObj.insert("deviceId", devCode); + jsonObj.insert("deviceId", deviceId); // kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } // 4. 在界面上简单显示相差数据结果 emit this->sendDataToDraw(counterData); } + +void CounterDevice::pushChannelRawFrame(CounterDataDto * counterData) +{ + QString currentFrameId = counterData->frameId; + QString currentChannelId = QString("%1").arg(counterData->channelId); + + if (counterData->channelId == counterData->channelRefId) + { + // 自身是参考通道 + bench.insert(currentFrameId, counterData->channelData); + counterData->channelClockValue = 0; + + emit successDataCalculate(counterData); + + qlonglong thisBench = counterData->channelData; + // 遍历temp,处理之前的临时暂存的队列 + if (hisList.isEmpty() == false) + { + for (int i = 0; i < hisList.size(); i++) + { + CounterDataDto * hisItem = hisList.at(i); + if (hisItem->frameId == currentFrameId) + { + hisItem->channelClockValue = (hisItem->channelData - thisBench) * 10; + + emit successDataCalculate(hisItem); + delete hisItem; + } + } + + hisList.clear(); + } + } else + { + // 自身不是参考通道,减去相同frameId的参考通道值 + if (bench.contains(currentFrameId) == true) + { + // 在参考基准中能找到 + qlonglong currentBench = bench.find(currentFrameId).value(); + counterData->channelClockValue = (counterData->channelData - currentBench) * 10; // 10ps + + emit successDataCalculate(counterData); + } else + { + // 暂存,等收到基准之后再处置 + CounterDataDto * copyPoint = new CounterDataDto(); + + // ★clone一份对象,存入缓存队列 + counterData->clone(copyPoint); + + hisList.append(copyPoint); + } + } +} diff --git a/CounterAcq/CounterDevice.h b/CounterAcq/CounterDevice.h index 3572d69..b15e44f 100644 --- a/CounterAcq/CounterDevice.h +++ b/CounterAcq/CounterDevice.h @@ -19,16 +19,16 @@ void initSerialPort(); - void afterFramePhase(CounterDataDto * counterData); - void setComName(QString comName); void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; @@ -37,11 +37,18 @@ // QKafkaUtil kafkaUtil; QByteArray dataBuff; + QMap bench; + QList hisList; + + void pushChannelRawFrame(CounterDataDto * counterData); + signals: void sendDataToDraw(CounterDataDto * counterData); + void successDataCalculate(CounterDataDto * counterData); public slots: void dataReceivedHandler(QByteArray data); + void afterFramePhase(CounterDataDto * counterData); }; #endif // COUNTERDEVICE_H diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 31d43fd..f8278f6 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -5,12 +5,12 @@ #include #include #include +#include +#include #include -#include -#include #include -#include #include +#include CounterWindow::CounterWindow(QWidget *parent) : QWidget(parent), @@ -18,56 +18,74 @@ { ui->setupUi(this); + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), 700); + resize(screenRect.width(), screenRect.height()); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); - - for (int i = 0; i < comDevList.size(); i++) - { - CounterDevice * device = new CounterDevice(this); - - // - connect(device, &CounterDevice::sendDataToDraw, - this, &CounterWindow::drawCounterDataOnPage); - - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); - - device->setDevCode(devCodeList.at(i)); - - this->deviceList.append(device); - -// device->initSerialPort(); -// device->startWork(); - } - - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget = new QWidget(this->ui->stackedWidget); - ui->stackedWidget->addWidget(devWidget); - devWidgetList.append(devWidget); - - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); httpReq = new HttpRequestController(this); - QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, - SettingConfig::getInstance().APP_KEY); - if (response.find("code")->toInt() == 200) + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - httpReq->initDictDeviceType(); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - httpReq->initDeviceList(); + QApplication::exit(0); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); + + // 3. 获取计数器设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); + + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i =0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); + + CounterDevice * device = new CounterDevice(this); + deviceList.append(device); + + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &CounterDevice::sendDataToDraw, + this, &CounterWindow::drawCounterDataOnPage); + + device->initSerialPort(); + + QThread::msleep(200); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } -// timer = new QTimer(this); -// timer->start(1000 * 10); + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } CounterWindow::~CounterWindow() @@ -75,110 +93,153 @@ delete ui; } -void CounterWindow::generateWidgetForDevice(QString devCode, int index) +void CounterWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(75); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(75); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * refChLabel = new QLabel(); + refChLabel->setText("参考通道"); + refChLabel->setFont(labelFont); + refChLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(refChLabel); + QLineEdit * refChValue = new QLineEdit(); + refChValue->setFixedWidth(60); + refChValue->setFont(labelFont); + vbox->addWidget(refChValue); + + QLabel * loadLabel = new QLabel(); + loadLabel->setText("负载"); + loadLabel->setFont(labelFont); + loadLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(loadLabel); + QLineEdit * loadValue = new QLineEdit(); + loadValue->setFixedWidth(60); + loadValue->setFont(labelFont); + vbox->addWidget(loadValue); + + QLabel * levelLabel = new QLabel(); + levelLabel->setText("触发电平"); + levelLabel->setFont(labelFont); + levelLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(levelLabel); + QLineEdit * levelValue = new QLineEdit(); + levelValue->setFixedWidth(60); + levelValue->setFont(labelFont); + vbox->addWidget(levelValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,clock").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } void CounterWindow::drawCounterDataOnPage(CounterDataDto * counterData) { // 1. 判断数据属于哪个设备,显示在不同的widget上 +// qDebug() << counterData->toJSON() << counterData->devCode << "---" << counterData->frameId; - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - QList row; - QStandardItem * itemTm = 0; - QStandardItem * itemData = 0; - itemTm = new QStandardItem(QString("%1").arg(counterData->timestamp.mid(11, 12))); - itemData = new QStandardItem(QString("%1").arg(counterData->channelData)); + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - row.append(itemTm); - row.append(itemData); - - QStandardItemModel * model; - model = devChannels.at(counterData->channelId - 1); - if (model->rowCount() >= 20) + // 如果不是当前设备的帧,直接返回 + if (counterData->devCode != currentDevCode) { - model->removeRows(0, model->rowCount()); + return; } - model->insertRow(0, row); + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(counterData->channelId); + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(counterData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 ps").arg(counterData->channelClockValue)); + ((QLineEdit *)channelBox->children().at(6))->setText(counterData->frameId); + ((QLineEdit *)channelBox->children().at(8))->setText(QString("%1").arg(counterData->channelRefId)); + ((QLineEdit *)channelBox->children().at(10))->setText(QString("%1 Ω").arg(counterData->load == 1 ? "1M" : "50")); + ((QLineEdit *)channelBox->children().at(12))->setText(QString("%1 V").arg(counterData->level)); + ((QLabel *)channelBox->children().at(13))->setText(counterData->channelActive == 1 ? "有效" : "无效"); +} -// for (int i = 0; i < counterData->channelData.size(); i++) -// { -// if (counterData->channelActive.at(i).toInt() == 1) -// { -// QList row; -// QStandardItem * item = 0; -// QStandardItem * item2 = 0; -// item = new QStandardItem(QString("%1").arg(counterData->timestamp.mid(11, 12))); -// item2 = new QStandardItem(QString("%1").arg(counterData->channelData.at(i))); +int CounterWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int CounterWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject CounterWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("计数器"); + return response; +} -// row.append(item); -// row.append(item2); +void CounterWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} -// QStandardItemModel * model; -// model = devChannels.at(i); -// if (model->rowCount() >= 60) -// { -// model->removeRows(0, model->rowCount()); -// } - -// model->insertRow(0, row); -// } -// } +void CounterWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); } diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 88ec496..3273433 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -2,7 +2,9 @@ #define COUNTERWINDOW_H #include +#include #include +#include #include "common/utils/SettingConfig.h" //#include "common/utils/QKafkaUtil.h" @@ -26,18 +28,24 @@ public slots: void drawCounterDataOnPage(CounterDataDto * counterData); +private slots: + void on_exitButt_clicked(); + + void on_minButt_clicked(); + private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + Ui::CounterWindow *ui; QTimer * timer; HttpRequestController * httpReq; - QList devWidgetList; - QList deviceList; - QList> tableModelList; - void generateWidgetForDevice(QString devCode, int index); + void generateWidgetForDevice(); }; #endif // COUNTERWINDOW_H diff --git a/CounterAcq/CounterWindow.ui b/CounterAcq/CounterWindow.ui index bcf9570..9ac6eb3 100644 --- a/CounterAcq/CounterWindow.ui +++ b/CounterAcq/CounterWindow.ui @@ -1,29 +1,156 @@ - - CounterWindow - - - - 0 - 0 - 1024 - 720 - - - - 多通道计数器数据采集 - - - - - 0 - 0 - 1024 - 720 - - - - - - - + + CounterWindow + + + + 0 + 0 + 1024 + 720 + + + + 多通道计数器数据采集 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 400 + 10 + 250 + 40 + + + + + + + 250 + 0 + 150 + 60 + + + + + 微软雅黑 + 12 + + + + Qt::LeftToRight + + + 请选择计数器 + + + Qt::AlignCenter + + + + + + 880 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 20 + 0 + 200 + 60 + + + + + 微软雅黑 + 14 + + + + 多通道计数器数据采集 + + + + + + 0 + 59 + 1024 + 1 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 830 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + diff --git a/CounterAcq/common/HttpRequestController.cpp b/CounterAcq/common/HttpRequestController.cpp index 500f902..d4912b8 100644 --- a/CounterAcq/common/HttpRequestController.cpp +++ b/CounterAcq/common/HttpRequestController.cpp @@ -38,18 +38,21 @@ document.setObject(paramObj); QByteArray content = document.toJson(QJsonDocument::Compact); - QNetworkReply *reply = httpUtil->sendPostRequest(request, content); + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); - } - if (resultObj.find("code")->toInt() == 200) + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else { - QString token = resultObj.find("data")->toString(); - this->token = token; + resultObj.insert("code", -1); } return resultObj; @@ -72,36 +75,39 @@ QNetworkReply * reply = httpUtil->sendGetRequest(request); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); - } - if (resultObj.find("code")->toInt() == 200) - { - ConstCache::getInstance().deviceTypes.clear(); - - QJsonArray data = resultObj.find("data")->toArray(); - for (int i = 0; i < data.size(); i++) + if (resultObj.find("code")->toInt() == 200) { - QJsonObject item = data.at(i).toObject(); + ConstCache::getInstance().deviceTypes.clear(); - ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } } + } else + { + resultObj.insert("code", -1); } return resultObj; } -QJsonObject HttpRequestController::initDeviceList() +QJsonObject HttpRequestController::initDeviceList(QString devType) { QJsonObject resultObj; - QString counterDevType = "01"; + QString counterDevType = ""; QMapIterator it(ConstCache::getInstance().deviceTypes); while (it.hasNext()) { it.next(); - if (it.value().contains("计数器") == true) + if (it.value().contains(devType) == true) { counterDevType = it.key(); break; @@ -120,26 +126,32 @@ request.setRawHeader("token", token.toLocal8Bit()); request.setRawHeader("system", system.toLocal8Bit()); + qDebug() << url; + QNetworkReply * reply = httpUtil->sendGetRequest(request); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); } qDebug() << resultObj; - if (resultObj.find("code")->toInt() == 200) - { - ConstCache::getInstance().deviceList.clear(); - - QJsonArray data = resultObj.find("data")->toArray(); - for (int i = 0; i < data.size(); i++) - { - QJsonObject item = data.at(i).toObject(); - - ConstCache::getInstance().deviceList.append(item); - } - } return resultObj; } diff --git a/CounterAcq/common/HttpRequestController.h b/CounterAcq/common/HttpRequestController.h index 46d9b84..77fc3db 100644 --- a/CounterAcq/common/HttpRequestController.h +++ b/CounterAcq/common/HttpRequestController.h @@ -18,7 +18,7 @@ QJsonObject getTokenByClientId(QString clientId, QString key); QJsonObject initDictDeviceType(); - QJsonObject initDeviceList(); + QJsonObject initDeviceList(QString devType); private: HttpRequestUtil * httpUtil; diff --git a/CounterAcq/common/utils/QLogUtil.cpp b/CounterAcq/common/utils/QLogUtil.cpp index 458ac15..6ec3d80 100644 --- a/CounterAcq/common/utils/QLogUtil.cpp +++ b/CounterAcq/common/utils/QLogUtil.cpp @@ -34,3 +34,59 @@ } +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "\\"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "\\"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/CounterAcq/common/utils/QLogUtil.h b/CounterAcq/common/utils/QLogUtil.h index 8da0fcd..1d1ef0f 100644 --- a/CounterAcq/common/utils/QLogUtil.h +++ b/CounterAcq/common/utils/QLogUtil.h @@ -3,7 +3,9 @@ #include #include +#include #include +#include "SettingConfig.h" class QLogUtil : public QObject { @@ -16,6 +18,11 @@ static void writeInfoLog(QString message); static void writeDebugLog(QString message); + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); signals: }; diff --git a/CounterAcq/common/utils/QSerialPortUtil.cpp b/CounterAcq/common/utils/QSerialPortUtil.cpp index 2da13b2..7af0555 100644 --- a/CounterAcq/common/utils/QSerialPortUtil.cpp +++ b/CounterAcq/common/utils/QSerialPortUtil.cpp @@ -63,7 +63,7 @@ QByteArray buffer; QString channel = QString("%1").arg(i); - QString channelRef = "1"; + QString channelRef = "3"; QString dataValue = QString("%1").arg(qrand() % 400); QString level = QString("%1").arg(qrand() % 4 / (double) 10); QString frameId = QString("%1").arg(now.toSecsSinceEpoch() % 10000); diff --git a/CounterAcq/common/utils/SettingConfig.cpp b/CounterAcq/common/utils/SettingConfig.cpp index e9d136e..1f2ebb2 100644 --- a/CounterAcq/common/utils/SettingConfig.cpp +++ b/CounterAcq/common/utils/SettingConfig.cpp @@ -5,9 +5,7 @@ filename = QApplication::applicationDirPath() + "/conf/config.ini"; setting = new QSettings(this->filename, QSettings::IniFormat); - PORT_NAMES = getProperty("com", "portNames").toString(); BAUD_RATE = getProperty("com", "baudRate").toUInt(); - DEV_CODES = getProperty("com", "devCodes").toString(); NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); @@ -17,6 +15,8 @@ APP_KEY = getProperty("client", "appKey").toString(); BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); } diff --git a/CounterAcq/common/utils/SettingConfig.h b/CounterAcq/common/utils/SettingConfig.h index 227d029..ce1e933 100644 --- a/CounterAcq/common/utils/SettingConfig.h +++ b/CounterAcq/common/utils/SettingConfig.h @@ -27,9 +27,7 @@ QVariant getProperty(QString nodeName, QString keyName); /******** 以下为需要的各类参数 ********/ - QString PORT_NAMES; int BAUD_RATE; - QString DEV_CODES; int NEED_KAFKA; QString KAFKA_BROKERS; @@ -40,6 +38,8 @@ QString BASE_URL; + QString BASE_LOG_PATH; + private: SettingConfig(); diff --git a/CounterAcq/conf/config.ini b/CounterAcq/conf/config.ini index 0321e65..ebe1e82 100644 --- a/CounterAcq/conf/config.ini +++ b/CounterAcq/conf/config.ini @@ -1,10 +1,8 @@ [com] -portNames="COM1,COM2,COM3" -devCodes="9101,9102,9103" baudRate=115200 [kafka] -needKafka=1 +needKafka=0 brokers="111.198.10.15:12502" dataTopic="cppTest" @@ -14,3 +12,6 @@ [http] baseUrl="http://111.198.10.15:11410" + +[log] +basePath="D://Workspace Qt//ZXSSCJ-Release//Counter//logs//" diff --git a/CounterAcq/protocol/CounterProtocolBM.cpp b/CounterAcq/protocol/CounterProtocolBM.cpp index b33be0d..2aca849 100644 --- a/CounterAcq/protocol/CounterProtocolBM.cpp +++ b/CounterAcq/protocol/CounterProtocolBM.cpp @@ -25,12 +25,10 @@ counterData->channelActive = subList.at(2).toUInt(); counterData->channelRefId = subList.at(3).toUInt(); counterData->channelData = subList.at(4).toLongLong(); - counterData->load = subList.at(5).toDouble(); + counterData->load = subList.at(5); counterData->level = subList.at(6).toDouble(); counterData->frameId = subList.at(7); - counterData->channelClockValue = counterData->channelData * 1E-11; - return true; } diff --git a/CounterAcq/protocol/dto/CounterDataDto.cpp b/CounterAcq/protocol/dto/CounterDataDto.cpp index 99b8b09..3cd2078 100644 --- a/CounterAcq/protocol/dto/CounterDataDto.cpp +++ b/CounterAcq/protocol/dto/CounterDataDto.cpp @@ -1,4 +1,4 @@ -#include "CounterDataDto.h" +#include "CounterDataDto.h" #include "common/utils/SettingConfig.h" CounterDataDto::CounterDataDto(QObject *parent) : QObject(parent) @@ -12,7 +12,8 @@ QJsonObject dataObj; dataObj.insert("channelRefNo", this->channelRefId); - dataObj.insert("dataValue", QString("%1").arg(this->channelClockValue)); + dataObj.insert("dataValue", QString("%1").arg(this->channelClockValue * 1E-12)); + dataObj.insert("rawValue", QString("%1").arg(this->channelData)); dataObj.insert("frameId", this->frameId); jsonObj.insert("channelNo", this->channelId); @@ -21,3 +22,24 @@ return jsonObj; } + +void CounterDataDto::clone(CounterDataDto *copy) +{ + copy->frameId = this->frameId; + copy->level = this->level; + copy->load = this->load; + copy->channelData = this->channelData; + copy->channelRefId = this->channelRefId; + copy->channelActive = this->channelActive; + copy->channelId = channelId; + copy->type = 0; + + copy->channelClockValue = this->channelClockValue; + + copy->rawFrame = this->rawFrame; + + copy->timestamp = this->timestamp; + copy->milisecond = this->milisecond; + copy->devCode = this->devCode; + copy->devStatus = this->devStatus; +} diff --git a/CounterAcq/CounterDevice.cpp b/CounterAcq/CounterDevice.cpp index 1aef95a..a6f0bd1 100644 --- a/CounterAcq/CounterDevice.cpp +++ b/CounterAcq/CounterDevice.cpp @@ -2,12 +2,16 @@ #include #include +#include CounterDevice::CounterDevice(QObject *parent) : QObject(parent) { connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, this, &CounterDevice::dataReceivedHandler); + connect(this, &CounterDevice::successDataCalculate, + this, &CounterDevice::afterFramePhase); + // kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); // kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); // kafkaUtil.createProducer(); @@ -35,6 +39,10 @@ { this->devCode = devCode; } +void CounterDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} bool CounterDevice::isSerialOpen() { @@ -55,7 +63,7 @@ if (CounterProtocolBM::checkFrame(this->dataBuff) == true) { counterData->rawFrame = this->dataBuff; - std::cout << counterData->rawFrame.toStdString() << std::endl; +// std::cout << counterData->rawFrame.toStdString() << std::endl; // ★解析成数据对象 bool parse = CounterProtocolBM::parseMessureData(this->dataBuff, counterData); @@ -63,36 +71,38 @@ // 解析成功 if (parse == true) { + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 补充其他字段 QDateTime now = QDateTime::currentDateTime(); counterData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); counterData->milisecond = now.toMSecsSinceEpoch(); - this->afterFramePhase(counterData); + counterData->devCode = devCode; + + // 3 计算数据ID一样的测量数据的时差值,通道值-参考通道值 + this->pushChannelRawFrame(counterData); } } // 在此处释放内存,不影响后续显示 // 不在此处释放内存则会导致内存持续增加 - // 具体原因不明 delete counterData; } void CounterDevice::afterFramePhase(CounterDataDto * counterData) { - // 1. 清空dataBuff,等待下一帧的数据 - this->dataBuff.clear(); + // 0. 输出到日志文件中 + QString date = counterData->timestamp.mid(0, 10); - // 2. 输出到日志文件中 - QString filePostfix = counterData->timestamp.mid(0, 13).replace(" ", "_"); - QString filePrefix = QApplication::applicationDirPath() + "/logs/"; - - // 2.1 原始字节数组数据 - QString filename = filePrefix + "raw_" + filePostfix + ".log"; + // 1. 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; QString content = counterData->timestamp + " " + counterData->rawFrame.left(counterData->rawFrame.size() - COUNTER_FRAME_TAIL.size()); - QLogUtil::writeRawDataLog(filename, content); + QLogUtil::writeRawDataLogByDate(date, filename, content); - // 2.2 各个通道的clock diff数据 - QString chFilename("%1CH_%2_%3.log"); - chFilename = chFilename.arg(filePrefix); + // 2. 各个通道的clock diff数据 + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); if (counterData->channelId < 10) { chFilename = chFilename.arg(QString("0%1").arg(counterData->channelId)); @@ -100,20 +110,76 @@ { chFilename = chFilename.arg(counterData->channelId); } - chFilename = chFilename.arg(filePostfix); - QString channelDataStr = QString("%1 %2 %3").arg(counterData->timestamp).arg(counterData->channelClockValue).arg(counterData->frameId); - - QLogUtil::writeChannelDataLog(chFilename, channelDataStr); + QString channelDataStr = QString("%1 [%2] %3 %4") + .arg(counterData->timestamp) + .arg(counterData->frameId) + .arg(counterData->channelData) + .arg(counterData->channelClockValue); + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); // 3. 输出到中间件,执行后续处理过程 if (SettingConfig::getInstance().NEED_KAFKA == 1) { QJsonObject jsonObj = counterData->toJSON(); jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); - jsonObj.insert("deviceId", devCode); + jsonObj.insert("deviceId", deviceId); // kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); } // 4. 在界面上简单显示相差数据结果 emit this->sendDataToDraw(counterData); } + +void CounterDevice::pushChannelRawFrame(CounterDataDto * counterData) +{ + QString currentFrameId = counterData->frameId; + QString currentChannelId = QString("%1").arg(counterData->channelId); + + if (counterData->channelId == counterData->channelRefId) + { + // 自身是参考通道 + bench.insert(currentFrameId, counterData->channelData); + counterData->channelClockValue = 0; + + emit successDataCalculate(counterData); + + qlonglong thisBench = counterData->channelData; + // 遍历temp,处理之前的临时暂存的队列 + if (hisList.isEmpty() == false) + { + for (int i = 0; i < hisList.size(); i++) + { + CounterDataDto * hisItem = hisList.at(i); + if (hisItem->frameId == currentFrameId) + { + hisItem->channelClockValue = (hisItem->channelData - thisBench) * 10; + + emit successDataCalculate(hisItem); + delete hisItem; + } + } + + hisList.clear(); + } + } else + { + // 自身不是参考通道,减去相同frameId的参考通道值 + if (bench.contains(currentFrameId) == true) + { + // 在参考基准中能找到 + qlonglong currentBench = bench.find(currentFrameId).value(); + counterData->channelClockValue = (counterData->channelData - currentBench) * 10; // 10ps + + emit successDataCalculate(counterData); + } else + { + // 暂存,等收到基准之后再处置 + CounterDataDto * copyPoint = new CounterDataDto(); + + // ★clone一份对象,存入缓存队列 + counterData->clone(copyPoint); + + hisList.append(copyPoint); + } + } +} diff --git a/CounterAcq/CounterDevice.h b/CounterAcq/CounterDevice.h index 3572d69..b15e44f 100644 --- a/CounterAcq/CounterDevice.h +++ b/CounterAcq/CounterDevice.h @@ -19,16 +19,16 @@ void initSerialPort(); - void afterFramePhase(CounterDataDto * counterData); - void setComName(QString comName); void setBaudRate(int baudRate); QString getDevCode(); void setDevCode(QString devCode); + void setDeviceId(QString deviceId); bool isSerialOpen(); private: + QString deviceId; QString devCode; QString comName; int baudRate; @@ -37,11 +37,18 @@ // QKafkaUtil kafkaUtil; QByteArray dataBuff; + QMap bench; + QList hisList; + + void pushChannelRawFrame(CounterDataDto * counterData); + signals: void sendDataToDraw(CounterDataDto * counterData); + void successDataCalculate(CounterDataDto * counterData); public slots: void dataReceivedHandler(QByteArray data); + void afterFramePhase(CounterDataDto * counterData); }; #endif // COUNTERDEVICE_H diff --git a/CounterAcq/CounterWindow.cpp b/CounterAcq/CounterWindow.cpp index 31d43fd..f8278f6 100644 --- a/CounterAcq/CounterWindow.cpp +++ b/CounterAcq/CounterWindow.cpp @@ -5,12 +5,12 @@ #include #include #include +#include +#include #include -#include -#include #include -#include #include +#include CounterWindow::CounterWindow(QWidget *parent) : QWidget(parent), @@ -18,56 +18,74 @@ { ui->setupUi(this); + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 QRect screenRect = QApplication::desktop()->screenGeometry(); - resize(screenRect.width(), 700); + resize(screenRect.width(), screenRect.height()); - QString portNames = SettingConfig::getInstance().PORT_NAMES; - int baudRate = SettingConfig::getInstance().BAUD_RATE; - QString devCodes = SettingConfig::getInstance().DEV_CODES; + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->line->setGeometry(0, 59, screenRect.width(), 1); - QStringList comDevList = portNames.split(","); - QStringList devCodeList = devCodes.split(","); - - for (int i = 0; i < comDevList.size(); i++) - { - CounterDevice * device = new CounterDevice(this); - - // - connect(device, &CounterDevice::sendDataToDraw, - this, &CounterWindow::drawCounterDataOnPage); - - device->setComName(comDevList.at(i)); - device->setBaudRate(baudRate); - - device->setDevCode(devCodeList.at(i)); - - this->deviceList.append(device); - -// device->initSerialPort(); -// device->startWork(); - } - - for (int i = 0; i < this->deviceList.size(); i++) - { - QWidget * devWidget = new QWidget(this->ui->stackedWidget); - ui->stackedWidget->addWidget(devWidget); - devWidgetList.append(devWidget); - - this->generateWidgetForDevice(devCodeList.at(i), i); - } + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); httpReq = new HttpRequestController(this); - QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, - SettingConfig::getInstance().APP_KEY); - if (response.find("code")->toInt() == 200) + // 1. 获取访问接口需要的token + int retCode = this->initHttpToken(); + if (retCode != 200) { - httpReq->initDictDeviceType(); + QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); - httpReq->initDeviceList(); + QApplication::exit(0); + } + // 2. 获取字典值:设备类型 + retCode = this->initDictDeviceTypes(); + + // 3. 获取计数器设备列表 + QJsonObject devListRes = this->initDeviceList(); + if (devListRes.find("code")->toInt() == 200) + { + ui->devSelect->clear(); + + // 4. 将获取到的设备添加到下拉列表框中 + QJsonArray devArray = devListRes.find("data")->toArray(); + for (int i =0; i < devArray.size(); i++) + { + QJsonObject devItem = devArray.at(i).toObject(); + ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString()); + + CounterDevice * device = new CounterDevice(this); + deviceList.append(device); + + device->setComName(devItem.find("linkComName")->toString()); + device->setBaudRate(SettingConfig::getInstance().BAUD_RATE); + device->setDevCode(devItem.find("deviceNo")->toString()); + device->setDeviceId(devItem.find("deviceId")->toString()); + + connect(device, &CounterDevice::sendDataToDraw, + this, &CounterWindow::drawCounterDataOnPage); + + device->initSerialPort(); + + QThread::msleep(200); + } + // 5. 设置下拉框的样式 + QStandardItemModel * model = qobject_cast(ui->devSelect->model()); + for (int i = 0; i < model->rowCount(); ++i) + { + QStandardItem * item = model->item(i); + item->setSizeHint({ 0, 30 }); + } } -// timer = new QTimer(this); -// timer->start(1000 * 10); + // 6. 绘制一个设备的多个通道数据面板 + this->generateWidgetForDevice(); } CounterWindow::~CounterWindow() @@ -75,110 +93,153 @@ delete ui; } -void CounterWindow::generateWidgetForDevice(QString devCode, int index) +void CounterWindow::generateWidgetForDevice() { - // 顶部切换widget - QWidget * switchWidget = new QWidget(this->devWidgetList.at(index)); - switchWidget->setGeometry(0, 0, 1024, 50); + // 获取设备数据 + int channelNum = 16; - // 显示数据的区域 - QWidget * gridWidget = new QWidget(this->devWidgetList.at(index)); - gridWidget->setGeometry(0, 50, 1024, 670); + QRect screenRect = QApplication::desktop()->screenGeometry(); - // 顶部水平布局,用于排布按钮 - QHBoxLayout * hLayout = new QHBoxLayout(switchWidget); + ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90); - // 文本 - QLabel * label = new QLabel(switchWidget); - label->setText("设备编号:" + devCode); - label->setFont(QFont("微软雅黑", 12)); - hLayout->addWidget(label); + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); - // 按钮 - for (int i = 0; i < this->deviceList.size(); i++) + for (int i = 0; i < channelNum; i++) { - QPushButton * butt5 = new QPushButton(this->deviceList.at(i)->getDevCode()); - hLayout->addWidget(butt5); + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80); - connect(butt5, &QPushButton::clicked, [=](){ - this->ui->stackedWidget->setCurrentIndex(i); - }); + QHBoxLayout * vbox = new QHBoxLayout(group); + + QLabel * tmLabel = new QLabel(); + tmLabel->setText("时间"); + tmLabel->setFont(labelFont); + tmLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(tmLabel); + QLineEdit * tmValue = new QLineEdit(); + tmValue->setFixedWidth(200); + tmValue->setFont(labelFont); + vbox->addWidget(tmValue); + + QLabel * dataLabel = new QLabel(); + dataLabel->setText("测量数据"); + dataLabel->setFont(labelFont); + dataLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(dataLabel); + QLineEdit * dataValue = new QLineEdit(); + dataValue->setFixedWidth(75); + dataValue->setFont(labelFont); + vbox->addWidget(dataValue); + + QLabel * idLabel = new QLabel(); + idLabel->setText("数据ID"); + idLabel->setFont(labelFont); + idLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(idLabel); + QLineEdit * idValue = new QLineEdit(); + idValue->setFixedWidth(75); + idValue->setFont(labelFont); + vbox->addWidget(idValue); + + QLabel * refChLabel = new QLabel(); + refChLabel->setText("参考通道"); + refChLabel->setFont(labelFont); + refChLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(refChLabel); + QLineEdit * refChValue = new QLineEdit(); + refChValue->setFixedWidth(60); + refChValue->setFont(labelFont); + vbox->addWidget(refChValue); + + QLabel * loadLabel = new QLabel(); + loadLabel->setText("负载"); + loadLabel->setFont(labelFont); + loadLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(loadLabel); + QLineEdit * loadValue = new QLineEdit(); + loadValue->setFixedWidth(60); + loadValue->setFont(labelFont); + vbox->addWidget(loadValue); + + QLabel * levelLabel = new QLabel(); + levelLabel->setText("触发电平"); + levelLabel->setFont(labelFont); + levelLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(levelLabel); + QLineEdit * levelValue = new QLineEdit(); + levelValue->setFixedWidth(60); + levelValue->setFont(labelFont); + vbox->addWidget(levelValue); + + QLabel * validLabel = new QLabel(); + validLabel->setText("-"); + validLabel->setFont(labelFont); + validLabel->setStyleSheet("margin-left:20;"); + vbox->addWidget(validLabel); + + QSpacerItem * hSpace = new QSpacerItem(20, 20); + hSpace->changeSize(20, 20, QSizePolicy::Expanding); + vbox->addItem(hSpace); + + group->setLayout(vbox); + + layout->addWidget(group); } - - // Grid布局 - QGridLayout * gridLayout = new QGridLayout(gridWidget); - gridLayout->setSpacing(10); - - QList channelModelList; - QStringList labels = QObject::trUtf8("时间,clock").simplified().split(","); - - for (int i = 0; i < 16; i++) - { - QTableView * channelTable = new QTableView(gridWidget); - QStandardItemModel * model = new QStandardItemModel(channelTable); - - model->setHorizontalHeaderLabels(labels); - - channelTable->setModel(model); - - gridLayout->addWidget(channelTable, i / 4, i % 4); - - channelTable->verticalHeader()->hide(); - channelTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - channelTable->scrollToBottom(); - - channelModelList.append(model); - } - - this->tableModelList.append(channelModelList); } void CounterWindow::drawCounterDataOnPage(CounterDataDto * counterData) { // 1. 判断数据属于哪个设备,显示在不同的widget上 +// qDebug() << counterData->toJSON() << counterData->devCode << "---" << counterData->frameId; - // 2. 循环设置各个tableView - QList devChannels = this->tableModelList.at(0); // 暂时写死 - QList row; - QStandardItem * itemTm = 0; - QStandardItem * itemData = 0; - itemTm = new QStandardItem(QString("%1").arg(counterData->timestamp.mid(11, 12))); - itemData = new QStandardItem(QString("%1").arg(counterData->channelData)); + // 当前显示的设备编号 + QString currentDevCode = ui->devSelect->currentData().toString(); - row.append(itemTm); - row.append(itemData); - - QStandardItemModel * model; - model = devChannels.at(counterData->channelId - 1); - if (model->rowCount() >= 20) + // 如果不是当前设备的帧,直接返回 + if (counterData->devCode != currentDevCode) { - model->removeRows(0, model->rowCount()); + return; } - model->insertRow(0, row); + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(counterData->channelId); + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(counterData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 ps").arg(counterData->channelClockValue)); + ((QLineEdit *)channelBox->children().at(6))->setText(counterData->frameId); + ((QLineEdit *)channelBox->children().at(8))->setText(QString("%1").arg(counterData->channelRefId)); + ((QLineEdit *)channelBox->children().at(10))->setText(QString("%1 Ω").arg(counterData->load == 1 ? "1M" : "50")); + ((QLineEdit *)channelBox->children().at(12))->setText(QString("%1 V").arg(counterData->level)); + ((QLabel *)channelBox->children().at(13))->setText(counterData->channelActive == 1 ? "有效" : "无效"); +} -// for (int i = 0; i < counterData->channelData.size(); i++) -// { -// if (counterData->channelActive.at(i).toInt() == 1) -// { -// QList row; -// QStandardItem * item = 0; -// QStandardItem * item2 = 0; -// item = new QStandardItem(QString("%1").arg(counterData->timestamp.mid(11, 12))); -// item2 = new QStandardItem(QString("%1").arg(counterData->channelData.at(i))); +int CounterWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int CounterWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject CounterWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("计数器"); + return response; +} -// row.append(item); -// row.append(item2); +void CounterWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} -// QStandardItemModel * model; -// model = devChannels.at(i); -// if (model->rowCount() >= 60) -// { -// model->removeRows(0, model->rowCount()); -// } - -// model->insertRow(0, row); -// } -// } +void CounterWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); } diff --git a/CounterAcq/CounterWindow.h b/CounterAcq/CounterWindow.h index 88ec496..3273433 100644 --- a/CounterAcq/CounterWindow.h +++ b/CounterAcq/CounterWindow.h @@ -2,7 +2,9 @@ #define COUNTERWINDOW_H #include +#include #include +#include #include "common/utils/SettingConfig.h" //#include "common/utils/QKafkaUtil.h" @@ -26,18 +28,24 @@ public slots: void drawCounterDataOnPage(CounterDataDto * counterData); +private slots: + void on_exitButt_clicked(); + + void on_minButt_clicked(); + private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + Ui::CounterWindow *ui; QTimer * timer; HttpRequestController * httpReq; - QList devWidgetList; - QList deviceList; - QList> tableModelList; - void generateWidgetForDevice(QString devCode, int index); + void generateWidgetForDevice(); }; #endif // COUNTERWINDOW_H diff --git a/CounterAcq/CounterWindow.ui b/CounterAcq/CounterWindow.ui index bcf9570..9ac6eb3 100644 --- a/CounterAcq/CounterWindow.ui +++ b/CounterAcq/CounterWindow.ui @@ -1,29 +1,156 @@ - - CounterWindow - - - - 0 - 0 - 1024 - 720 - - - - 多通道计数器数据采集 - - - - - 0 - 0 - 1024 - 720 - - - - - - - + + CounterWindow + + + + 0 + 0 + 1024 + 720 + + + + 多通道计数器数据采集 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 400 + 10 + 250 + 40 + + + + + + + 250 + 0 + 150 + 60 + + + + + 微软雅黑 + 12 + + + + Qt::LeftToRight + + + 请选择计数器 + + + Qt::AlignCenter + + + + + + 880 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 20 + 0 + 200 + 60 + + + + + 微软雅黑 + 14 + + + + 多通道计数器数据采集 + + + + + + 0 + 59 + 1024 + 1 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 830 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + diff --git a/CounterAcq/common/HttpRequestController.cpp b/CounterAcq/common/HttpRequestController.cpp index 500f902..d4912b8 100644 --- a/CounterAcq/common/HttpRequestController.cpp +++ b/CounterAcq/common/HttpRequestController.cpp @@ -38,18 +38,21 @@ document.setObject(paramObj); QByteArray content = document.toJson(QJsonDocument::Compact); - QNetworkReply *reply = httpUtil->sendPostRequest(request, content); + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); - } - if (resultObj.find("code")->toInt() == 200) + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else { - QString token = resultObj.find("data")->toString(); - this->token = token; + resultObj.insert("code", -1); } return resultObj; @@ -72,36 +75,39 @@ QNetworkReply * reply = httpUtil->sendGetRequest(request); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); - } - if (resultObj.find("code")->toInt() == 200) - { - ConstCache::getInstance().deviceTypes.clear(); - - QJsonArray data = resultObj.find("data")->toArray(); - for (int i = 0; i < data.size(); i++) + if (resultObj.find("code")->toInt() == 200) { - QJsonObject item = data.at(i).toObject(); + ConstCache::getInstance().deviceTypes.clear(); - ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceTypes.insert(item.find("value")->toString(), item.find("name")->toString()); + } } + } else + { + resultObj.insert("code", -1); } return resultObj; } -QJsonObject HttpRequestController::initDeviceList() +QJsonObject HttpRequestController::initDeviceList(QString devType) { QJsonObject resultObj; - QString counterDevType = "01"; + QString counterDevType = ""; QMapIterator it(ConstCache::getInstance().deviceTypes); while (it.hasNext()) { it.next(); - if (it.value().contains("计数器") == true) + if (it.value().contains(devType) == true) { counterDevType = it.key(); break; @@ -120,26 +126,32 @@ request.setRawHeader("token", token.toLocal8Bit()); request.setRawHeader("system", system.toLocal8Bit()); + qDebug() << url; + QNetworkReply * reply = httpUtil->sendGetRequest(request); const QByteArray reply_data = reply->readAll(); QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); - if( jsonDocument.isNull() == false ) { + if(jsonDocument.isNull() == false) { resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + ConstCache::getInstance().deviceList.clear(); + + QJsonArray data = resultObj.find("data")->toArray(); + for (int i = 0; i < data.size(); i++) + { + QJsonObject item = data.at(i).toObject(); + + ConstCache::getInstance().deviceList.append(item); + } + } + } else + { + resultObj.insert("code", -1); } qDebug() << resultObj; - if (resultObj.find("code")->toInt() == 200) - { - ConstCache::getInstance().deviceList.clear(); - - QJsonArray data = resultObj.find("data")->toArray(); - for (int i = 0; i < data.size(); i++) - { - QJsonObject item = data.at(i).toObject(); - - ConstCache::getInstance().deviceList.append(item); - } - } return resultObj; } diff --git a/CounterAcq/common/HttpRequestController.h b/CounterAcq/common/HttpRequestController.h index 46d9b84..77fc3db 100644 --- a/CounterAcq/common/HttpRequestController.h +++ b/CounterAcq/common/HttpRequestController.h @@ -18,7 +18,7 @@ QJsonObject getTokenByClientId(QString clientId, QString key); QJsonObject initDictDeviceType(); - QJsonObject initDeviceList(); + QJsonObject initDeviceList(QString devType); private: HttpRequestUtil * httpUtil; diff --git a/CounterAcq/common/utils/QLogUtil.cpp b/CounterAcq/common/utils/QLogUtil.cpp index 458ac15..6ec3d80 100644 --- a/CounterAcq/common/utils/QLogUtil.cpp +++ b/CounterAcq/common/utils/QLogUtil.cpp @@ -34,3 +34,59 @@ } +void QLogUtil::writeRawDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "\\"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile rawLogFile(datePath + filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLogByDate(QString date, QString filename, QString content) +{ + QString basePath = SettingConfig::getInstance().BASE_LOG_PATH; + QString datePath = basePath + date + "\\"; + + QStringList pathList; + pathList.append(basePath); + pathList.append(datePath); + + // 检查并创建目录 + QLogUtil::checkLogPath(pathList); + + // 输出内容到日志中 + content.append("\n"); + QFile chLogFile(datePath + filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::checkLogPath(QStringList path) +{ + QDir dir; + bool exist = false; + + for (int i = 0; i < path.size(); i++) + { + // 判断是否存在日志根目录 + exist = dir.exists(path.at(i)); + if (exist == false) + { + // 不存在则创建目录 + dir.mkdir(path.at(i)); + } + } +} diff --git a/CounterAcq/common/utils/QLogUtil.h b/CounterAcq/common/utils/QLogUtil.h index 8da0fcd..1d1ef0f 100644 --- a/CounterAcq/common/utils/QLogUtil.h +++ b/CounterAcq/common/utils/QLogUtil.h @@ -3,7 +3,9 @@ #include #include +#include #include +#include "SettingConfig.h" class QLogUtil : public QObject { @@ -16,6 +18,11 @@ static void writeInfoLog(QString message); static void writeDebugLog(QString message); + static void writeRawDataLogByDate(QString date, QString filename, QString content); + static void writeChannelDataLogByDate(QString date, QString filename, QString content); + +private: + static void checkLogPath(QStringList path); signals: }; diff --git a/CounterAcq/common/utils/QSerialPortUtil.cpp b/CounterAcq/common/utils/QSerialPortUtil.cpp index 2da13b2..7af0555 100644 --- a/CounterAcq/common/utils/QSerialPortUtil.cpp +++ b/CounterAcq/common/utils/QSerialPortUtil.cpp @@ -63,7 +63,7 @@ QByteArray buffer; QString channel = QString("%1").arg(i); - QString channelRef = "1"; + QString channelRef = "3"; QString dataValue = QString("%1").arg(qrand() % 400); QString level = QString("%1").arg(qrand() % 4 / (double) 10); QString frameId = QString("%1").arg(now.toSecsSinceEpoch() % 10000); diff --git a/CounterAcq/common/utils/SettingConfig.cpp b/CounterAcq/common/utils/SettingConfig.cpp index e9d136e..1f2ebb2 100644 --- a/CounterAcq/common/utils/SettingConfig.cpp +++ b/CounterAcq/common/utils/SettingConfig.cpp @@ -5,9 +5,7 @@ filename = QApplication::applicationDirPath() + "/conf/config.ini"; setting = new QSettings(this->filename, QSettings::IniFormat); - PORT_NAMES = getProperty("com", "portNames").toString(); BAUD_RATE = getProperty("com", "baudRate").toUInt(); - DEV_CODES = getProperty("com", "devCodes").toString(); NEED_KAFKA = getProperty("kafka", "needKafka").toUInt(); KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); @@ -17,6 +15,8 @@ APP_KEY = getProperty("client", "appKey").toString(); BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); } diff --git a/CounterAcq/common/utils/SettingConfig.h b/CounterAcq/common/utils/SettingConfig.h index 227d029..ce1e933 100644 --- a/CounterAcq/common/utils/SettingConfig.h +++ b/CounterAcq/common/utils/SettingConfig.h @@ -27,9 +27,7 @@ QVariant getProperty(QString nodeName, QString keyName); /******** 以下为需要的各类参数 ********/ - QString PORT_NAMES; int BAUD_RATE; - QString DEV_CODES; int NEED_KAFKA; QString KAFKA_BROKERS; @@ -40,6 +38,8 @@ QString BASE_URL; + QString BASE_LOG_PATH; + private: SettingConfig(); diff --git a/CounterAcq/conf/config.ini b/CounterAcq/conf/config.ini index 0321e65..ebe1e82 100644 --- a/CounterAcq/conf/config.ini +++ b/CounterAcq/conf/config.ini @@ -1,10 +1,8 @@ [com] -portNames="COM1,COM2,COM3" -devCodes="9101,9102,9103" baudRate=115200 [kafka] -needKafka=1 +needKafka=0 brokers="111.198.10.15:12502" dataTopic="cppTest" @@ -14,3 +12,6 @@ [http] baseUrl="http://111.198.10.15:11410" + +[log] +basePath="D://Workspace Qt//ZXSSCJ-Release//Counter//logs//" diff --git a/CounterAcq/protocol/CounterProtocolBM.cpp b/CounterAcq/protocol/CounterProtocolBM.cpp index b33be0d..2aca849 100644 --- a/CounterAcq/protocol/CounterProtocolBM.cpp +++ b/CounterAcq/protocol/CounterProtocolBM.cpp @@ -25,12 +25,10 @@ counterData->channelActive = subList.at(2).toUInt(); counterData->channelRefId = subList.at(3).toUInt(); counterData->channelData = subList.at(4).toLongLong(); - counterData->load = subList.at(5).toDouble(); + counterData->load = subList.at(5); counterData->level = subList.at(6).toDouble(); counterData->frameId = subList.at(7); - counterData->channelClockValue = counterData->channelData * 1E-11; - return true; } diff --git a/CounterAcq/protocol/dto/CounterDataDto.cpp b/CounterAcq/protocol/dto/CounterDataDto.cpp index 99b8b09..3cd2078 100644 --- a/CounterAcq/protocol/dto/CounterDataDto.cpp +++ b/CounterAcq/protocol/dto/CounterDataDto.cpp @@ -1,4 +1,4 @@ -#include "CounterDataDto.h" +#include "CounterDataDto.h" #include "common/utils/SettingConfig.h" CounterDataDto::CounterDataDto(QObject *parent) : QObject(parent) @@ -12,7 +12,8 @@ QJsonObject dataObj; dataObj.insert("channelRefNo", this->channelRefId); - dataObj.insert("dataValue", QString("%1").arg(this->channelClockValue)); + dataObj.insert("dataValue", QString("%1").arg(this->channelClockValue * 1E-12)); + dataObj.insert("rawValue", QString("%1").arg(this->channelData)); dataObj.insert("frameId", this->frameId); jsonObj.insert("channelNo", this->channelId); @@ -21,3 +22,24 @@ return jsonObj; } + +void CounterDataDto::clone(CounterDataDto *copy) +{ + copy->frameId = this->frameId; + copy->level = this->level; + copy->load = this->load; + copy->channelData = this->channelData; + copy->channelRefId = this->channelRefId; + copy->channelActive = this->channelActive; + copy->channelId = channelId; + copy->type = 0; + + copy->channelClockValue = this->channelClockValue; + + copy->rawFrame = this->rawFrame; + + copy->timestamp = this->timestamp; + copy->milisecond = this->milisecond; + copy->devCode = this->devCode; + copy->devStatus = this->devStatus; +} diff --git a/CounterAcq/protocol/dto/CounterDataDto.h b/CounterAcq/protocol/dto/CounterDataDto.h index 6f4488f..546fd02 100644 --- a/CounterAcq/protocol/dto/CounterDataDto.h +++ b/CounterAcq/protocol/dto/CounterDataDto.h @@ -30,6 +30,7 @@ QString devStatus; QJsonObject toJSON(); + void clone(CounterDataDto * copy); signals: