diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/PhaseWindow.h b/PhaseWindow.h new file mode 100644 index 0000000..02a7908 --- /dev/null +++ b/PhaseWindow.h @@ -0,0 +1,47 @@ +#ifndef PHASEWINDOW_H +#define PHASEWINDOW_H + +#include +#include +#include +#include + +#include "PhaseDevice.h" +#include "common/utils/SettingConfig.h" +#include "common/HttpRequestController.h" + +namespace Ui { +class PhaseWindow; +} + +class PhaseWindow : public QWidget +{ + Q_OBJECT + +public: + explicit PhaseWindow(QWidget *parent = nullptr); + ~PhaseWindow(); + +public slots: + void drawPhaseDataOnPage(PhaseDataDto * phaseData); + +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + +private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + + Ui::PhaseWindow *ui; + + HttpRequestController * httpReq; + + QList deviceList; + + void generateWidgetForDevice(); +}; + +#endif // PHASEWINDOW_H diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/PhaseWindow.h b/PhaseWindow.h new file mode 100644 index 0000000..02a7908 --- /dev/null +++ b/PhaseWindow.h @@ -0,0 +1,47 @@ +#ifndef PHASEWINDOW_H +#define PHASEWINDOW_H + +#include +#include +#include +#include + +#include "PhaseDevice.h" +#include "common/utils/SettingConfig.h" +#include "common/HttpRequestController.h" + +namespace Ui { +class PhaseWindow; +} + +class PhaseWindow : public QWidget +{ + Q_OBJECT + +public: + explicit PhaseWindow(QWidget *parent = nullptr); + ~PhaseWindow(); + +public slots: + void drawPhaseDataOnPage(PhaseDataDto * phaseData); + +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + +private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + + Ui::PhaseWindow *ui; + + HttpRequestController * httpReq; + + QList deviceList; + + void generateWidgetForDevice(); +}; + +#endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui new file mode 100644 index 0000000..97edbe1 --- /dev/null +++ b/PhaseWindow.ui @@ -0,0 +1,712 @@ + + + PhaseWindow + + + + 0 + 0 + 1366 + 720 + + + + + 1366 + 0 + + + + 比相仪测量软件 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 1300 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 100 + 0 + 200 + 41 + + + + + 微软雅黑 + 14 + + + + 比相仪测量软件 + + + + + + 0 + 90 + 1371 + 16 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 1250 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + 1200 + 10 + 40 + 40 + + + + + + + 配置 + + + + + + 40 + 40 + 141 + 51 + + + + + 微软雅黑 + 14 + 75 + true + + + + Qt::RightToLeft + + + 2021-12-10 +10:00:00 + + + Qt::AlignCenter + + + + + + 230 + 35 + 941 + 40 + + + + + 1 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + 230 + 65 + 941 + 30 + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/PhaseWindow.h b/PhaseWindow.h new file mode 100644 index 0000000..02a7908 --- /dev/null +++ b/PhaseWindow.h @@ -0,0 +1,47 @@ +#ifndef PHASEWINDOW_H +#define PHASEWINDOW_H + +#include +#include +#include +#include + +#include "PhaseDevice.h" +#include "common/utils/SettingConfig.h" +#include "common/HttpRequestController.h" + +namespace Ui { +class PhaseWindow; +} + +class PhaseWindow : public QWidget +{ + Q_OBJECT + +public: + explicit PhaseWindow(QWidget *parent = nullptr); + ~PhaseWindow(); + +public slots: + void drawPhaseDataOnPage(PhaseDataDto * phaseData); + +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + +private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + + Ui::PhaseWindow *ui; + + HttpRequestController * httpReq; + + QList deviceList; + + void generateWidgetForDevice(); +}; + +#endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui new file mode 100644 index 0000000..97edbe1 --- /dev/null +++ b/PhaseWindow.ui @@ -0,0 +1,712 @@ + + + PhaseWindow + + + + 0 + 0 + 1366 + 720 + + + + + 1366 + 0 + + + + 比相仪测量软件 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 1300 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 100 + 0 + 200 + 41 + + + + + 微软雅黑 + 14 + + + + 比相仪测量软件 + + + + + + 0 + 90 + 1371 + 16 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 1250 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + 1200 + 10 + 40 + 40 + + + + + + + 配置 + + + + + + 40 + 40 + 141 + 51 + + + + + 微软雅黑 + 14 + 75 + true + + + + Qt::RightToLeft + + + 2021-12-10 +10:00:00 + + + Qt::AlignCenter + + + + + + 230 + 35 + 941 + 40 + + + + + 1 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + 230 + 65 + 941 + 30 + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/common/ConstCache.h b/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/PhaseWindow.h b/PhaseWindow.h new file mode 100644 index 0000000..02a7908 --- /dev/null +++ b/PhaseWindow.h @@ -0,0 +1,47 @@ +#ifndef PHASEWINDOW_H +#define PHASEWINDOW_H + +#include +#include +#include +#include + +#include "PhaseDevice.h" +#include "common/utils/SettingConfig.h" +#include "common/HttpRequestController.h" + +namespace Ui { +class PhaseWindow; +} + +class PhaseWindow : public QWidget +{ + Q_OBJECT + +public: + explicit PhaseWindow(QWidget *parent = nullptr); + ~PhaseWindow(); + +public slots: + void drawPhaseDataOnPage(PhaseDataDto * phaseData); + +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + +private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + + Ui::PhaseWindow *ui; + + HttpRequestController * httpReq; + + QList deviceList; + + void generateWidgetForDevice(); +}; + +#endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui new file mode 100644 index 0000000..97edbe1 --- /dev/null +++ b/PhaseWindow.ui @@ -0,0 +1,712 @@ + + + PhaseWindow + + + + 0 + 0 + 1366 + 720 + + + + + 1366 + 0 + + + + 比相仪测量软件 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 1300 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 100 + 0 + 200 + 41 + + + + + 微软雅黑 + 14 + + + + 比相仪测量软件 + + + + + + 0 + 90 + 1371 + 16 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 1250 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + 1200 + 10 + 40 + 40 + + + + + + + 配置 + + + + + + 40 + 40 + 141 + 51 + + + + + 微软雅黑 + 14 + 75 + true + + + + Qt::RightToLeft + + + 2021-12-10 +10:00:00 + + + Qt::AlignCenter + + + + + + 230 + 35 + 941 + 40 + + + + + 1 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + 230 + 65 + 941 + 30 + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/common/ConstCache.h b/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/common/HttpRequestController.cpp b/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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++) + { + 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(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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; + + return resultObj; +} diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/PhaseWindow.h b/PhaseWindow.h new file mode 100644 index 0000000..02a7908 --- /dev/null +++ b/PhaseWindow.h @@ -0,0 +1,47 @@ +#ifndef PHASEWINDOW_H +#define PHASEWINDOW_H + +#include +#include +#include +#include + +#include "PhaseDevice.h" +#include "common/utils/SettingConfig.h" +#include "common/HttpRequestController.h" + +namespace Ui { +class PhaseWindow; +} + +class PhaseWindow : public QWidget +{ + Q_OBJECT + +public: + explicit PhaseWindow(QWidget *parent = nullptr); + ~PhaseWindow(); + +public slots: + void drawPhaseDataOnPage(PhaseDataDto * phaseData); + +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + +private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + + Ui::PhaseWindow *ui; + + HttpRequestController * httpReq; + + QList deviceList; + + void generateWidgetForDevice(); +}; + +#endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui new file mode 100644 index 0000000..97edbe1 --- /dev/null +++ b/PhaseWindow.ui @@ -0,0 +1,712 @@ + + + PhaseWindow + + + + 0 + 0 + 1366 + 720 + + + + + 1366 + 0 + + + + 比相仪测量软件 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 1300 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 100 + 0 + 200 + 41 + + + + + 微软雅黑 + 14 + + + + 比相仪测量软件 + + + + + + 0 + 90 + 1371 + 16 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 1250 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + 1200 + 10 + 40 + 40 + + + + + + + 配置 + + + + + + 40 + 40 + 141 + 51 + + + + + 微软雅黑 + 14 + 75 + true + + + + Qt::RightToLeft + + + 2021-12-10 +10:00:00 + + + Qt::AlignCenter + + + + + + 230 + 35 + 941 + 40 + + + + + 1 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + 230 + 65 + 941 + 30 + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/common/ConstCache.h b/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/common/HttpRequestController.cpp b/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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++) + { + 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(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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; + + return resultObj; +} diff --git a/common/HttpRequestController.h b/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/PhaseWindow.h b/PhaseWindow.h new file mode 100644 index 0000000..02a7908 --- /dev/null +++ b/PhaseWindow.h @@ -0,0 +1,47 @@ +#ifndef PHASEWINDOW_H +#define PHASEWINDOW_H + +#include +#include +#include +#include + +#include "PhaseDevice.h" +#include "common/utils/SettingConfig.h" +#include "common/HttpRequestController.h" + +namespace Ui { +class PhaseWindow; +} + +class PhaseWindow : public QWidget +{ + Q_OBJECT + +public: + explicit PhaseWindow(QWidget *parent = nullptr); + ~PhaseWindow(); + +public slots: + void drawPhaseDataOnPage(PhaseDataDto * phaseData); + +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + +private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + + Ui::PhaseWindow *ui; + + HttpRequestController * httpReq; + + QList deviceList; + + void generateWidgetForDevice(); +}; + +#endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui new file mode 100644 index 0000000..97edbe1 --- /dev/null +++ b/PhaseWindow.ui @@ -0,0 +1,712 @@ + + + PhaseWindow + + + + 0 + 0 + 1366 + 720 + + + + + 1366 + 0 + + + + 比相仪测量软件 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 1300 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 100 + 0 + 200 + 41 + + + + + 微软雅黑 + 14 + + + + 比相仪测量软件 + + + + + + 0 + 90 + 1371 + 16 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 1250 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + 1200 + 10 + 40 + 40 + + + + + + + 配置 + + + + + + 40 + 40 + 141 + 51 + + + + + 微软雅黑 + 14 + 75 + true + + + + Qt::RightToLeft + + + 2021-12-10 +10:00:00 + + + Qt::AlignCenter + + + + + + 230 + 35 + 941 + 40 + + + + + 1 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + 230 + 65 + 941 + 30 + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/common/ConstCache.h b/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/common/HttpRequestController.cpp b/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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++) + { + 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(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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; + + return resultObj; +} diff --git a/common/HttpRequestController.h b/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/common/common.pri b/common/common.pri new file mode 100644 index 0000000..84f57ae --- /dev/null +++ b/common/common.pri @@ -0,0 +1,20 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/PhaseWindow.h b/PhaseWindow.h new file mode 100644 index 0000000..02a7908 --- /dev/null +++ b/PhaseWindow.h @@ -0,0 +1,47 @@ +#ifndef PHASEWINDOW_H +#define PHASEWINDOW_H + +#include +#include +#include +#include + +#include "PhaseDevice.h" +#include "common/utils/SettingConfig.h" +#include "common/HttpRequestController.h" + +namespace Ui { +class PhaseWindow; +} + +class PhaseWindow : public QWidget +{ + Q_OBJECT + +public: + explicit PhaseWindow(QWidget *parent = nullptr); + ~PhaseWindow(); + +public slots: + void drawPhaseDataOnPage(PhaseDataDto * phaseData); + +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + +private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + + Ui::PhaseWindow *ui; + + HttpRequestController * httpReq; + + QList deviceList; + + void generateWidgetForDevice(); +}; + +#endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui new file mode 100644 index 0000000..97edbe1 --- /dev/null +++ b/PhaseWindow.ui @@ -0,0 +1,712 @@ + + + PhaseWindow + + + + 0 + 0 + 1366 + 720 + + + + + 1366 + 0 + + + + 比相仪测量软件 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 1300 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 100 + 0 + 200 + 41 + + + + + 微软雅黑 + 14 + + + + 比相仪测量软件 + + + + + + 0 + 90 + 1371 + 16 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 1250 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + 1200 + 10 + 40 + 40 + + + + + + + 配置 + + + + + + 40 + 40 + 141 + 51 + + + + + 微软雅黑 + 14 + 75 + true + + + + Qt::RightToLeft + + + 2021-12-10 +10:00:00 + + + Qt::AlignCenter + + + + + + 230 + 35 + 941 + 40 + + + + + 1 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + 230 + 65 + 941 + 30 + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/common/ConstCache.h b/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/common/HttpRequestController.cpp b/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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++) + { + 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(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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; + + return resultObj; +} diff --git a/common/HttpRequestController.h b/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/common/common.pri b/common/common.pri new file mode 100644 index 0000000..84f57ae --- /dev/null +++ b/common/common.pri @@ -0,0 +1,20 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/common/utils/DefHead.h b/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/PhaseWindow.h b/PhaseWindow.h new file mode 100644 index 0000000..02a7908 --- /dev/null +++ b/PhaseWindow.h @@ -0,0 +1,47 @@ +#ifndef PHASEWINDOW_H +#define PHASEWINDOW_H + +#include +#include +#include +#include + +#include "PhaseDevice.h" +#include "common/utils/SettingConfig.h" +#include "common/HttpRequestController.h" + +namespace Ui { +class PhaseWindow; +} + +class PhaseWindow : public QWidget +{ + Q_OBJECT + +public: + explicit PhaseWindow(QWidget *parent = nullptr); + ~PhaseWindow(); + +public slots: + void drawPhaseDataOnPage(PhaseDataDto * phaseData); + +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + +private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + + Ui::PhaseWindow *ui; + + HttpRequestController * httpReq; + + QList deviceList; + + void generateWidgetForDevice(); +}; + +#endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui new file mode 100644 index 0000000..97edbe1 --- /dev/null +++ b/PhaseWindow.ui @@ -0,0 +1,712 @@ + + + PhaseWindow + + + + 0 + 0 + 1366 + 720 + + + + + 1366 + 0 + + + + 比相仪测量软件 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 1300 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 100 + 0 + 200 + 41 + + + + + 微软雅黑 + 14 + + + + 比相仪测量软件 + + + + + + 0 + 90 + 1371 + 16 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 1250 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + 1200 + 10 + 40 + 40 + + + + + + + 配置 + + + + + + 40 + 40 + 141 + 51 + + + + + 微软雅黑 + 14 + 75 + true + + + + Qt::RightToLeft + + + 2021-12-10 +10:00:00 + + + Qt::AlignCenter + + + + + + 230 + 35 + 941 + 40 + + + + + 1 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + 230 + 65 + 941 + 30 + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/common/ConstCache.h b/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/common/HttpRequestController.cpp b/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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++) + { + 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(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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; + + return resultObj; +} diff --git a/common/HttpRequestController.h b/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/common/common.pri b/common/common.pri new file mode 100644 index 0000000..84f57ae --- /dev/null +++ b/common/common.pri @@ -0,0 +1,20 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/common/utils/DefHead.h b/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/common/utils/HttpRequestUtil.cpp b/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/PhaseWindow.h b/PhaseWindow.h new file mode 100644 index 0000000..02a7908 --- /dev/null +++ b/PhaseWindow.h @@ -0,0 +1,47 @@ +#ifndef PHASEWINDOW_H +#define PHASEWINDOW_H + +#include +#include +#include +#include + +#include "PhaseDevice.h" +#include "common/utils/SettingConfig.h" +#include "common/HttpRequestController.h" + +namespace Ui { +class PhaseWindow; +} + +class PhaseWindow : public QWidget +{ + Q_OBJECT + +public: + explicit PhaseWindow(QWidget *parent = nullptr); + ~PhaseWindow(); + +public slots: + void drawPhaseDataOnPage(PhaseDataDto * phaseData); + +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + +private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + + Ui::PhaseWindow *ui; + + HttpRequestController * httpReq; + + QList deviceList; + + void generateWidgetForDevice(); +}; + +#endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui new file mode 100644 index 0000000..97edbe1 --- /dev/null +++ b/PhaseWindow.ui @@ -0,0 +1,712 @@ + + + PhaseWindow + + + + 0 + 0 + 1366 + 720 + + + + + 1366 + 0 + + + + 比相仪测量软件 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 1300 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 100 + 0 + 200 + 41 + + + + + 微软雅黑 + 14 + + + + 比相仪测量软件 + + + + + + 0 + 90 + 1371 + 16 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 1250 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + 1200 + 10 + 40 + 40 + + + + + + + 配置 + + + + + + 40 + 40 + 141 + 51 + + + + + 微软雅黑 + 14 + 75 + true + + + + Qt::RightToLeft + + + 2021-12-10 +10:00:00 + + + Qt::AlignCenter + + + + + + 230 + 35 + 941 + 40 + + + + + 1 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + 230 + 65 + 941 + 30 + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/common/ConstCache.h b/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/common/HttpRequestController.cpp b/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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++) + { + 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(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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; + + return resultObj; +} diff --git a/common/HttpRequestController.h b/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/common/common.pri b/common/common.pri new file mode 100644 index 0000000..84f57ae --- /dev/null +++ b/common/common.pri @@ -0,0 +1,20 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/common/utils/DefHead.h b/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/common/utils/HttpRequestUtil.cpp b/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/common/utils/HttpRequestUtil.h b/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/PhaseWindow.h b/PhaseWindow.h new file mode 100644 index 0000000..02a7908 --- /dev/null +++ b/PhaseWindow.h @@ -0,0 +1,47 @@ +#ifndef PHASEWINDOW_H +#define PHASEWINDOW_H + +#include +#include +#include +#include + +#include "PhaseDevice.h" +#include "common/utils/SettingConfig.h" +#include "common/HttpRequestController.h" + +namespace Ui { +class PhaseWindow; +} + +class PhaseWindow : public QWidget +{ + Q_OBJECT + +public: + explicit PhaseWindow(QWidget *parent = nullptr); + ~PhaseWindow(); + +public slots: + void drawPhaseDataOnPage(PhaseDataDto * phaseData); + +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + +private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + + Ui::PhaseWindow *ui; + + HttpRequestController * httpReq; + + QList deviceList; + + void generateWidgetForDevice(); +}; + +#endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui new file mode 100644 index 0000000..97edbe1 --- /dev/null +++ b/PhaseWindow.ui @@ -0,0 +1,712 @@ + + + PhaseWindow + + + + 0 + 0 + 1366 + 720 + + + + + 1366 + 0 + + + + 比相仪测量软件 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 1300 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 100 + 0 + 200 + 41 + + + + + 微软雅黑 + 14 + + + + 比相仪测量软件 + + + + + + 0 + 90 + 1371 + 16 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 1250 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + 1200 + 10 + 40 + 40 + + + + + + + 配置 + + + + + + 40 + 40 + 141 + 51 + + + + + 微软雅黑 + 14 + 75 + true + + + + Qt::RightToLeft + + + 2021-12-10 +10:00:00 + + + Qt::AlignCenter + + + + + + 230 + 35 + 941 + 40 + + + + + 1 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + 230 + 65 + 941 + 30 + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/common/ConstCache.h b/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/common/HttpRequestController.cpp b/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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++) + { + 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(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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; + + return resultObj; +} diff --git a/common/HttpRequestController.h b/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/common/common.pri b/common/common.pri new file mode 100644 index 0000000..84f57ae --- /dev/null +++ b/common/common.pri @@ -0,0 +1,20 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/common/utils/DefHead.h b/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/common/utils/HttpRequestUtil.cpp b/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/common/utils/HttpRequestUtil.h b/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/common/utils/MD5.cpp b/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/PhaseWindow.h b/PhaseWindow.h new file mode 100644 index 0000000..02a7908 --- /dev/null +++ b/PhaseWindow.h @@ -0,0 +1,47 @@ +#ifndef PHASEWINDOW_H +#define PHASEWINDOW_H + +#include +#include +#include +#include + +#include "PhaseDevice.h" +#include "common/utils/SettingConfig.h" +#include "common/HttpRequestController.h" + +namespace Ui { +class PhaseWindow; +} + +class PhaseWindow : public QWidget +{ + Q_OBJECT + +public: + explicit PhaseWindow(QWidget *parent = nullptr); + ~PhaseWindow(); + +public slots: + void drawPhaseDataOnPage(PhaseDataDto * phaseData); + +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + +private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + + Ui::PhaseWindow *ui; + + HttpRequestController * httpReq; + + QList deviceList; + + void generateWidgetForDevice(); +}; + +#endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui new file mode 100644 index 0000000..97edbe1 --- /dev/null +++ b/PhaseWindow.ui @@ -0,0 +1,712 @@ + + + PhaseWindow + + + + 0 + 0 + 1366 + 720 + + + + + 1366 + 0 + + + + 比相仪测量软件 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 1300 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 100 + 0 + 200 + 41 + + + + + 微软雅黑 + 14 + + + + 比相仪测量软件 + + + + + + 0 + 90 + 1371 + 16 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 1250 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + 1200 + 10 + 40 + 40 + + + + + + + 配置 + + + + + + 40 + 40 + 141 + 51 + + + + + 微软雅黑 + 14 + 75 + true + + + + Qt::RightToLeft + + + 2021-12-10 +10:00:00 + + + Qt::AlignCenter + + + + + + 230 + 35 + 941 + 40 + + + + + 1 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + 230 + 65 + 941 + 30 + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/common/ConstCache.h b/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/common/HttpRequestController.cpp b/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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++) + { + 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(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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; + + return resultObj; +} diff --git a/common/HttpRequestController.h b/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/common/common.pri b/common/common.pri new file mode 100644 index 0000000..84f57ae --- /dev/null +++ b/common/common.pri @@ -0,0 +1,20 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/common/utils/DefHead.h b/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/common/utils/HttpRequestUtil.cpp b/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/common/utils/HttpRequestUtil.h b/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/common/utils/MD5.cpp b/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/common/utils/MD5.h b/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/PhaseWindow.h b/PhaseWindow.h new file mode 100644 index 0000000..02a7908 --- /dev/null +++ b/PhaseWindow.h @@ -0,0 +1,47 @@ +#ifndef PHASEWINDOW_H +#define PHASEWINDOW_H + +#include +#include +#include +#include + +#include "PhaseDevice.h" +#include "common/utils/SettingConfig.h" +#include "common/HttpRequestController.h" + +namespace Ui { +class PhaseWindow; +} + +class PhaseWindow : public QWidget +{ + Q_OBJECT + +public: + explicit PhaseWindow(QWidget *parent = nullptr); + ~PhaseWindow(); + +public slots: + void drawPhaseDataOnPage(PhaseDataDto * phaseData); + +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + +private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + + Ui::PhaseWindow *ui; + + HttpRequestController * httpReq; + + QList deviceList; + + void generateWidgetForDevice(); +}; + +#endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui new file mode 100644 index 0000000..97edbe1 --- /dev/null +++ b/PhaseWindow.ui @@ -0,0 +1,712 @@ + + + PhaseWindow + + + + 0 + 0 + 1366 + 720 + + + + + 1366 + 0 + + + + 比相仪测量软件 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 1300 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 100 + 0 + 200 + 41 + + + + + 微软雅黑 + 14 + + + + 比相仪测量软件 + + + + + + 0 + 90 + 1371 + 16 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 1250 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + 1200 + 10 + 40 + 40 + + + + + + + 配置 + + + + + + 40 + 40 + 141 + 51 + + + + + 微软雅黑 + 14 + 75 + true + + + + Qt::RightToLeft + + + 2021-12-10 +10:00:00 + + + Qt::AlignCenter + + + + + + 230 + 35 + 941 + 40 + + + + + 1 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + 230 + 65 + 941 + 30 + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/common/ConstCache.h b/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/common/HttpRequestController.cpp b/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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++) + { + 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(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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; + + return resultObj; +} diff --git a/common/HttpRequestController.h b/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/common/common.pri b/common/common.pri new file mode 100644 index 0000000..84f57ae --- /dev/null +++ b/common/common.pri @@ -0,0 +1,20 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/common/utils/DefHead.h b/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/common/utils/HttpRequestUtil.cpp b/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/common/utils/HttpRequestUtil.h b/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/common/utils/MD5.cpp b/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/common/utils/MD5.h b/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/common/utils/QByteUtil.cpp b/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/PhaseWindow.h b/PhaseWindow.h new file mode 100644 index 0000000..02a7908 --- /dev/null +++ b/PhaseWindow.h @@ -0,0 +1,47 @@ +#ifndef PHASEWINDOW_H +#define PHASEWINDOW_H + +#include +#include +#include +#include + +#include "PhaseDevice.h" +#include "common/utils/SettingConfig.h" +#include "common/HttpRequestController.h" + +namespace Ui { +class PhaseWindow; +} + +class PhaseWindow : public QWidget +{ + Q_OBJECT + +public: + explicit PhaseWindow(QWidget *parent = nullptr); + ~PhaseWindow(); + +public slots: + void drawPhaseDataOnPage(PhaseDataDto * phaseData); + +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + +private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + + Ui::PhaseWindow *ui; + + HttpRequestController * httpReq; + + QList deviceList; + + void generateWidgetForDevice(); +}; + +#endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui new file mode 100644 index 0000000..97edbe1 --- /dev/null +++ b/PhaseWindow.ui @@ -0,0 +1,712 @@ + + + PhaseWindow + + + + 0 + 0 + 1366 + 720 + + + + + 1366 + 0 + + + + 比相仪测量软件 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 1300 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 100 + 0 + 200 + 41 + + + + + 微软雅黑 + 14 + + + + 比相仪测量软件 + + + + + + 0 + 90 + 1371 + 16 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 1250 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + 1200 + 10 + 40 + 40 + + + + + + + 配置 + + + + + + 40 + 40 + 141 + 51 + + + + + 微软雅黑 + 14 + 75 + true + + + + Qt::RightToLeft + + + 2021-12-10 +10:00:00 + + + Qt::AlignCenter + + + + + + 230 + 35 + 941 + 40 + + + + + 1 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + 230 + 65 + 941 + 30 + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/common/ConstCache.h b/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/common/HttpRequestController.cpp b/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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++) + { + 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(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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; + + return resultObj; +} diff --git a/common/HttpRequestController.h b/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/common/common.pri b/common/common.pri new file mode 100644 index 0000000..84f57ae --- /dev/null +++ b/common/common.pri @@ -0,0 +1,20 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/common/utils/DefHead.h b/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/common/utils/HttpRequestUtil.cpp b/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/common/utils/HttpRequestUtil.h b/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/common/utils/MD5.cpp b/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/common/utils/MD5.h b/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/common/utils/QByteUtil.cpp b/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/common/utils/QByteUtil.h b/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/PhaseWindow.h b/PhaseWindow.h new file mode 100644 index 0000000..02a7908 --- /dev/null +++ b/PhaseWindow.h @@ -0,0 +1,47 @@ +#ifndef PHASEWINDOW_H +#define PHASEWINDOW_H + +#include +#include +#include +#include + +#include "PhaseDevice.h" +#include "common/utils/SettingConfig.h" +#include "common/HttpRequestController.h" + +namespace Ui { +class PhaseWindow; +} + +class PhaseWindow : public QWidget +{ + Q_OBJECT + +public: + explicit PhaseWindow(QWidget *parent = nullptr); + ~PhaseWindow(); + +public slots: + void drawPhaseDataOnPage(PhaseDataDto * phaseData); + +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + +private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + + Ui::PhaseWindow *ui; + + HttpRequestController * httpReq; + + QList deviceList; + + void generateWidgetForDevice(); +}; + +#endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui new file mode 100644 index 0000000..97edbe1 --- /dev/null +++ b/PhaseWindow.ui @@ -0,0 +1,712 @@ + + + PhaseWindow + + + + 0 + 0 + 1366 + 720 + + + + + 1366 + 0 + + + + 比相仪测量软件 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 1300 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 100 + 0 + 200 + 41 + + + + + 微软雅黑 + 14 + + + + 比相仪测量软件 + + + + + + 0 + 90 + 1371 + 16 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 1250 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + 1200 + 10 + 40 + 40 + + + + + + + 配置 + + + + + + 40 + 40 + 141 + 51 + + + + + 微软雅黑 + 14 + 75 + true + + + + Qt::RightToLeft + + + 2021-12-10 +10:00:00 + + + Qt::AlignCenter + + + + + + 230 + 35 + 941 + 40 + + + + + 1 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + 230 + 65 + 941 + 30 + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/common/ConstCache.h b/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/common/HttpRequestController.cpp b/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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++) + { + 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(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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; + + return resultObj; +} diff --git a/common/HttpRequestController.h b/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/common/common.pri b/common/common.pri new file mode 100644 index 0000000..84f57ae --- /dev/null +++ b/common/common.pri @@ -0,0 +1,20 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/common/utils/DefHead.h b/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/common/utils/HttpRequestUtil.cpp b/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/common/utils/HttpRequestUtil.h b/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/common/utils/MD5.cpp b/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/common/utils/MD5.h b/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/common/utils/QByteUtil.cpp b/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/common/utils/QByteUtil.h b/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/common/utils/QKafkaUtil.cpp b/common/utils/QKafkaUtil.cpp new file mode 100644 index 0000000..0cd1639 --- /dev/null +++ b/common/utils/QKafkaUtil.cpp @@ -0,0 +1,68 @@ +#include "QKafkaUtil.h" +#include "SettingConfig.h" +#include + +QKafkaUtil::QKafkaUtil(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaUtil::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaUtil::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaUtil::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + if (SettingConfig::getInstance().NEED_SASL == 1) + { + conf->set("sasl.username", SettingConfig::getInstance().SASL_USERNAME.toStdString(), errStr); + conf->set("sasl.password", SettingConfig::getInstance().SASL_PASSWORD.toStdString(), errStr); + conf->set("security.protocol", "sasl_plaintext", errStr); + conf->set("sasl.mechanisms", "PLAIN", errStr); + } + + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaUtil::produceMessage(QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/PhaseWindow.h b/PhaseWindow.h new file mode 100644 index 0000000..02a7908 --- /dev/null +++ b/PhaseWindow.h @@ -0,0 +1,47 @@ +#ifndef PHASEWINDOW_H +#define PHASEWINDOW_H + +#include +#include +#include +#include + +#include "PhaseDevice.h" +#include "common/utils/SettingConfig.h" +#include "common/HttpRequestController.h" + +namespace Ui { +class PhaseWindow; +} + +class PhaseWindow : public QWidget +{ + Q_OBJECT + +public: + explicit PhaseWindow(QWidget *parent = nullptr); + ~PhaseWindow(); + +public slots: + void drawPhaseDataOnPage(PhaseDataDto * phaseData); + +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + +private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + + Ui::PhaseWindow *ui; + + HttpRequestController * httpReq; + + QList deviceList; + + void generateWidgetForDevice(); +}; + +#endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui new file mode 100644 index 0000000..97edbe1 --- /dev/null +++ b/PhaseWindow.ui @@ -0,0 +1,712 @@ + + + PhaseWindow + + + + 0 + 0 + 1366 + 720 + + + + + 1366 + 0 + + + + 比相仪测量软件 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 1300 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 100 + 0 + 200 + 41 + + + + + 微软雅黑 + 14 + + + + 比相仪测量软件 + + + + + + 0 + 90 + 1371 + 16 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 1250 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + 1200 + 10 + 40 + 40 + + + + + + + 配置 + + + + + + 40 + 40 + 141 + 51 + + + + + 微软雅黑 + 14 + 75 + true + + + + Qt::RightToLeft + + + 2021-12-10 +10:00:00 + + + Qt::AlignCenter + + + + + + 230 + 35 + 941 + 40 + + + + + 1 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + 230 + 65 + 941 + 30 + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/common/ConstCache.h b/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/common/HttpRequestController.cpp b/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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++) + { + 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(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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; + + return resultObj; +} diff --git a/common/HttpRequestController.h b/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/common/common.pri b/common/common.pri new file mode 100644 index 0000000..84f57ae --- /dev/null +++ b/common/common.pri @@ -0,0 +1,20 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/common/utils/DefHead.h b/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/common/utils/HttpRequestUtil.cpp b/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/common/utils/HttpRequestUtil.h b/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/common/utils/MD5.cpp b/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/common/utils/MD5.h b/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/common/utils/QByteUtil.cpp b/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/common/utils/QByteUtil.h b/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/common/utils/QKafkaUtil.cpp b/common/utils/QKafkaUtil.cpp new file mode 100644 index 0000000..0cd1639 --- /dev/null +++ b/common/utils/QKafkaUtil.cpp @@ -0,0 +1,68 @@ +#include "QKafkaUtil.h" +#include "SettingConfig.h" +#include + +QKafkaUtil::QKafkaUtil(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaUtil::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaUtil::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaUtil::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + if (SettingConfig::getInstance().NEED_SASL == 1) + { + conf->set("sasl.username", SettingConfig::getInstance().SASL_USERNAME.toStdString(), errStr); + conf->set("sasl.password", SettingConfig::getInstance().SASL_PASSWORD.toStdString(), errStr); + conf->set("security.protocol", "sasl_plaintext", errStr); + conf->set("sasl.mechanisms", "PLAIN", errStr); + } + + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaUtil::produceMessage(QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/common/utils/QKafkaUtil.h b/common/utils/QKafkaUtil.h new file mode 100644 index 0000000..289ea6f --- /dev/null +++ b/common/utils/QKafkaUtil.h @@ -0,0 +1,33 @@ +#ifndef QKAFKAUTIL_H +#define QKAFKAUTIL_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaUtil : public QObject +{ + Q_OBJECT +public: + explicit QKafkaUtil(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAUTIL_H diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/PhaseWindow.h b/PhaseWindow.h new file mode 100644 index 0000000..02a7908 --- /dev/null +++ b/PhaseWindow.h @@ -0,0 +1,47 @@ +#ifndef PHASEWINDOW_H +#define PHASEWINDOW_H + +#include +#include +#include +#include + +#include "PhaseDevice.h" +#include "common/utils/SettingConfig.h" +#include "common/HttpRequestController.h" + +namespace Ui { +class PhaseWindow; +} + +class PhaseWindow : public QWidget +{ + Q_OBJECT + +public: + explicit PhaseWindow(QWidget *parent = nullptr); + ~PhaseWindow(); + +public slots: + void drawPhaseDataOnPage(PhaseDataDto * phaseData); + +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + +private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + + Ui::PhaseWindow *ui; + + HttpRequestController * httpReq; + + QList deviceList; + + void generateWidgetForDevice(); +}; + +#endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui new file mode 100644 index 0000000..97edbe1 --- /dev/null +++ b/PhaseWindow.ui @@ -0,0 +1,712 @@ + + + PhaseWindow + + + + 0 + 0 + 1366 + 720 + + + + + 1366 + 0 + + + + 比相仪测量软件 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 1300 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 100 + 0 + 200 + 41 + + + + + 微软雅黑 + 14 + + + + 比相仪测量软件 + + + + + + 0 + 90 + 1371 + 16 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 1250 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + 1200 + 10 + 40 + 40 + + + + + + + 配置 + + + + + + 40 + 40 + 141 + 51 + + + + + 微软雅黑 + 14 + 75 + true + + + + Qt::RightToLeft + + + 2021-12-10 +10:00:00 + + + Qt::AlignCenter + + + + + + 230 + 35 + 941 + 40 + + + + + 1 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + 230 + 65 + 941 + 30 + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/common/ConstCache.h b/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/common/HttpRequestController.cpp b/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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++) + { + 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(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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; + + return resultObj; +} diff --git a/common/HttpRequestController.h b/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/common/common.pri b/common/common.pri new file mode 100644 index 0000000..84f57ae --- /dev/null +++ b/common/common.pri @@ -0,0 +1,20 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/common/utils/DefHead.h b/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/common/utils/HttpRequestUtil.cpp b/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/common/utils/HttpRequestUtil.h b/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/common/utils/MD5.cpp b/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/common/utils/MD5.h b/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/common/utils/QByteUtil.cpp b/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/common/utils/QByteUtil.h b/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/common/utils/QKafkaUtil.cpp b/common/utils/QKafkaUtil.cpp new file mode 100644 index 0000000..0cd1639 --- /dev/null +++ b/common/utils/QKafkaUtil.cpp @@ -0,0 +1,68 @@ +#include "QKafkaUtil.h" +#include "SettingConfig.h" +#include + +QKafkaUtil::QKafkaUtil(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaUtil::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaUtil::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaUtil::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + if (SettingConfig::getInstance().NEED_SASL == 1) + { + conf->set("sasl.username", SettingConfig::getInstance().SASL_USERNAME.toStdString(), errStr); + conf->set("sasl.password", SettingConfig::getInstance().SASL_PASSWORD.toStdString(), errStr); + conf->set("security.protocol", "sasl_plaintext", errStr); + conf->set("sasl.mechanisms", "PLAIN", errStr); + } + + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaUtil::produceMessage(QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/common/utils/QKafkaUtil.h b/common/utils/QKafkaUtil.h new file mode 100644 index 0000000..289ea6f --- /dev/null +++ b/common/utils/QKafkaUtil.h @@ -0,0 +1,33 @@ +#ifndef QKAFKAUTIL_H +#define QKAFKAUTIL_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaUtil : public QObject +{ + Q_OBJECT +public: + explicit QKafkaUtil(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAUTIL_H diff --git a/common/utils/QLogUtil.cpp b/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +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/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/PhaseWindow.h b/PhaseWindow.h new file mode 100644 index 0000000..02a7908 --- /dev/null +++ b/PhaseWindow.h @@ -0,0 +1,47 @@ +#ifndef PHASEWINDOW_H +#define PHASEWINDOW_H + +#include +#include +#include +#include + +#include "PhaseDevice.h" +#include "common/utils/SettingConfig.h" +#include "common/HttpRequestController.h" + +namespace Ui { +class PhaseWindow; +} + +class PhaseWindow : public QWidget +{ + Q_OBJECT + +public: + explicit PhaseWindow(QWidget *parent = nullptr); + ~PhaseWindow(); + +public slots: + void drawPhaseDataOnPage(PhaseDataDto * phaseData); + +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + +private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + + Ui::PhaseWindow *ui; + + HttpRequestController * httpReq; + + QList deviceList; + + void generateWidgetForDevice(); +}; + +#endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui new file mode 100644 index 0000000..97edbe1 --- /dev/null +++ b/PhaseWindow.ui @@ -0,0 +1,712 @@ + + + PhaseWindow + + + + 0 + 0 + 1366 + 720 + + + + + 1366 + 0 + + + + 比相仪测量软件 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 1300 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 100 + 0 + 200 + 41 + + + + + 微软雅黑 + 14 + + + + 比相仪测量软件 + + + + + + 0 + 90 + 1371 + 16 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 1250 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + 1200 + 10 + 40 + 40 + + + + + + + 配置 + + + + + + 40 + 40 + 141 + 51 + + + + + 微软雅黑 + 14 + 75 + true + + + + Qt::RightToLeft + + + 2021-12-10 +10:00:00 + + + Qt::AlignCenter + + + + + + 230 + 35 + 941 + 40 + + + + + 1 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + 230 + 65 + 941 + 30 + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/common/ConstCache.h b/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/common/HttpRequestController.cpp b/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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++) + { + 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(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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; + + return resultObj; +} diff --git a/common/HttpRequestController.h b/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/common/common.pri b/common/common.pri new file mode 100644 index 0000000..84f57ae --- /dev/null +++ b/common/common.pri @@ -0,0 +1,20 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/common/utils/DefHead.h b/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/common/utils/HttpRequestUtil.cpp b/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/common/utils/HttpRequestUtil.h b/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/common/utils/MD5.cpp b/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/common/utils/MD5.h b/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/common/utils/QByteUtil.cpp b/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/common/utils/QByteUtil.h b/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/common/utils/QKafkaUtil.cpp b/common/utils/QKafkaUtil.cpp new file mode 100644 index 0000000..0cd1639 --- /dev/null +++ b/common/utils/QKafkaUtil.cpp @@ -0,0 +1,68 @@ +#include "QKafkaUtil.h" +#include "SettingConfig.h" +#include + +QKafkaUtil::QKafkaUtil(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaUtil::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaUtil::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaUtil::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + if (SettingConfig::getInstance().NEED_SASL == 1) + { + conf->set("sasl.username", SettingConfig::getInstance().SASL_USERNAME.toStdString(), errStr); + conf->set("sasl.password", SettingConfig::getInstance().SASL_PASSWORD.toStdString(), errStr); + conf->set("security.protocol", "sasl_plaintext", errStr); + conf->set("sasl.mechanisms", "PLAIN", errStr); + } + + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaUtil::produceMessage(QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/common/utils/QKafkaUtil.h b/common/utils/QKafkaUtil.h new file mode 100644 index 0000000..289ea6f --- /dev/null +++ b/common/utils/QKafkaUtil.h @@ -0,0 +1,33 @@ +#ifndef QKAFKAUTIL_H +#define QKAFKAUTIL_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaUtil : public QObject +{ + Q_OBJECT +public: + explicit QKafkaUtil(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAUTIL_H diff --git a/common/utils/QLogUtil.cpp b/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +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/common/utils/QLogUtil.h b/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + 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: + +}; + +#endif // QLOGUTIL_H diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/PhaseWindow.h b/PhaseWindow.h new file mode 100644 index 0000000..02a7908 --- /dev/null +++ b/PhaseWindow.h @@ -0,0 +1,47 @@ +#ifndef PHASEWINDOW_H +#define PHASEWINDOW_H + +#include +#include +#include +#include + +#include "PhaseDevice.h" +#include "common/utils/SettingConfig.h" +#include "common/HttpRequestController.h" + +namespace Ui { +class PhaseWindow; +} + +class PhaseWindow : public QWidget +{ + Q_OBJECT + +public: + explicit PhaseWindow(QWidget *parent = nullptr); + ~PhaseWindow(); + +public slots: + void drawPhaseDataOnPage(PhaseDataDto * phaseData); + +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + +private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + + Ui::PhaseWindow *ui; + + HttpRequestController * httpReq; + + QList deviceList; + + void generateWidgetForDevice(); +}; + +#endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui new file mode 100644 index 0000000..97edbe1 --- /dev/null +++ b/PhaseWindow.ui @@ -0,0 +1,712 @@ + + + PhaseWindow + + + + 0 + 0 + 1366 + 720 + + + + + 1366 + 0 + + + + 比相仪测量软件 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 1300 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 100 + 0 + 200 + 41 + + + + + 微软雅黑 + 14 + + + + 比相仪测量软件 + + + + + + 0 + 90 + 1371 + 16 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 1250 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + 1200 + 10 + 40 + 40 + + + + + + + 配置 + + + + + + 40 + 40 + 141 + 51 + + + + + 微软雅黑 + 14 + 75 + true + + + + Qt::RightToLeft + + + 2021-12-10 +10:00:00 + + + Qt::AlignCenter + + + + + + 230 + 35 + 941 + 40 + + + + + 1 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + 230 + 65 + 941 + 30 + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/common/ConstCache.h b/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/common/HttpRequestController.cpp b/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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++) + { + 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(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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; + + return resultObj; +} diff --git a/common/HttpRequestController.h b/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/common/common.pri b/common/common.pri new file mode 100644 index 0000000..84f57ae --- /dev/null +++ b/common/common.pri @@ -0,0 +1,20 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/common/utils/DefHead.h b/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/common/utils/HttpRequestUtil.cpp b/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/common/utils/HttpRequestUtil.h b/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/common/utils/MD5.cpp b/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/common/utils/MD5.h b/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/common/utils/QByteUtil.cpp b/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/common/utils/QByteUtil.h b/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/common/utils/QKafkaUtil.cpp b/common/utils/QKafkaUtil.cpp new file mode 100644 index 0000000..0cd1639 --- /dev/null +++ b/common/utils/QKafkaUtil.cpp @@ -0,0 +1,68 @@ +#include "QKafkaUtil.h" +#include "SettingConfig.h" +#include + +QKafkaUtil::QKafkaUtil(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaUtil::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaUtil::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaUtil::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + if (SettingConfig::getInstance().NEED_SASL == 1) + { + conf->set("sasl.username", SettingConfig::getInstance().SASL_USERNAME.toStdString(), errStr); + conf->set("sasl.password", SettingConfig::getInstance().SASL_PASSWORD.toStdString(), errStr); + conf->set("security.protocol", "sasl_plaintext", errStr); + conf->set("sasl.mechanisms", "PLAIN", errStr); + } + + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaUtil::produceMessage(QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/common/utils/QKafkaUtil.h b/common/utils/QKafkaUtil.h new file mode 100644 index 0000000..289ea6f --- /dev/null +++ b/common/utils/QKafkaUtil.h @@ -0,0 +1,33 @@ +#ifndef QKAFKAUTIL_H +#define QKAFKAUTIL_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaUtil : public QObject +{ + Q_OBJECT +public: + explicit QKafkaUtil(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAUTIL_H diff --git a/common/utils/QLogUtil.cpp b/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +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/common/utils/QLogUtil.h b/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + 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: + +}; + +#endif // QLOGUTIL_H diff --git a/common/utils/QSerialPortUtil.cpp b/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..64da0f7 --- /dev/null +++ b/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,77 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + + if (open == true) + { + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); + + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000); + } +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + if (this->open == true) + { + std::cout << data.toStdString() << std::endl; + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData() +{ + QDateTime now = QDateTime::currentDateTime(); + + QString frameId = now.toString("HHmmsszzz"); + + QByteArray buffer; + buffer.append(QByteUtil::hexStringToBytes(frameId.mid(0, 8))); + + for (int i = 1; i <= 16; i++) + { + int value = qrand() % 10000; + buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); + } + + buffer.append(QByteUtil::hexStringToBytes("EEEEEEEE")); + + emit dataRecieved(buffer); +} diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/PhaseWindow.h b/PhaseWindow.h new file mode 100644 index 0000000..02a7908 --- /dev/null +++ b/PhaseWindow.h @@ -0,0 +1,47 @@ +#ifndef PHASEWINDOW_H +#define PHASEWINDOW_H + +#include +#include +#include +#include + +#include "PhaseDevice.h" +#include "common/utils/SettingConfig.h" +#include "common/HttpRequestController.h" + +namespace Ui { +class PhaseWindow; +} + +class PhaseWindow : public QWidget +{ + Q_OBJECT + +public: + explicit PhaseWindow(QWidget *parent = nullptr); + ~PhaseWindow(); + +public slots: + void drawPhaseDataOnPage(PhaseDataDto * phaseData); + +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + +private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + + Ui::PhaseWindow *ui; + + HttpRequestController * httpReq; + + QList deviceList; + + void generateWidgetForDevice(); +}; + +#endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui new file mode 100644 index 0000000..97edbe1 --- /dev/null +++ b/PhaseWindow.ui @@ -0,0 +1,712 @@ + + + PhaseWindow + + + + 0 + 0 + 1366 + 720 + + + + + 1366 + 0 + + + + 比相仪测量软件 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 1300 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 100 + 0 + 200 + 41 + + + + + 微软雅黑 + 14 + + + + 比相仪测量软件 + + + + + + 0 + 90 + 1371 + 16 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 1250 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + 1200 + 10 + 40 + 40 + + + + + + + 配置 + + + + + + 40 + 40 + 141 + 51 + + + + + 微软雅黑 + 14 + 75 + true + + + + Qt::RightToLeft + + + 2021-12-10 +10:00:00 + + + Qt::AlignCenter + + + + + + 230 + 35 + 941 + 40 + + + + + 1 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + 230 + 65 + 941 + 30 + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/common/ConstCache.h b/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/common/HttpRequestController.cpp b/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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++) + { + 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(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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; + + return resultObj; +} diff --git a/common/HttpRequestController.h b/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/common/common.pri b/common/common.pri new file mode 100644 index 0000000..84f57ae --- /dev/null +++ b/common/common.pri @@ -0,0 +1,20 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/common/utils/DefHead.h b/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/common/utils/HttpRequestUtil.cpp b/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/common/utils/HttpRequestUtil.h b/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/common/utils/MD5.cpp b/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/common/utils/MD5.h b/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/common/utils/QByteUtil.cpp b/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/common/utils/QByteUtil.h b/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/common/utils/QKafkaUtil.cpp b/common/utils/QKafkaUtil.cpp new file mode 100644 index 0000000..0cd1639 --- /dev/null +++ b/common/utils/QKafkaUtil.cpp @@ -0,0 +1,68 @@ +#include "QKafkaUtil.h" +#include "SettingConfig.h" +#include + +QKafkaUtil::QKafkaUtil(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaUtil::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaUtil::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaUtil::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + if (SettingConfig::getInstance().NEED_SASL == 1) + { + conf->set("sasl.username", SettingConfig::getInstance().SASL_USERNAME.toStdString(), errStr); + conf->set("sasl.password", SettingConfig::getInstance().SASL_PASSWORD.toStdString(), errStr); + conf->set("security.protocol", "sasl_plaintext", errStr); + conf->set("sasl.mechanisms", "PLAIN", errStr); + } + + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaUtil::produceMessage(QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/common/utils/QKafkaUtil.h b/common/utils/QKafkaUtil.h new file mode 100644 index 0000000..289ea6f --- /dev/null +++ b/common/utils/QKafkaUtil.h @@ -0,0 +1,33 @@ +#ifndef QKAFKAUTIL_H +#define QKAFKAUTIL_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaUtil : public QObject +{ + Q_OBJECT +public: + explicit QKafkaUtil(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAUTIL_H diff --git a/common/utils/QLogUtil.cpp b/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +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/common/utils/QLogUtil.h b/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + 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: + +}; + +#endif // QLOGUTIL_H diff --git a/common/utils/QSerialPortUtil.cpp b/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..64da0f7 --- /dev/null +++ b/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,77 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + + if (open == true) + { + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); + + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000); + } +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + if (this->open == true) + { + std::cout << data.toStdString() << std::endl; + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData() +{ + QDateTime now = QDateTime::currentDateTime(); + + QString frameId = now.toString("HHmmsszzz"); + + QByteArray buffer; + buffer.append(QByteUtil::hexStringToBytes(frameId.mid(0, 8))); + + for (int i = 1; i <= 16; i++) + { + int value = qrand() % 10000; + buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); + } + + buffer.append(QByteUtil::hexStringToBytes("EEEEEEEE")); + + emit dataRecieved(buffer); +} diff --git a/common/utils/QSerialPortUtil.h b/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..accf403 --- /dev/null +++ b/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open; + + void mockReceivData(); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/PhaseWindow.h b/PhaseWindow.h new file mode 100644 index 0000000..02a7908 --- /dev/null +++ b/PhaseWindow.h @@ -0,0 +1,47 @@ +#ifndef PHASEWINDOW_H +#define PHASEWINDOW_H + +#include +#include +#include +#include + +#include "PhaseDevice.h" +#include "common/utils/SettingConfig.h" +#include "common/HttpRequestController.h" + +namespace Ui { +class PhaseWindow; +} + +class PhaseWindow : public QWidget +{ + Q_OBJECT + +public: + explicit PhaseWindow(QWidget *parent = nullptr); + ~PhaseWindow(); + +public slots: + void drawPhaseDataOnPage(PhaseDataDto * phaseData); + +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + +private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + + Ui::PhaseWindow *ui; + + HttpRequestController * httpReq; + + QList deviceList; + + void generateWidgetForDevice(); +}; + +#endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui new file mode 100644 index 0000000..97edbe1 --- /dev/null +++ b/PhaseWindow.ui @@ -0,0 +1,712 @@ + + + PhaseWindow + + + + 0 + 0 + 1366 + 720 + + + + + 1366 + 0 + + + + 比相仪测量软件 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 1300 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 100 + 0 + 200 + 41 + + + + + 微软雅黑 + 14 + + + + 比相仪测量软件 + + + + + + 0 + 90 + 1371 + 16 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 1250 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + 1200 + 10 + 40 + 40 + + + + + + + 配置 + + + + + + 40 + 40 + 141 + 51 + + + + + 微软雅黑 + 14 + 75 + true + + + + Qt::RightToLeft + + + 2021-12-10 +10:00:00 + + + Qt::AlignCenter + + + + + + 230 + 35 + 941 + 40 + + + + + 1 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + 230 + 65 + 941 + 30 + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/common/ConstCache.h b/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/common/HttpRequestController.cpp b/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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++) + { + 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(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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; + + return resultObj; +} diff --git a/common/HttpRequestController.h b/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/common/common.pri b/common/common.pri new file mode 100644 index 0000000..84f57ae --- /dev/null +++ b/common/common.pri @@ -0,0 +1,20 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/common/utils/DefHead.h b/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/common/utils/HttpRequestUtil.cpp b/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/common/utils/HttpRequestUtil.h b/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/common/utils/MD5.cpp b/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/common/utils/MD5.h b/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/common/utils/QByteUtil.cpp b/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/common/utils/QByteUtil.h b/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/common/utils/QKafkaUtil.cpp b/common/utils/QKafkaUtil.cpp new file mode 100644 index 0000000..0cd1639 --- /dev/null +++ b/common/utils/QKafkaUtil.cpp @@ -0,0 +1,68 @@ +#include "QKafkaUtil.h" +#include "SettingConfig.h" +#include + +QKafkaUtil::QKafkaUtil(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaUtil::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaUtil::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaUtil::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + if (SettingConfig::getInstance().NEED_SASL == 1) + { + conf->set("sasl.username", SettingConfig::getInstance().SASL_USERNAME.toStdString(), errStr); + conf->set("sasl.password", SettingConfig::getInstance().SASL_PASSWORD.toStdString(), errStr); + conf->set("security.protocol", "sasl_plaintext", errStr); + conf->set("sasl.mechanisms", "PLAIN", errStr); + } + + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaUtil::produceMessage(QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/common/utils/QKafkaUtil.h b/common/utils/QKafkaUtil.h new file mode 100644 index 0000000..289ea6f --- /dev/null +++ b/common/utils/QKafkaUtil.h @@ -0,0 +1,33 @@ +#ifndef QKAFKAUTIL_H +#define QKAFKAUTIL_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaUtil : public QObject +{ + Q_OBJECT +public: + explicit QKafkaUtil(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAUTIL_H diff --git a/common/utils/QLogUtil.cpp b/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +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/common/utils/QLogUtil.h b/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + 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: + +}; + +#endif // QLOGUTIL_H diff --git a/common/utils/QSerialPortUtil.cpp b/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..64da0f7 --- /dev/null +++ b/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,77 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + + if (open == true) + { + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); + + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000); + } +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + if (this->open == true) + { + std::cout << data.toStdString() << std::endl; + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData() +{ + QDateTime now = QDateTime::currentDateTime(); + + QString frameId = now.toString("HHmmsszzz"); + + QByteArray buffer; + buffer.append(QByteUtil::hexStringToBytes(frameId.mid(0, 8))); + + for (int i = 1; i <= 16; i++) + { + int value = qrand() % 10000; + buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); + } + + buffer.append(QByteUtil::hexStringToBytes("EEEEEEEE")); + + emit dataRecieved(buffer); +} diff --git a/common/utils/QSerialPortUtil.h b/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..accf403 --- /dev/null +++ b/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open; + + void mockReceivData(); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/common/utils/SettingConfig.cpp b/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..9a84a43 --- /dev/null +++ b/common/utils/SettingConfig.cpp @@ -0,0 +1,29 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + BAUD_RATE = getProperty("com", "baudRate").toInt(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + NEED_SASL = getProperty("kafka", "needSasl").toInt(); + SASL_USERNAME = getProperty("kafka", "saslUsername").toString(); + SASL_PASSWORD = getProperty("kafka", "saslPassword").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/PhaseWindow.h b/PhaseWindow.h new file mode 100644 index 0000000..02a7908 --- /dev/null +++ b/PhaseWindow.h @@ -0,0 +1,47 @@ +#ifndef PHASEWINDOW_H +#define PHASEWINDOW_H + +#include +#include +#include +#include + +#include "PhaseDevice.h" +#include "common/utils/SettingConfig.h" +#include "common/HttpRequestController.h" + +namespace Ui { +class PhaseWindow; +} + +class PhaseWindow : public QWidget +{ + Q_OBJECT + +public: + explicit PhaseWindow(QWidget *parent = nullptr); + ~PhaseWindow(); + +public slots: + void drawPhaseDataOnPage(PhaseDataDto * phaseData); + +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + +private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + + Ui::PhaseWindow *ui; + + HttpRequestController * httpReq; + + QList deviceList; + + void generateWidgetForDevice(); +}; + +#endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui new file mode 100644 index 0000000..97edbe1 --- /dev/null +++ b/PhaseWindow.ui @@ -0,0 +1,712 @@ + + + PhaseWindow + + + + 0 + 0 + 1366 + 720 + + + + + 1366 + 0 + + + + 比相仪测量软件 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 1300 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 100 + 0 + 200 + 41 + + + + + 微软雅黑 + 14 + + + + 比相仪测量软件 + + + + + + 0 + 90 + 1371 + 16 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 1250 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + 1200 + 10 + 40 + 40 + + + + + + + 配置 + + + + + + 40 + 40 + 141 + 51 + + + + + 微软雅黑 + 14 + 75 + true + + + + Qt::RightToLeft + + + 2021-12-10 +10:00:00 + + + Qt::AlignCenter + + + + + + 230 + 35 + 941 + 40 + + + + + 1 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + 230 + 65 + 941 + 30 + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/common/ConstCache.h b/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/common/HttpRequestController.cpp b/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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++) + { + 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(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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; + + return resultObj; +} diff --git a/common/HttpRequestController.h b/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/common/common.pri b/common/common.pri new file mode 100644 index 0000000..84f57ae --- /dev/null +++ b/common/common.pri @@ -0,0 +1,20 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/common/utils/DefHead.h b/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/common/utils/HttpRequestUtil.cpp b/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/common/utils/HttpRequestUtil.h b/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/common/utils/MD5.cpp b/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/common/utils/MD5.h b/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/common/utils/QByteUtil.cpp b/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/common/utils/QByteUtil.h b/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/common/utils/QKafkaUtil.cpp b/common/utils/QKafkaUtil.cpp new file mode 100644 index 0000000..0cd1639 --- /dev/null +++ b/common/utils/QKafkaUtil.cpp @@ -0,0 +1,68 @@ +#include "QKafkaUtil.h" +#include "SettingConfig.h" +#include + +QKafkaUtil::QKafkaUtil(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaUtil::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaUtil::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaUtil::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + if (SettingConfig::getInstance().NEED_SASL == 1) + { + conf->set("sasl.username", SettingConfig::getInstance().SASL_USERNAME.toStdString(), errStr); + conf->set("sasl.password", SettingConfig::getInstance().SASL_PASSWORD.toStdString(), errStr); + conf->set("security.protocol", "sasl_plaintext", errStr); + conf->set("sasl.mechanisms", "PLAIN", errStr); + } + + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaUtil::produceMessage(QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/common/utils/QKafkaUtil.h b/common/utils/QKafkaUtil.h new file mode 100644 index 0000000..289ea6f --- /dev/null +++ b/common/utils/QKafkaUtil.h @@ -0,0 +1,33 @@ +#ifndef QKAFKAUTIL_H +#define QKAFKAUTIL_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaUtil : public QObject +{ + Q_OBJECT +public: + explicit QKafkaUtil(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAUTIL_H diff --git a/common/utils/QLogUtil.cpp b/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +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/common/utils/QLogUtil.h b/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + 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: + +}; + +#endif // QLOGUTIL_H diff --git a/common/utils/QSerialPortUtil.cpp b/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..64da0f7 --- /dev/null +++ b/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,77 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + + if (open == true) + { + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); + + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000); + } +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + if (this->open == true) + { + std::cout << data.toStdString() << std::endl; + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData() +{ + QDateTime now = QDateTime::currentDateTime(); + + QString frameId = now.toString("HHmmsszzz"); + + QByteArray buffer; + buffer.append(QByteUtil::hexStringToBytes(frameId.mid(0, 8))); + + for (int i = 1; i <= 16; i++) + { + int value = qrand() % 10000; + buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); + } + + buffer.append(QByteUtil::hexStringToBytes("EEEEEEEE")); + + emit dataRecieved(buffer); +} diff --git a/common/utils/QSerialPortUtil.h b/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..accf403 --- /dev/null +++ b/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open; + + void mockReceivData(); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/common/utils/SettingConfig.cpp b/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..9a84a43 --- /dev/null +++ b/common/utils/SettingConfig.cpp @@ -0,0 +1,29 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + BAUD_RATE = getProperty("com", "baudRate").toInt(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + NEED_SASL = getProperty("kafka", "needSasl").toInt(); + SASL_USERNAME = getProperty("kafka", "saslUsername").toString(); + SASL_PASSWORD = getProperty("kafka", "saslPassword").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/common/utils/SettingConfig.h b/common/utils/SettingConfig.h new file mode 100644 index 0000000..0038ecc --- /dev/null +++ b/common/utils/SettingConfig.h @@ -0,0 +1,53 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + int BAUD_RATE; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + int NEED_SASL; + QString SASL_USERNAME; + QString SASL_PASSWORD; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/PhaseWindow.h b/PhaseWindow.h new file mode 100644 index 0000000..02a7908 --- /dev/null +++ b/PhaseWindow.h @@ -0,0 +1,47 @@ +#ifndef PHASEWINDOW_H +#define PHASEWINDOW_H + +#include +#include +#include +#include + +#include "PhaseDevice.h" +#include "common/utils/SettingConfig.h" +#include "common/HttpRequestController.h" + +namespace Ui { +class PhaseWindow; +} + +class PhaseWindow : public QWidget +{ + Q_OBJECT + +public: + explicit PhaseWindow(QWidget *parent = nullptr); + ~PhaseWindow(); + +public slots: + void drawPhaseDataOnPage(PhaseDataDto * phaseData); + +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + +private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + + Ui::PhaseWindow *ui; + + HttpRequestController * httpReq; + + QList deviceList; + + void generateWidgetForDevice(); +}; + +#endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui new file mode 100644 index 0000000..97edbe1 --- /dev/null +++ b/PhaseWindow.ui @@ -0,0 +1,712 @@ + + + PhaseWindow + + + + 0 + 0 + 1366 + 720 + + + + + 1366 + 0 + + + + 比相仪测量软件 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 1300 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 100 + 0 + 200 + 41 + + + + + 微软雅黑 + 14 + + + + 比相仪测量软件 + + + + + + 0 + 90 + 1371 + 16 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 1250 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + 1200 + 10 + 40 + 40 + + + + + + + 配置 + + + + + + 40 + 40 + 141 + 51 + + + + + 微软雅黑 + 14 + 75 + true + + + + Qt::RightToLeft + + + 2021-12-10 +10:00:00 + + + Qt::AlignCenter + + + + + + 230 + 35 + 941 + 40 + + + + + 1 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + 230 + 65 + 941 + 30 + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/common/ConstCache.h b/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/common/HttpRequestController.cpp b/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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++) + { + 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(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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; + + return resultObj; +} diff --git a/common/HttpRequestController.h b/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/common/common.pri b/common/common.pri new file mode 100644 index 0000000..84f57ae --- /dev/null +++ b/common/common.pri @@ -0,0 +1,20 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/common/utils/DefHead.h b/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/common/utils/HttpRequestUtil.cpp b/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/common/utils/HttpRequestUtil.h b/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/common/utils/MD5.cpp b/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/common/utils/MD5.h b/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/common/utils/QByteUtil.cpp b/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/common/utils/QByteUtil.h b/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/common/utils/QKafkaUtil.cpp b/common/utils/QKafkaUtil.cpp new file mode 100644 index 0000000..0cd1639 --- /dev/null +++ b/common/utils/QKafkaUtil.cpp @@ -0,0 +1,68 @@ +#include "QKafkaUtil.h" +#include "SettingConfig.h" +#include + +QKafkaUtil::QKafkaUtil(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaUtil::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaUtil::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaUtil::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + if (SettingConfig::getInstance().NEED_SASL == 1) + { + conf->set("sasl.username", SettingConfig::getInstance().SASL_USERNAME.toStdString(), errStr); + conf->set("sasl.password", SettingConfig::getInstance().SASL_PASSWORD.toStdString(), errStr); + conf->set("security.protocol", "sasl_plaintext", errStr); + conf->set("sasl.mechanisms", "PLAIN", errStr); + } + + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaUtil::produceMessage(QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/common/utils/QKafkaUtil.h b/common/utils/QKafkaUtil.h new file mode 100644 index 0000000..289ea6f --- /dev/null +++ b/common/utils/QKafkaUtil.h @@ -0,0 +1,33 @@ +#ifndef QKAFKAUTIL_H +#define QKAFKAUTIL_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaUtil : public QObject +{ + Q_OBJECT +public: + explicit QKafkaUtil(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAUTIL_H diff --git a/common/utils/QLogUtil.cpp b/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +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/common/utils/QLogUtil.h b/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + 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: + +}; + +#endif // QLOGUTIL_H diff --git a/common/utils/QSerialPortUtil.cpp b/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..64da0f7 --- /dev/null +++ b/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,77 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + + if (open == true) + { + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); + + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000); + } +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + if (this->open == true) + { + std::cout << data.toStdString() << std::endl; + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData() +{ + QDateTime now = QDateTime::currentDateTime(); + + QString frameId = now.toString("HHmmsszzz"); + + QByteArray buffer; + buffer.append(QByteUtil::hexStringToBytes(frameId.mid(0, 8))); + + for (int i = 1; i <= 16; i++) + { + int value = qrand() % 10000; + buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); + } + + buffer.append(QByteUtil::hexStringToBytes("EEEEEEEE")); + + emit dataRecieved(buffer); +} diff --git a/common/utils/QSerialPortUtil.h b/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..accf403 --- /dev/null +++ b/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open; + + void mockReceivData(); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/common/utils/SettingConfig.cpp b/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..9a84a43 --- /dev/null +++ b/common/utils/SettingConfig.cpp @@ -0,0 +1,29 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + BAUD_RATE = getProperty("com", "baudRate").toInt(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + NEED_SASL = getProperty("kafka", "needSasl").toInt(); + SASL_USERNAME = getProperty("kafka", "saslUsername").toString(); + SASL_PASSWORD = getProperty("kafka", "saslPassword").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/common/utils/SettingConfig.h b/common/utils/SettingConfig.h new file mode 100644 index 0000000..0038ecc --- /dev/null +++ b/common/utils/SettingConfig.h @@ -0,0 +1,53 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + int BAUD_RATE; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + int NEED_SASL; + QString SASL_USERNAME; + QString SASL_PASSWORD; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..46d97d7 --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,20 @@ +[com] +baudRate=115200 + +[kafka] +needKafka=1 +brokers="111.198.10.15:12502" +dataTopic="cppTest" +needSasl=0 +sasl.username="admin" +sasl.password="casicss" + +[client] +clientId="phase" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="/home/admin/Qt/ZXSSCJ-Release/PhaseCompAcq/logs/" diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/PhaseWindow.h b/PhaseWindow.h new file mode 100644 index 0000000..02a7908 --- /dev/null +++ b/PhaseWindow.h @@ -0,0 +1,47 @@ +#ifndef PHASEWINDOW_H +#define PHASEWINDOW_H + +#include +#include +#include +#include + +#include "PhaseDevice.h" +#include "common/utils/SettingConfig.h" +#include "common/HttpRequestController.h" + +namespace Ui { +class PhaseWindow; +} + +class PhaseWindow : public QWidget +{ + Q_OBJECT + +public: + explicit PhaseWindow(QWidget *parent = nullptr); + ~PhaseWindow(); + +public slots: + void drawPhaseDataOnPage(PhaseDataDto * phaseData); + +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + +private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + + Ui::PhaseWindow *ui; + + HttpRequestController * httpReq; + + QList deviceList; + + void generateWidgetForDevice(); +}; + +#endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui new file mode 100644 index 0000000..97edbe1 --- /dev/null +++ b/PhaseWindow.ui @@ -0,0 +1,712 @@ + + + PhaseWindow + + + + 0 + 0 + 1366 + 720 + + + + + 1366 + 0 + + + + 比相仪测量软件 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 1300 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 100 + 0 + 200 + 41 + + + + + 微软雅黑 + 14 + + + + 比相仪测量软件 + + + + + + 0 + 90 + 1371 + 16 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 1250 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + 1200 + 10 + 40 + 40 + + + + + + + 配置 + + + + + + 40 + 40 + 141 + 51 + + + + + 微软雅黑 + 14 + 75 + true + + + + Qt::RightToLeft + + + 2021-12-10 +10:00:00 + + + Qt::AlignCenter + + + + + + 230 + 35 + 941 + 40 + + + + + 1 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + 230 + 65 + 941 + 30 + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/common/ConstCache.h b/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/common/HttpRequestController.cpp b/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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++) + { + 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(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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; + + return resultObj; +} diff --git a/common/HttpRequestController.h b/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/common/common.pri b/common/common.pri new file mode 100644 index 0000000..84f57ae --- /dev/null +++ b/common/common.pri @@ -0,0 +1,20 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/common/utils/DefHead.h b/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/common/utils/HttpRequestUtil.cpp b/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/common/utils/HttpRequestUtil.h b/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/common/utils/MD5.cpp b/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/common/utils/MD5.h b/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/common/utils/QByteUtil.cpp b/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/common/utils/QByteUtil.h b/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/common/utils/QKafkaUtil.cpp b/common/utils/QKafkaUtil.cpp new file mode 100644 index 0000000..0cd1639 --- /dev/null +++ b/common/utils/QKafkaUtil.cpp @@ -0,0 +1,68 @@ +#include "QKafkaUtil.h" +#include "SettingConfig.h" +#include + +QKafkaUtil::QKafkaUtil(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaUtil::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaUtil::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaUtil::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + if (SettingConfig::getInstance().NEED_SASL == 1) + { + conf->set("sasl.username", SettingConfig::getInstance().SASL_USERNAME.toStdString(), errStr); + conf->set("sasl.password", SettingConfig::getInstance().SASL_PASSWORD.toStdString(), errStr); + conf->set("security.protocol", "sasl_plaintext", errStr); + conf->set("sasl.mechanisms", "PLAIN", errStr); + } + + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaUtil::produceMessage(QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/common/utils/QKafkaUtil.h b/common/utils/QKafkaUtil.h new file mode 100644 index 0000000..289ea6f --- /dev/null +++ b/common/utils/QKafkaUtil.h @@ -0,0 +1,33 @@ +#ifndef QKAFKAUTIL_H +#define QKAFKAUTIL_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaUtil : public QObject +{ + Q_OBJECT +public: + explicit QKafkaUtil(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAUTIL_H diff --git a/common/utils/QLogUtil.cpp b/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +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/common/utils/QLogUtil.h b/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + 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: + +}; + +#endif // QLOGUTIL_H diff --git a/common/utils/QSerialPortUtil.cpp b/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..64da0f7 --- /dev/null +++ b/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,77 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + + if (open == true) + { + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); + + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000); + } +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + if (this->open == true) + { + std::cout << data.toStdString() << std::endl; + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData() +{ + QDateTime now = QDateTime::currentDateTime(); + + QString frameId = now.toString("HHmmsszzz"); + + QByteArray buffer; + buffer.append(QByteUtil::hexStringToBytes(frameId.mid(0, 8))); + + for (int i = 1; i <= 16; i++) + { + int value = qrand() % 10000; + buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); + } + + buffer.append(QByteUtil::hexStringToBytes("EEEEEEEE")); + + emit dataRecieved(buffer); +} diff --git a/common/utils/QSerialPortUtil.h b/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..accf403 --- /dev/null +++ b/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open; + + void mockReceivData(); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/common/utils/SettingConfig.cpp b/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..9a84a43 --- /dev/null +++ b/common/utils/SettingConfig.cpp @@ -0,0 +1,29 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + BAUD_RATE = getProperty("com", "baudRate").toInt(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + NEED_SASL = getProperty("kafka", "needSasl").toInt(); + SASL_USERNAME = getProperty("kafka", "saslUsername").toString(); + SASL_PASSWORD = getProperty("kafka", "saslPassword").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/common/utils/SettingConfig.h b/common/utils/SettingConfig.h new file mode 100644 index 0000000..0038ecc --- /dev/null +++ b/common/utils/SettingConfig.h @@ -0,0 +1,53 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + int BAUD_RATE; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + int NEED_SASL; + QString SASL_USERNAME; + QString SASL_PASSWORD; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..46d97d7 --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,20 @@ +[com] +baudRate=115200 + +[kafka] +needKafka=1 +brokers="111.198.10.15:12502" +dataTopic="cppTest" +needSasl=0 +sasl.username="admin" +sasl.password="casicss" + +[client] +clientId="phase" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="/home/admin/Qt/ZXSSCJ-Release/PhaseCompAcq/logs/" diff --git a/images.qrc b/images.qrc new file mode 100644 index 0000000..0fc1f3e --- /dev/null +++ b/images.qrc @@ -0,0 +1,6 @@ + + + images/white.png + images/green.png + + diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/PhaseWindow.h b/PhaseWindow.h new file mode 100644 index 0000000..02a7908 --- /dev/null +++ b/PhaseWindow.h @@ -0,0 +1,47 @@ +#ifndef PHASEWINDOW_H +#define PHASEWINDOW_H + +#include +#include +#include +#include + +#include "PhaseDevice.h" +#include "common/utils/SettingConfig.h" +#include "common/HttpRequestController.h" + +namespace Ui { +class PhaseWindow; +} + +class PhaseWindow : public QWidget +{ + Q_OBJECT + +public: + explicit PhaseWindow(QWidget *parent = nullptr); + ~PhaseWindow(); + +public slots: + void drawPhaseDataOnPage(PhaseDataDto * phaseData); + +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + +private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + + Ui::PhaseWindow *ui; + + HttpRequestController * httpReq; + + QList deviceList; + + void generateWidgetForDevice(); +}; + +#endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui new file mode 100644 index 0000000..97edbe1 --- /dev/null +++ b/PhaseWindow.ui @@ -0,0 +1,712 @@ + + + PhaseWindow + + + + 0 + 0 + 1366 + 720 + + + + + 1366 + 0 + + + + 比相仪测量软件 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 1300 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 100 + 0 + 200 + 41 + + + + + 微软雅黑 + 14 + + + + 比相仪测量软件 + + + + + + 0 + 90 + 1371 + 16 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 1250 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + 1200 + 10 + 40 + 40 + + + + + + + 配置 + + + + + + 40 + 40 + 141 + 51 + + + + + 微软雅黑 + 14 + 75 + true + + + + Qt::RightToLeft + + + 2021-12-10 +10:00:00 + + + Qt::AlignCenter + + + + + + 230 + 35 + 941 + 40 + + + + + 1 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + 230 + 65 + 941 + 30 + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/common/ConstCache.h b/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/common/HttpRequestController.cpp b/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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++) + { + 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(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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; + + return resultObj; +} diff --git a/common/HttpRequestController.h b/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/common/common.pri b/common/common.pri new file mode 100644 index 0000000..84f57ae --- /dev/null +++ b/common/common.pri @@ -0,0 +1,20 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/common/utils/DefHead.h b/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/common/utils/HttpRequestUtil.cpp b/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/common/utils/HttpRequestUtil.h b/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/common/utils/MD5.cpp b/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/common/utils/MD5.h b/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/common/utils/QByteUtil.cpp b/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/common/utils/QByteUtil.h b/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/common/utils/QKafkaUtil.cpp b/common/utils/QKafkaUtil.cpp new file mode 100644 index 0000000..0cd1639 --- /dev/null +++ b/common/utils/QKafkaUtil.cpp @@ -0,0 +1,68 @@ +#include "QKafkaUtil.h" +#include "SettingConfig.h" +#include + +QKafkaUtil::QKafkaUtil(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaUtil::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaUtil::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaUtil::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + if (SettingConfig::getInstance().NEED_SASL == 1) + { + conf->set("sasl.username", SettingConfig::getInstance().SASL_USERNAME.toStdString(), errStr); + conf->set("sasl.password", SettingConfig::getInstance().SASL_PASSWORD.toStdString(), errStr); + conf->set("security.protocol", "sasl_plaintext", errStr); + conf->set("sasl.mechanisms", "PLAIN", errStr); + } + + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaUtil::produceMessage(QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/common/utils/QKafkaUtil.h b/common/utils/QKafkaUtil.h new file mode 100644 index 0000000..289ea6f --- /dev/null +++ b/common/utils/QKafkaUtil.h @@ -0,0 +1,33 @@ +#ifndef QKAFKAUTIL_H +#define QKAFKAUTIL_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaUtil : public QObject +{ + Q_OBJECT +public: + explicit QKafkaUtil(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAUTIL_H diff --git a/common/utils/QLogUtil.cpp b/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +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/common/utils/QLogUtil.h b/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + 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: + +}; + +#endif // QLOGUTIL_H diff --git a/common/utils/QSerialPortUtil.cpp b/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..64da0f7 --- /dev/null +++ b/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,77 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + + if (open == true) + { + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); + + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000); + } +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + if (this->open == true) + { + std::cout << data.toStdString() << std::endl; + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData() +{ + QDateTime now = QDateTime::currentDateTime(); + + QString frameId = now.toString("HHmmsszzz"); + + QByteArray buffer; + buffer.append(QByteUtil::hexStringToBytes(frameId.mid(0, 8))); + + for (int i = 1; i <= 16; i++) + { + int value = qrand() % 10000; + buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); + } + + buffer.append(QByteUtil::hexStringToBytes("EEEEEEEE")); + + emit dataRecieved(buffer); +} diff --git a/common/utils/QSerialPortUtil.h b/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..accf403 --- /dev/null +++ b/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open; + + void mockReceivData(); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/common/utils/SettingConfig.cpp b/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..9a84a43 --- /dev/null +++ b/common/utils/SettingConfig.cpp @@ -0,0 +1,29 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + BAUD_RATE = getProperty("com", "baudRate").toInt(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + NEED_SASL = getProperty("kafka", "needSasl").toInt(); + SASL_USERNAME = getProperty("kafka", "saslUsername").toString(); + SASL_PASSWORD = getProperty("kafka", "saslPassword").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/common/utils/SettingConfig.h b/common/utils/SettingConfig.h new file mode 100644 index 0000000..0038ecc --- /dev/null +++ b/common/utils/SettingConfig.h @@ -0,0 +1,53 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + int BAUD_RATE; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + int NEED_SASL; + QString SASL_USERNAME; + QString SASL_PASSWORD; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..46d97d7 --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,20 @@ +[com] +baudRate=115200 + +[kafka] +needKafka=1 +brokers="111.198.10.15:12502" +dataTopic="cppTest" +needSasl=0 +sasl.username="admin" +sasl.password="casicss" + +[client] +clientId="phase" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="/home/admin/Qt/ZXSSCJ-Release/PhaseCompAcq/logs/" diff --git a/images.qrc b/images.qrc new file mode 100644 index 0000000..0fc1f3e --- /dev/null +++ b/images.qrc @@ -0,0 +1,6 @@ + + + images/white.png + images/green.png + + diff --git a/images/green.png b/images/green.png new file mode 100644 index 0000000..a33ee4b --- /dev/null +++ b/images/green.png Binary files differ diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/PhaseWindow.h b/PhaseWindow.h new file mode 100644 index 0000000..02a7908 --- /dev/null +++ b/PhaseWindow.h @@ -0,0 +1,47 @@ +#ifndef PHASEWINDOW_H +#define PHASEWINDOW_H + +#include +#include +#include +#include + +#include "PhaseDevice.h" +#include "common/utils/SettingConfig.h" +#include "common/HttpRequestController.h" + +namespace Ui { +class PhaseWindow; +} + +class PhaseWindow : public QWidget +{ + Q_OBJECT + +public: + explicit PhaseWindow(QWidget *parent = nullptr); + ~PhaseWindow(); + +public slots: + void drawPhaseDataOnPage(PhaseDataDto * phaseData); + +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + +private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + + Ui::PhaseWindow *ui; + + HttpRequestController * httpReq; + + QList deviceList; + + void generateWidgetForDevice(); +}; + +#endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui new file mode 100644 index 0000000..97edbe1 --- /dev/null +++ b/PhaseWindow.ui @@ -0,0 +1,712 @@ + + + PhaseWindow + + + + 0 + 0 + 1366 + 720 + + + + + 1366 + 0 + + + + 比相仪测量软件 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 1300 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 100 + 0 + 200 + 41 + + + + + 微软雅黑 + 14 + + + + 比相仪测量软件 + + + + + + 0 + 90 + 1371 + 16 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 1250 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + 1200 + 10 + 40 + 40 + + + + + + + 配置 + + + + + + 40 + 40 + 141 + 51 + + + + + 微软雅黑 + 14 + 75 + true + + + + Qt::RightToLeft + + + 2021-12-10 +10:00:00 + + + Qt::AlignCenter + + + + + + 230 + 35 + 941 + 40 + + + + + 1 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + 230 + 65 + 941 + 30 + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/common/ConstCache.h b/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/common/HttpRequestController.cpp b/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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++) + { + 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(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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; + + return resultObj; +} diff --git a/common/HttpRequestController.h b/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/common/common.pri b/common/common.pri new file mode 100644 index 0000000..84f57ae --- /dev/null +++ b/common/common.pri @@ -0,0 +1,20 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/common/utils/DefHead.h b/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/common/utils/HttpRequestUtil.cpp b/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/common/utils/HttpRequestUtil.h b/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/common/utils/MD5.cpp b/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/common/utils/MD5.h b/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/common/utils/QByteUtil.cpp b/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/common/utils/QByteUtil.h b/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/common/utils/QKafkaUtil.cpp b/common/utils/QKafkaUtil.cpp new file mode 100644 index 0000000..0cd1639 --- /dev/null +++ b/common/utils/QKafkaUtil.cpp @@ -0,0 +1,68 @@ +#include "QKafkaUtil.h" +#include "SettingConfig.h" +#include + +QKafkaUtil::QKafkaUtil(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaUtil::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaUtil::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaUtil::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + if (SettingConfig::getInstance().NEED_SASL == 1) + { + conf->set("sasl.username", SettingConfig::getInstance().SASL_USERNAME.toStdString(), errStr); + conf->set("sasl.password", SettingConfig::getInstance().SASL_PASSWORD.toStdString(), errStr); + conf->set("security.protocol", "sasl_plaintext", errStr); + conf->set("sasl.mechanisms", "PLAIN", errStr); + } + + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaUtil::produceMessage(QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/common/utils/QKafkaUtil.h b/common/utils/QKafkaUtil.h new file mode 100644 index 0000000..289ea6f --- /dev/null +++ b/common/utils/QKafkaUtil.h @@ -0,0 +1,33 @@ +#ifndef QKAFKAUTIL_H +#define QKAFKAUTIL_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaUtil : public QObject +{ + Q_OBJECT +public: + explicit QKafkaUtil(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAUTIL_H diff --git a/common/utils/QLogUtil.cpp b/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +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/common/utils/QLogUtil.h b/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + 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: + +}; + +#endif // QLOGUTIL_H diff --git a/common/utils/QSerialPortUtil.cpp b/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..64da0f7 --- /dev/null +++ b/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,77 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + + if (open == true) + { + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); + + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000); + } +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + if (this->open == true) + { + std::cout << data.toStdString() << std::endl; + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData() +{ + QDateTime now = QDateTime::currentDateTime(); + + QString frameId = now.toString("HHmmsszzz"); + + QByteArray buffer; + buffer.append(QByteUtil::hexStringToBytes(frameId.mid(0, 8))); + + for (int i = 1; i <= 16; i++) + { + int value = qrand() % 10000; + buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); + } + + buffer.append(QByteUtil::hexStringToBytes("EEEEEEEE")); + + emit dataRecieved(buffer); +} diff --git a/common/utils/QSerialPortUtil.h b/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..accf403 --- /dev/null +++ b/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open; + + void mockReceivData(); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/common/utils/SettingConfig.cpp b/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..9a84a43 --- /dev/null +++ b/common/utils/SettingConfig.cpp @@ -0,0 +1,29 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + BAUD_RATE = getProperty("com", "baudRate").toInt(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + NEED_SASL = getProperty("kafka", "needSasl").toInt(); + SASL_USERNAME = getProperty("kafka", "saslUsername").toString(); + SASL_PASSWORD = getProperty("kafka", "saslPassword").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/common/utils/SettingConfig.h b/common/utils/SettingConfig.h new file mode 100644 index 0000000..0038ecc --- /dev/null +++ b/common/utils/SettingConfig.h @@ -0,0 +1,53 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + int BAUD_RATE; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + int NEED_SASL; + QString SASL_USERNAME; + QString SASL_PASSWORD; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..46d97d7 --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,20 @@ +[com] +baudRate=115200 + +[kafka] +needKafka=1 +brokers="111.198.10.15:12502" +dataTopic="cppTest" +needSasl=0 +sasl.username="admin" +sasl.password="casicss" + +[client] +clientId="phase" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="/home/admin/Qt/ZXSSCJ-Release/PhaseCompAcq/logs/" diff --git a/images.qrc b/images.qrc new file mode 100644 index 0000000..0fc1f3e --- /dev/null +++ b/images.qrc @@ -0,0 +1,6 @@ + + + images/white.png + images/green.png + + diff --git a/images/green.png b/images/green.png new file mode 100644 index 0000000..a33ee4b --- /dev/null +++ b/images/green.png Binary files differ diff --git a/images/white.png b/images/white.png new file mode 100644 index 0000000..337df06 --- /dev/null +++ b/images/white.png Binary files differ diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/PhaseWindow.h b/PhaseWindow.h new file mode 100644 index 0000000..02a7908 --- /dev/null +++ b/PhaseWindow.h @@ -0,0 +1,47 @@ +#ifndef PHASEWINDOW_H +#define PHASEWINDOW_H + +#include +#include +#include +#include + +#include "PhaseDevice.h" +#include "common/utils/SettingConfig.h" +#include "common/HttpRequestController.h" + +namespace Ui { +class PhaseWindow; +} + +class PhaseWindow : public QWidget +{ + Q_OBJECT + +public: + explicit PhaseWindow(QWidget *parent = nullptr); + ~PhaseWindow(); + +public slots: + void drawPhaseDataOnPage(PhaseDataDto * phaseData); + +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + +private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + + Ui::PhaseWindow *ui; + + HttpRequestController * httpReq; + + QList deviceList; + + void generateWidgetForDevice(); +}; + +#endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui new file mode 100644 index 0000000..97edbe1 --- /dev/null +++ b/PhaseWindow.ui @@ -0,0 +1,712 @@ + + + PhaseWindow + + + + 0 + 0 + 1366 + 720 + + + + + 1366 + 0 + + + + 比相仪测量软件 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 1300 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 100 + 0 + 200 + 41 + + + + + 微软雅黑 + 14 + + + + 比相仪测量软件 + + + + + + 0 + 90 + 1371 + 16 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 1250 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + 1200 + 10 + 40 + 40 + + + + + + + 配置 + + + + + + 40 + 40 + 141 + 51 + + + + + 微软雅黑 + 14 + 75 + true + + + + Qt::RightToLeft + + + 2021-12-10 +10:00:00 + + + Qt::AlignCenter + + + + + + 230 + 35 + 941 + 40 + + + + + 1 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + 230 + 65 + 941 + 30 + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/common/ConstCache.h b/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/common/HttpRequestController.cpp b/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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++) + { + 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(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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; + + return resultObj; +} diff --git a/common/HttpRequestController.h b/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/common/common.pri b/common/common.pri new file mode 100644 index 0000000..84f57ae --- /dev/null +++ b/common/common.pri @@ -0,0 +1,20 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/common/utils/DefHead.h b/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/common/utils/HttpRequestUtil.cpp b/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/common/utils/HttpRequestUtil.h b/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/common/utils/MD5.cpp b/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/common/utils/MD5.h b/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/common/utils/QByteUtil.cpp b/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/common/utils/QByteUtil.h b/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/common/utils/QKafkaUtil.cpp b/common/utils/QKafkaUtil.cpp new file mode 100644 index 0000000..0cd1639 --- /dev/null +++ b/common/utils/QKafkaUtil.cpp @@ -0,0 +1,68 @@ +#include "QKafkaUtil.h" +#include "SettingConfig.h" +#include + +QKafkaUtil::QKafkaUtil(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaUtil::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaUtil::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaUtil::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + if (SettingConfig::getInstance().NEED_SASL == 1) + { + conf->set("sasl.username", SettingConfig::getInstance().SASL_USERNAME.toStdString(), errStr); + conf->set("sasl.password", SettingConfig::getInstance().SASL_PASSWORD.toStdString(), errStr); + conf->set("security.protocol", "sasl_plaintext", errStr); + conf->set("sasl.mechanisms", "PLAIN", errStr); + } + + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaUtil::produceMessage(QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/common/utils/QKafkaUtil.h b/common/utils/QKafkaUtil.h new file mode 100644 index 0000000..289ea6f --- /dev/null +++ b/common/utils/QKafkaUtil.h @@ -0,0 +1,33 @@ +#ifndef QKAFKAUTIL_H +#define QKAFKAUTIL_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaUtil : public QObject +{ + Q_OBJECT +public: + explicit QKafkaUtil(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAUTIL_H diff --git a/common/utils/QLogUtil.cpp b/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +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/common/utils/QLogUtil.h b/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + 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: + +}; + +#endif // QLOGUTIL_H diff --git a/common/utils/QSerialPortUtil.cpp b/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..64da0f7 --- /dev/null +++ b/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,77 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + + if (open == true) + { + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); + + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000); + } +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + if (this->open == true) + { + std::cout << data.toStdString() << std::endl; + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData() +{ + QDateTime now = QDateTime::currentDateTime(); + + QString frameId = now.toString("HHmmsszzz"); + + QByteArray buffer; + buffer.append(QByteUtil::hexStringToBytes(frameId.mid(0, 8))); + + for (int i = 1; i <= 16; i++) + { + int value = qrand() % 10000; + buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); + } + + buffer.append(QByteUtil::hexStringToBytes("EEEEEEEE")); + + emit dataRecieved(buffer); +} diff --git a/common/utils/QSerialPortUtil.h b/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..accf403 --- /dev/null +++ b/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open; + + void mockReceivData(); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/common/utils/SettingConfig.cpp b/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..9a84a43 --- /dev/null +++ b/common/utils/SettingConfig.cpp @@ -0,0 +1,29 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + BAUD_RATE = getProperty("com", "baudRate").toInt(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + NEED_SASL = getProperty("kafka", "needSasl").toInt(); + SASL_USERNAME = getProperty("kafka", "saslUsername").toString(); + SASL_PASSWORD = getProperty("kafka", "saslPassword").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/common/utils/SettingConfig.h b/common/utils/SettingConfig.h new file mode 100644 index 0000000..0038ecc --- /dev/null +++ b/common/utils/SettingConfig.h @@ -0,0 +1,53 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + int BAUD_RATE; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + int NEED_SASL; + QString SASL_USERNAME; + QString SASL_PASSWORD; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..46d97d7 --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,20 @@ +[com] +baudRate=115200 + +[kafka] +needKafka=1 +brokers="111.198.10.15:12502" +dataTopic="cppTest" +needSasl=0 +sasl.username="admin" +sasl.password="casicss" + +[client] +clientId="phase" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="/home/admin/Qt/ZXSSCJ-Release/PhaseCompAcq/logs/" diff --git a/images.qrc b/images.qrc new file mode 100644 index 0000000..0fc1f3e --- /dev/null +++ b/images.qrc @@ -0,0 +1,6 @@ + + + images/white.png + images/green.png + + diff --git a/images/green.png b/images/green.png new file mode 100644 index 0000000..a33ee4b --- /dev/null +++ b/images/green.png Binary files differ diff --git a/images/white.png b/images/white.png new file mode 100644 index 0000000..337df06 --- /dev/null +++ b/images/white.png Binary files differ diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..adf5eeb --- /dev/null +++ b/main.cpp @@ -0,0 +1,11 @@ +#include "PhaseWindow.h" + +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + PhaseWindow w; + w.show(); + return a.exec(); +} diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/PhaseWindow.h b/PhaseWindow.h new file mode 100644 index 0000000..02a7908 --- /dev/null +++ b/PhaseWindow.h @@ -0,0 +1,47 @@ +#ifndef PHASEWINDOW_H +#define PHASEWINDOW_H + +#include +#include +#include +#include + +#include "PhaseDevice.h" +#include "common/utils/SettingConfig.h" +#include "common/HttpRequestController.h" + +namespace Ui { +class PhaseWindow; +} + +class PhaseWindow : public QWidget +{ + Q_OBJECT + +public: + explicit PhaseWindow(QWidget *parent = nullptr); + ~PhaseWindow(); + +public slots: + void drawPhaseDataOnPage(PhaseDataDto * phaseData); + +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + +private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + + Ui::PhaseWindow *ui; + + HttpRequestController * httpReq; + + QList deviceList; + + void generateWidgetForDevice(); +}; + +#endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui new file mode 100644 index 0000000..97edbe1 --- /dev/null +++ b/PhaseWindow.ui @@ -0,0 +1,712 @@ + + + PhaseWindow + + + + 0 + 0 + 1366 + 720 + + + + + 1366 + 0 + + + + 比相仪测量软件 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 1300 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 100 + 0 + 200 + 41 + + + + + 微软雅黑 + 14 + + + + 比相仪测量软件 + + + + + + 0 + 90 + 1371 + 16 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 1250 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + 1200 + 10 + 40 + 40 + + + + + + + 配置 + + + + + + 40 + 40 + 141 + 51 + + + + + 微软雅黑 + 14 + 75 + true + + + + Qt::RightToLeft + + + 2021-12-10 +10:00:00 + + + Qt::AlignCenter + + + + + + 230 + 35 + 941 + 40 + + + + + 1 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + 230 + 65 + 941 + 30 + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/common/ConstCache.h b/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/common/HttpRequestController.cpp b/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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++) + { + 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(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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; + + return resultObj; +} diff --git a/common/HttpRequestController.h b/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/common/common.pri b/common/common.pri new file mode 100644 index 0000000..84f57ae --- /dev/null +++ b/common/common.pri @@ -0,0 +1,20 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/common/utils/DefHead.h b/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/common/utils/HttpRequestUtil.cpp b/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/common/utils/HttpRequestUtil.h b/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/common/utils/MD5.cpp b/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/common/utils/MD5.h b/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/common/utils/QByteUtil.cpp b/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/common/utils/QByteUtil.h b/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/common/utils/QKafkaUtil.cpp b/common/utils/QKafkaUtil.cpp new file mode 100644 index 0000000..0cd1639 --- /dev/null +++ b/common/utils/QKafkaUtil.cpp @@ -0,0 +1,68 @@ +#include "QKafkaUtil.h" +#include "SettingConfig.h" +#include + +QKafkaUtil::QKafkaUtil(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaUtil::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaUtil::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaUtil::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + if (SettingConfig::getInstance().NEED_SASL == 1) + { + conf->set("sasl.username", SettingConfig::getInstance().SASL_USERNAME.toStdString(), errStr); + conf->set("sasl.password", SettingConfig::getInstance().SASL_PASSWORD.toStdString(), errStr); + conf->set("security.protocol", "sasl_plaintext", errStr); + conf->set("sasl.mechanisms", "PLAIN", errStr); + } + + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaUtil::produceMessage(QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/common/utils/QKafkaUtil.h b/common/utils/QKafkaUtil.h new file mode 100644 index 0000000..289ea6f --- /dev/null +++ b/common/utils/QKafkaUtil.h @@ -0,0 +1,33 @@ +#ifndef QKAFKAUTIL_H +#define QKAFKAUTIL_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaUtil : public QObject +{ + Q_OBJECT +public: + explicit QKafkaUtil(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAUTIL_H diff --git a/common/utils/QLogUtil.cpp b/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +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/common/utils/QLogUtil.h b/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + 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: + +}; + +#endif // QLOGUTIL_H diff --git a/common/utils/QSerialPortUtil.cpp b/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..64da0f7 --- /dev/null +++ b/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,77 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + + if (open == true) + { + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); + + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000); + } +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + if (this->open == true) + { + std::cout << data.toStdString() << std::endl; + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData() +{ + QDateTime now = QDateTime::currentDateTime(); + + QString frameId = now.toString("HHmmsszzz"); + + QByteArray buffer; + buffer.append(QByteUtil::hexStringToBytes(frameId.mid(0, 8))); + + for (int i = 1; i <= 16; i++) + { + int value = qrand() % 10000; + buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); + } + + buffer.append(QByteUtil::hexStringToBytes("EEEEEEEE")); + + emit dataRecieved(buffer); +} diff --git a/common/utils/QSerialPortUtil.h b/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..accf403 --- /dev/null +++ b/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open; + + void mockReceivData(); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/common/utils/SettingConfig.cpp b/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..9a84a43 --- /dev/null +++ b/common/utils/SettingConfig.cpp @@ -0,0 +1,29 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + BAUD_RATE = getProperty("com", "baudRate").toInt(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + NEED_SASL = getProperty("kafka", "needSasl").toInt(); + SASL_USERNAME = getProperty("kafka", "saslUsername").toString(); + SASL_PASSWORD = getProperty("kafka", "saslPassword").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/common/utils/SettingConfig.h b/common/utils/SettingConfig.h new file mode 100644 index 0000000..0038ecc --- /dev/null +++ b/common/utils/SettingConfig.h @@ -0,0 +1,53 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + int BAUD_RATE; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + int NEED_SASL; + QString SASL_USERNAME; + QString SASL_PASSWORD; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..46d97d7 --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,20 @@ +[com] +baudRate=115200 + +[kafka] +needKafka=1 +brokers="111.198.10.15:12502" +dataTopic="cppTest" +needSasl=0 +sasl.username="admin" +sasl.password="casicss" + +[client] +clientId="phase" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="/home/admin/Qt/ZXSSCJ-Release/PhaseCompAcq/logs/" diff --git a/images.qrc b/images.qrc new file mode 100644 index 0000000..0fc1f3e --- /dev/null +++ b/images.qrc @@ -0,0 +1,6 @@ + + + images/white.png + images/green.png + + diff --git a/images/green.png b/images/green.png new file mode 100644 index 0000000..a33ee4b --- /dev/null +++ b/images/green.png Binary files differ diff --git a/images/white.png b/images/white.png new file mode 100644 index 0000000..337df06 --- /dev/null +++ b/images/white.png Binary files differ diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..adf5eeb --- /dev/null +++ b/main.cpp @@ -0,0 +1,11 @@ +#include "PhaseWindow.h" + +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + PhaseWindow w; + w.show(); + return a.exec(); +} diff --git a/protocol/PhaseProtocolBM.cpp b/protocol/PhaseProtocolBM.cpp new file mode 100644 index 0000000..aa4f086 --- /dev/null +++ b/protocol/PhaseProtocolBM.cpp @@ -0,0 +1,78 @@ +#include "PhaseProtocolBM.h" +#include + +PhaseProtocolBM::PhaseProtocolBM(QObject *parent) : QObject(parent) +{ + +} + +PhaseProtocolBM::~PhaseProtocolBM() +{ + +} + +bool PhaseProtocolBM::parseMessureData(QByteArray rawData, PhaseDataDto * dataObj) +{ + // 获取帧头——帧计数 + QByteArray head = rawData.left(PHASE_FRAME_ID_LENGTH); + dataObj->frameId = QByteUtil::binToHexString(head); + + int j = 0; // 用于转换通道顺序 + + // 获取每个通道的测量数据 + for (int i = 1; i <= PHASE_MESSURE_CHANNEL; i++) + { + if (i <= 8) + { + j = 2 * i - 1; + + } else + { + j = 2 * (i - 8); + } + + QByteArray channelRaw = rawData.left(PHASE_MESSURE_SIZE * j + PHASE_FRAME_ID_LENGTH).right(PHASE_MESSURE_SIZE); + qulonglong channelRawData = QByteUtil::binToULong(channelRaw, 8); + + if (channelRawData == CALCULATE_OFFSET) + { + dataObj->channelActive.append("0"); + dataObj->channelData.append(0.00); + dataObj->channelDataStr.append("0.00"); + } else + { + double phase = (channelRawData - CALCULATE_OFFSET) * CALCULATE_FACTOR; + dataObj->channelActive.append("1"); + dataObj->channelData.append(phase); + dataObj->channelDataStr.append(QString::number(phase, 'f', 12)); + } + } + + return true; +} + +QString PhaseProtocolBM::startMessure() +{ + return "$START*"; +} +QString PhaseProtocolBM::stopMessure() +{ + return "$$STOP*"; +} + +bool PhaseProtocolBM::checkFrame(QByteArray rawData) +{ + // 帧长度小于最小的长度 + if (rawData.length() != PHASE_FRAM_LENGTH) + { + return false; + } + + // 帧尾不是0xEEEEEEEE + if (rawData.mid(rawData.length() - PHASE_FRAME_TAIL.size()) != PHASE_FRAME_TAIL) + { + return false; + } + + return true; +} diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/PhaseWindow.h b/PhaseWindow.h new file mode 100644 index 0000000..02a7908 --- /dev/null +++ b/PhaseWindow.h @@ -0,0 +1,47 @@ +#ifndef PHASEWINDOW_H +#define PHASEWINDOW_H + +#include +#include +#include +#include + +#include "PhaseDevice.h" +#include "common/utils/SettingConfig.h" +#include "common/HttpRequestController.h" + +namespace Ui { +class PhaseWindow; +} + +class PhaseWindow : public QWidget +{ + Q_OBJECT + +public: + explicit PhaseWindow(QWidget *parent = nullptr); + ~PhaseWindow(); + +public slots: + void drawPhaseDataOnPage(PhaseDataDto * phaseData); + +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + +private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + + Ui::PhaseWindow *ui; + + HttpRequestController * httpReq; + + QList deviceList; + + void generateWidgetForDevice(); +}; + +#endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui new file mode 100644 index 0000000..97edbe1 --- /dev/null +++ b/PhaseWindow.ui @@ -0,0 +1,712 @@ + + + PhaseWindow + + + + 0 + 0 + 1366 + 720 + + + + + 1366 + 0 + + + + 比相仪测量软件 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 1300 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 100 + 0 + 200 + 41 + + + + + 微软雅黑 + 14 + + + + 比相仪测量软件 + + + + + + 0 + 90 + 1371 + 16 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 1250 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + 1200 + 10 + 40 + 40 + + + + + + + 配置 + + + + + + 40 + 40 + 141 + 51 + + + + + 微软雅黑 + 14 + 75 + true + + + + Qt::RightToLeft + + + 2021-12-10 +10:00:00 + + + Qt::AlignCenter + + + + + + 230 + 35 + 941 + 40 + + + + + 1 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + 230 + 65 + 941 + 30 + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/common/ConstCache.h b/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/common/HttpRequestController.cpp b/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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++) + { + 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(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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; + + return resultObj; +} diff --git a/common/HttpRequestController.h b/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/common/common.pri b/common/common.pri new file mode 100644 index 0000000..84f57ae --- /dev/null +++ b/common/common.pri @@ -0,0 +1,20 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/common/utils/DefHead.h b/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/common/utils/HttpRequestUtil.cpp b/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/common/utils/HttpRequestUtil.h b/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/common/utils/MD5.cpp b/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/common/utils/MD5.h b/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/common/utils/QByteUtil.cpp b/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/common/utils/QByteUtil.h b/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/common/utils/QKafkaUtil.cpp b/common/utils/QKafkaUtil.cpp new file mode 100644 index 0000000..0cd1639 --- /dev/null +++ b/common/utils/QKafkaUtil.cpp @@ -0,0 +1,68 @@ +#include "QKafkaUtil.h" +#include "SettingConfig.h" +#include + +QKafkaUtil::QKafkaUtil(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaUtil::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaUtil::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaUtil::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + if (SettingConfig::getInstance().NEED_SASL == 1) + { + conf->set("sasl.username", SettingConfig::getInstance().SASL_USERNAME.toStdString(), errStr); + conf->set("sasl.password", SettingConfig::getInstance().SASL_PASSWORD.toStdString(), errStr); + conf->set("security.protocol", "sasl_plaintext", errStr); + conf->set("sasl.mechanisms", "PLAIN", errStr); + } + + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaUtil::produceMessage(QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/common/utils/QKafkaUtil.h b/common/utils/QKafkaUtil.h new file mode 100644 index 0000000..289ea6f --- /dev/null +++ b/common/utils/QKafkaUtil.h @@ -0,0 +1,33 @@ +#ifndef QKAFKAUTIL_H +#define QKAFKAUTIL_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaUtil : public QObject +{ + Q_OBJECT +public: + explicit QKafkaUtil(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAUTIL_H diff --git a/common/utils/QLogUtil.cpp b/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +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/common/utils/QLogUtil.h b/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + 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: + +}; + +#endif // QLOGUTIL_H diff --git a/common/utils/QSerialPortUtil.cpp b/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..64da0f7 --- /dev/null +++ b/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,77 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + + if (open == true) + { + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); + + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000); + } +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + if (this->open == true) + { + std::cout << data.toStdString() << std::endl; + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData() +{ + QDateTime now = QDateTime::currentDateTime(); + + QString frameId = now.toString("HHmmsszzz"); + + QByteArray buffer; + buffer.append(QByteUtil::hexStringToBytes(frameId.mid(0, 8))); + + for (int i = 1; i <= 16; i++) + { + int value = qrand() % 10000; + buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); + } + + buffer.append(QByteUtil::hexStringToBytes("EEEEEEEE")); + + emit dataRecieved(buffer); +} diff --git a/common/utils/QSerialPortUtil.h b/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..accf403 --- /dev/null +++ b/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open; + + void mockReceivData(); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/common/utils/SettingConfig.cpp b/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..9a84a43 --- /dev/null +++ b/common/utils/SettingConfig.cpp @@ -0,0 +1,29 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + BAUD_RATE = getProperty("com", "baudRate").toInt(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + NEED_SASL = getProperty("kafka", "needSasl").toInt(); + SASL_USERNAME = getProperty("kafka", "saslUsername").toString(); + SASL_PASSWORD = getProperty("kafka", "saslPassword").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/common/utils/SettingConfig.h b/common/utils/SettingConfig.h new file mode 100644 index 0000000..0038ecc --- /dev/null +++ b/common/utils/SettingConfig.h @@ -0,0 +1,53 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + int BAUD_RATE; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + int NEED_SASL; + QString SASL_USERNAME; + QString SASL_PASSWORD; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..46d97d7 --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,20 @@ +[com] +baudRate=115200 + +[kafka] +needKafka=1 +brokers="111.198.10.15:12502" +dataTopic="cppTest" +needSasl=0 +sasl.username="admin" +sasl.password="casicss" + +[client] +clientId="phase" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="/home/admin/Qt/ZXSSCJ-Release/PhaseCompAcq/logs/" diff --git a/images.qrc b/images.qrc new file mode 100644 index 0000000..0fc1f3e --- /dev/null +++ b/images.qrc @@ -0,0 +1,6 @@ + + + images/white.png + images/green.png + + diff --git a/images/green.png b/images/green.png new file mode 100644 index 0000000..a33ee4b --- /dev/null +++ b/images/green.png Binary files differ diff --git a/images/white.png b/images/white.png new file mode 100644 index 0000000..337df06 --- /dev/null +++ b/images/white.png Binary files differ diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..adf5eeb --- /dev/null +++ b/main.cpp @@ -0,0 +1,11 @@ +#include "PhaseWindow.h" + +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + PhaseWindow w; + w.show(); + return a.exec(); +} diff --git a/protocol/PhaseProtocolBM.cpp b/protocol/PhaseProtocolBM.cpp new file mode 100644 index 0000000..aa4f086 --- /dev/null +++ b/protocol/PhaseProtocolBM.cpp @@ -0,0 +1,78 @@ +#include "PhaseProtocolBM.h" +#include + +PhaseProtocolBM::PhaseProtocolBM(QObject *parent) : QObject(parent) +{ + +} + +PhaseProtocolBM::~PhaseProtocolBM() +{ + +} + +bool PhaseProtocolBM::parseMessureData(QByteArray rawData, PhaseDataDto * dataObj) +{ + // 获取帧头——帧计数 + QByteArray head = rawData.left(PHASE_FRAME_ID_LENGTH); + dataObj->frameId = QByteUtil::binToHexString(head); + + int j = 0; // 用于转换通道顺序 + + // 获取每个通道的测量数据 + for (int i = 1; i <= PHASE_MESSURE_CHANNEL; i++) + { + if (i <= 8) + { + j = 2 * i - 1; + + } else + { + j = 2 * (i - 8); + } + + QByteArray channelRaw = rawData.left(PHASE_MESSURE_SIZE * j + PHASE_FRAME_ID_LENGTH).right(PHASE_MESSURE_SIZE); + qulonglong channelRawData = QByteUtil::binToULong(channelRaw, 8); + + if (channelRawData == CALCULATE_OFFSET) + { + dataObj->channelActive.append("0"); + dataObj->channelData.append(0.00); + dataObj->channelDataStr.append("0.00"); + } else + { + double phase = (channelRawData - CALCULATE_OFFSET) * CALCULATE_FACTOR; + dataObj->channelActive.append("1"); + dataObj->channelData.append(phase); + dataObj->channelDataStr.append(QString::number(phase, 'f', 12)); + } + } + + return true; +} + +QString PhaseProtocolBM::startMessure() +{ + return "$START*"; +} +QString PhaseProtocolBM::stopMessure() +{ + return "$$STOP*"; +} + +bool PhaseProtocolBM::checkFrame(QByteArray rawData) +{ + // 帧长度小于最小的长度 + if (rawData.length() != PHASE_FRAM_LENGTH) + { + return false; + } + + // 帧尾不是0xEEEEEEEE + if (rawData.mid(rawData.length() - PHASE_FRAME_TAIL.size()) != PHASE_FRAME_TAIL) + { + return false; + } + + return true; +} diff --git a/protocol/PhaseProtocolBM.h b/protocol/PhaseProtocolBM.h new file mode 100644 index 0000000..048a9c2 --- /dev/null +++ b/protocol/PhaseProtocolBM.h @@ -0,0 +1,36 @@ +#ifndef PHASEPROTOCOLBM_H +#define PHASEPROTOCOLBM_H + +#include + +#include "dto/PhaseDataDto.h" +#include "common/utils/QByteUtil.h" + +static const QByteArray PHASE_FRAME_TAIL("\xEE\xEE\xEE\xEE", 4); // 帧尾 + +static const int PHASE_FRAME_ID_LENGTH = 4; // 帧头id计数器为4个字节 +static const int PHASE_MESSURE_CHANNEL = 16; +static const int PHASE_MESSURE_SIZE = 8; +static const int PHASE_FRAM_LENGTH = PHASE_FRAME_ID_LENGTH + PHASE_FRAME_TAIL.size() + + PHASE_MESSURE_CHANNEL * PHASE_MESSURE_SIZE; + +static const qulonglong CALCULATE_OFFSET = 0X0080000000000000; +static const double CALCULATE_FACTOR = 1.6810E-15; + +class PhaseProtocolBM : public QObject +{ +public: + explicit PhaseProtocolBM(QObject *parent = nullptr); + ~PhaseProtocolBM(); + + // 解析比相仪测量数据 + static bool parseMessureData(QByteArray rawData, PhaseDataDto * phaseData); + + static QString startMessure(); + static QString stopMessure(); + + // 检测帧格式,帧头帧尾 + static bool checkFrame(QByteArray rawData); +}; + +#endif // PHASEROTOCOLBM_H diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/PhaseWindow.h b/PhaseWindow.h new file mode 100644 index 0000000..02a7908 --- /dev/null +++ b/PhaseWindow.h @@ -0,0 +1,47 @@ +#ifndef PHASEWINDOW_H +#define PHASEWINDOW_H + +#include +#include +#include +#include + +#include "PhaseDevice.h" +#include "common/utils/SettingConfig.h" +#include "common/HttpRequestController.h" + +namespace Ui { +class PhaseWindow; +} + +class PhaseWindow : public QWidget +{ + Q_OBJECT + +public: + explicit PhaseWindow(QWidget *parent = nullptr); + ~PhaseWindow(); + +public slots: + void drawPhaseDataOnPage(PhaseDataDto * phaseData); + +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + +private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + + Ui::PhaseWindow *ui; + + HttpRequestController * httpReq; + + QList deviceList; + + void generateWidgetForDevice(); +}; + +#endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui new file mode 100644 index 0000000..97edbe1 --- /dev/null +++ b/PhaseWindow.ui @@ -0,0 +1,712 @@ + + + PhaseWindow + + + + 0 + 0 + 1366 + 720 + + + + + 1366 + 0 + + + + 比相仪测量软件 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 1300 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 100 + 0 + 200 + 41 + + + + + 微软雅黑 + 14 + + + + 比相仪测量软件 + + + + + + 0 + 90 + 1371 + 16 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 1250 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + 1200 + 10 + 40 + 40 + + + + + + + 配置 + + + + + + 40 + 40 + 141 + 51 + + + + + 微软雅黑 + 14 + 75 + true + + + + Qt::RightToLeft + + + 2021-12-10 +10:00:00 + + + Qt::AlignCenter + + + + + + 230 + 35 + 941 + 40 + + + + + 1 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + 230 + 65 + 941 + 30 + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/common/ConstCache.h b/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/common/HttpRequestController.cpp b/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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++) + { + 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(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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; + + return resultObj; +} diff --git a/common/HttpRequestController.h b/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/common/common.pri b/common/common.pri new file mode 100644 index 0000000..84f57ae --- /dev/null +++ b/common/common.pri @@ -0,0 +1,20 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/common/utils/DefHead.h b/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/common/utils/HttpRequestUtil.cpp b/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/common/utils/HttpRequestUtil.h b/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/common/utils/MD5.cpp b/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/common/utils/MD5.h b/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/common/utils/QByteUtil.cpp b/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/common/utils/QByteUtil.h b/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/common/utils/QKafkaUtil.cpp b/common/utils/QKafkaUtil.cpp new file mode 100644 index 0000000..0cd1639 --- /dev/null +++ b/common/utils/QKafkaUtil.cpp @@ -0,0 +1,68 @@ +#include "QKafkaUtil.h" +#include "SettingConfig.h" +#include + +QKafkaUtil::QKafkaUtil(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaUtil::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaUtil::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaUtil::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + if (SettingConfig::getInstance().NEED_SASL == 1) + { + conf->set("sasl.username", SettingConfig::getInstance().SASL_USERNAME.toStdString(), errStr); + conf->set("sasl.password", SettingConfig::getInstance().SASL_PASSWORD.toStdString(), errStr); + conf->set("security.protocol", "sasl_plaintext", errStr); + conf->set("sasl.mechanisms", "PLAIN", errStr); + } + + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaUtil::produceMessage(QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/common/utils/QKafkaUtil.h b/common/utils/QKafkaUtil.h new file mode 100644 index 0000000..289ea6f --- /dev/null +++ b/common/utils/QKafkaUtil.h @@ -0,0 +1,33 @@ +#ifndef QKAFKAUTIL_H +#define QKAFKAUTIL_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaUtil : public QObject +{ + Q_OBJECT +public: + explicit QKafkaUtil(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAUTIL_H diff --git a/common/utils/QLogUtil.cpp b/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +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/common/utils/QLogUtil.h b/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + 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: + +}; + +#endif // QLOGUTIL_H diff --git a/common/utils/QSerialPortUtil.cpp b/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..64da0f7 --- /dev/null +++ b/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,77 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + + if (open == true) + { + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); + + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000); + } +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + if (this->open == true) + { + std::cout << data.toStdString() << std::endl; + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData() +{ + QDateTime now = QDateTime::currentDateTime(); + + QString frameId = now.toString("HHmmsszzz"); + + QByteArray buffer; + buffer.append(QByteUtil::hexStringToBytes(frameId.mid(0, 8))); + + for (int i = 1; i <= 16; i++) + { + int value = qrand() % 10000; + buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); + } + + buffer.append(QByteUtil::hexStringToBytes("EEEEEEEE")); + + emit dataRecieved(buffer); +} diff --git a/common/utils/QSerialPortUtil.h b/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..accf403 --- /dev/null +++ b/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open; + + void mockReceivData(); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/common/utils/SettingConfig.cpp b/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..9a84a43 --- /dev/null +++ b/common/utils/SettingConfig.cpp @@ -0,0 +1,29 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + BAUD_RATE = getProperty("com", "baudRate").toInt(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + NEED_SASL = getProperty("kafka", "needSasl").toInt(); + SASL_USERNAME = getProperty("kafka", "saslUsername").toString(); + SASL_PASSWORD = getProperty("kafka", "saslPassword").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/common/utils/SettingConfig.h b/common/utils/SettingConfig.h new file mode 100644 index 0000000..0038ecc --- /dev/null +++ b/common/utils/SettingConfig.h @@ -0,0 +1,53 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + int BAUD_RATE; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + int NEED_SASL; + QString SASL_USERNAME; + QString SASL_PASSWORD; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..46d97d7 --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,20 @@ +[com] +baudRate=115200 + +[kafka] +needKafka=1 +brokers="111.198.10.15:12502" +dataTopic="cppTest" +needSasl=0 +sasl.username="admin" +sasl.password="casicss" + +[client] +clientId="phase" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="/home/admin/Qt/ZXSSCJ-Release/PhaseCompAcq/logs/" diff --git a/images.qrc b/images.qrc new file mode 100644 index 0000000..0fc1f3e --- /dev/null +++ b/images.qrc @@ -0,0 +1,6 @@ + + + images/white.png + images/green.png + + diff --git a/images/green.png b/images/green.png new file mode 100644 index 0000000..a33ee4b --- /dev/null +++ b/images/green.png Binary files differ diff --git a/images/white.png b/images/white.png new file mode 100644 index 0000000..337df06 --- /dev/null +++ b/images/white.png Binary files differ diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..adf5eeb --- /dev/null +++ b/main.cpp @@ -0,0 +1,11 @@ +#include "PhaseWindow.h" + +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + PhaseWindow w; + w.show(); + return a.exec(); +} diff --git a/protocol/PhaseProtocolBM.cpp b/protocol/PhaseProtocolBM.cpp new file mode 100644 index 0000000..aa4f086 --- /dev/null +++ b/protocol/PhaseProtocolBM.cpp @@ -0,0 +1,78 @@ +#include "PhaseProtocolBM.h" +#include + +PhaseProtocolBM::PhaseProtocolBM(QObject *parent) : QObject(parent) +{ + +} + +PhaseProtocolBM::~PhaseProtocolBM() +{ + +} + +bool PhaseProtocolBM::parseMessureData(QByteArray rawData, PhaseDataDto * dataObj) +{ + // 获取帧头——帧计数 + QByteArray head = rawData.left(PHASE_FRAME_ID_LENGTH); + dataObj->frameId = QByteUtil::binToHexString(head); + + int j = 0; // 用于转换通道顺序 + + // 获取每个通道的测量数据 + for (int i = 1; i <= PHASE_MESSURE_CHANNEL; i++) + { + if (i <= 8) + { + j = 2 * i - 1; + + } else + { + j = 2 * (i - 8); + } + + QByteArray channelRaw = rawData.left(PHASE_MESSURE_SIZE * j + PHASE_FRAME_ID_LENGTH).right(PHASE_MESSURE_SIZE); + qulonglong channelRawData = QByteUtil::binToULong(channelRaw, 8); + + if (channelRawData == CALCULATE_OFFSET) + { + dataObj->channelActive.append("0"); + dataObj->channelData.append(0.00); + dataObj->channelDataStr.append("0.00"); + } else + { + double phase = (channelRawData - CALCULATE_OFFSET) * CALCULATE_FACTOR; + dataObj->channelActive.append("1"); + dataObj->channelData.append(phase); + dataObj->channelDataStr.append(QString::number(phase, 'f', 12)); + } + } + + return true; +} + +QString PhaseProtocolBM::startMessure() +{ + return "$START*"; +} +QString PhaseProtocolBM::stopMessure() +{ + return "$$STOP*"; +} + +bool PhaseProtocolBM::checkFrame(QByteArray rawData) +{ + // 帧长度小于最小的长度 + if (rawData.length() != PHASE_FRAM_LENGTH) + { + return false; + } + + // 帧尾不是0xEEEEEEEE + if (rawData.mid(rawData.length() - PHASE_FRAME_TAIL.size()) != PHASE_FRAME_TAIL) + { + return false; + } + + return true; +} diff --git a/protocol/PhaseProtocolBM.h b/protocol/PhaseProtocolBM.h new file mode 100644 index 0000000..048a9c2 --- /dev/null +++ b/protocol/PhaseProtocolBM.h @@ -0,0 +1,36 @@ +#ifndef PHASEPROTOCOLBM_H +#define PHASEPROTOCOLBM_H + +#include + +#include "dto/PhaseDataDto.h" +#include "common/utils/QByteUtil.h" + +static const QByteArray PHASE_FRAME_TAIL("\xEE\xEE\xEE\xEE", 4); // 帧尾 + +static const int PHASE_FRAME_ID_LENGTH = 4; // 帧头id计数器为4个字节 +static const int PHASE_MESSURE_CHANNEL = 16; +static const int PHASE_MESSURE_SIZE = 8; +static const int PHASE_FRAM_LENGTH = PHASE_FRAME_ID_LENGTH + PHASE_FRAME_TAIL.size() + + PHASE_MESSURE_CHANNEL * PHASE_MESSURE_SIZE; + +static const qulonglong CALCULATE_OFFSET = 0X0080000000000000; +static const double CALCULATE_FACTOR = 1.6810E-15; + +class PhaseProtocolBM : public QObject +{ +public: + explicit PhaseProtocolBM(QObject *parent = nullptr); + ~PhaseProtocolBM(); + + // 解析比相仪测量数据 + static bool parseMessureData(QByteArray rawData, PhaseDataDto * phaseData); + + static QString startMessure(); + static QString stopMessure(); + + // 检测帧格式,帧头帧尾 + static bool checkFrame(QByteArray rawData); +}; + +#endif // PHASEROTOCOLBM_H diff --git a/protocol/dto/PhaseDataDto.cpp b/protocol/dto/PhaseDataDto.cpp new file mode 100644 index 0000000..5163335 --- /dev/null +++ b/protocol/dto/PhaseDataDto.cpp @@ -0,0 +1,21 @@ +#include "PhaseDataDto.h" + +PhaseDataDto::PhaseDataDto(QObject *parent) : QObject(parent) +{ + +} + +QJsonObject PhaseDataDto::toJSON(int i) +{ + QJsonObject jsonObj; + + QJsonObject dataObj; + dataObj.insert("dataValue", this->channelDataStr.at(i)); + dataObj.insert("frameId", this->frameId); + + jsonObj.insert("channelNo", (i + 1)); + jsonObj.insert("ts", this->milisecond); + jsonObj.insert("data", dataObj); + + return jsonObj; +} diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/PhaseWindow.h b/PhaseWindow.h new file mode 100644 index 0000000..02a7908 --- /dev/null +++ b/PhaseWindow.h @@ -0,0 +1,47 @@ +#ifndef PHASEWINDOW_H +#define PHASEWINDOW_H + +#include +#include +#include +#include + +#include "PhaseDevice.h" +#include "common/utils/SettingConfig.h" +#include "common/HttpRequestController.h" + +namespace Ui { +class PhaseWindow; +} + +class PhaseWindow : public QWidget +{ + Q_OBJECT + +public: + explicit PhaseWindow(QWidget *parent = nullptr); + ~PhaseWindow(); + +public slots: + void drawPhaseDataOnPage(PhaseDataDto * phaseData); + +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + +private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + + Ui::PhaseWindow *ui; + + HttpRequestController * httpReq; + + QList deviceList; + + void generateWidgetForDevice(); +}; + +#endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui new file mode 100644 index 0000000..97edbe1 --- /dev/null +++ b/PhaseWindow.ui @@ -0,0 +1,712 @@ + + + PhaseWindow + + + + 0 + 0 + 1366 + 720 + + + + + 1366 + 0 + + + + 比相仪测量软件 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 1300 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 100 + 0 + 200 + 41 + + + + + 微软雅黑 + 14 + + + + 比相仪测量软件 + + + + + + 0 + 90 + 1371 + 16 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 1250 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + 1200 + 10 + 40 + 40 + + + + + + + 配置 + + + + + + 40 + 40 + 141 + 51 + + + + + 微软雅黑 + 14 + 75 + true + + + + Qt::RightToLeft + + + 2021-12-10 +10:00:00 + + + Qt::AlignCenter + + + + + + 230 + 35 + 941 + 40 + + + + + 1 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + 230 + 65 + 941 + 30 + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/common/ConstCache.h b/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/common/HttpRequestController.cpp b/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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++) + { + 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(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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; + + return resultObj; +} diff --git a/common/HttpRequestController.h b/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/common/common.pri b/common/common.pri new file mode 100644 index 0000000..84f57ae --- /dev/null +++ b/common/common.pri @@ -0,0 +1,20 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/common/utils/DefHead.h b/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/common/utils/HttpRequestUtil.cpp b/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/common/utils/HttpRequestUtil.h b/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/common/utils/MD5.cpp b/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/common/utils/MD5.h b/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/common/utils/QByteUtil.cpp b/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/common/utils/QByteUtil.h b/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/common/utils/QKafkaUtil.cpp b/common/utils/QKafkaUtil.cpp new file mode 100644 index 0000000..0cd1639 --- /dev/null +++ b/common/utils/QKafkaUtil.cpp @@ -0,0 +1,68 @@ +#include "QKafkaUtil.h" +#include "SettingConfig.h" +#include + +QKafkaUtil::QKafkaUtil(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaUtil::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaUtil::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaUtil::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + if (SettingConfig::getInstance().NEED_SASL == 1) + { + conf->set("sasl.username", SettingConfig::getInstance().SASL_USERNAME.toStdString(), errStr); + conf->set("sasl.password", SettingConfig::getInstance().SASL_PASSWORD.toStdString(), errStr); + conf->set("security.protocol", "sasl_plaintext", errStr); + conf->set("sasl.mechanisms", "PLAIN", errStr); + } + + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaUtil::produceMessage(QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/common/utils/QKafkaUtil.h b/common/utils/QKafkaUtil.h new file mode 100644 index 0000000..289ea6f --- /dev/null +++ b/common/utils/QKafkaUtil.h @@ -0,0 +1,33 @@ +#ifndef QKAFKAUTIL_H +#define QKAFKAUTIL_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaUtil : public QObject +{ + Q_OBJECT +public: + explicit QKafkaUtil(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAUTIL_H diff --git a/common/utils/QLogUtil.cpp b/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +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/common/utils/QLogUtil.h b/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + 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: + +}; + +#endif // QLOGUTIL_H diff --git a/common/utils/QSerialPortUtil.cpp b/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..64da0f7 --- /dev/null +++ b/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,77 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + + if (open == true) + { + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); + + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000); + } +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + if (this->open == true) + { + std::cout << data.toStdString() << std::endl; + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData() +{ + QDateTime now = QDateTime::currentDateTime(); + + QString frameId = now.toString("HHmmsszzz"); + + QByteArray buffer; + buffer.append(QByteUtil::hexStringToBytes(frameId.mid(0, 8))); + + for (int i = 1; i <= 16; i++) + { + int value = qrand() % 10000; + buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); + } + + buffer.append(QByteUtil::hexStringToBytes("EEEEEEEE")); + + emit dataRecieved(buffer); +} diff --git a/common/utils/QSerialPortUtil.h b/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..accf403 --- /dev/null +++ b/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open; + + void mockReceivData(); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/common/utils/SettingConfig.cpp b/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..9a84a43 --- /dev/null +++ b/common/utils/SettingConfig.cpp @@ -0,0 +1,29 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + BAUD_RATE = getProperty("com", "baudRate").toInt(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + NEED_SASL = getProperty("kafka", "needSasl").toInt(); + SASL_USERNAME = getProperty("kafka", "saslUsername").toString(); + SASL_PASSWORD = getProperty("kafka", "saslPassword").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/common/utils/SettingConfig.h b/common/utils/SettingConfig.h new file mode 100644 index 0000000..0038ecc --- /dev/null +++ b/common/utils/SettingConfig.h @@ -0,0 +1,53 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + int BAUD_RATE; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + int NEED_SASL; + QString SASL_USERNAME; + QString SASL_PASSWORD; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..46d97d7 --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,20 @@ +[com] +baudRate=115200 + +[kafka] +needKafka=1 +brokers="111.198.10.15:12502" +dataTopic="cppTest" +needSasl=0 +sasl.username="admin" +sasl.password="casicss" + +[client] +clientId="phase" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="/home/admin/Qt/ZXSSCJ-Release/PhaseCompAcq/logs/" diff --git a/images.qrc b/images.qrc new file mode 100644 index 0000000..0fc1f3e --- /dev/null +++ b/images.qrc @@ -0,0 +1,6 @@ + + + images/white.png + images/green.png + + diff --git a/images/green.png b/images/green.png new file mode 100644 index 0000000..a33ee4b --- /dev/null +++ b/images/green.png Binary files differ diff --git a/images/white.png b/images/white.png new file mode 100644 index 0000000..337df06 --- /dev/null +++ b/images/white.png Binary files differ diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..adf5eeb --- /dev/null +++ b/main.cpp @@ -0,0 +1,11 @@ +#include "PhaseWindow.h" + +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + PhaseWindow w; + w.show(); + return a.exec(); +} diff --git a/protocol/PhaseProtocolBM.cpp b/protocol/PhaseProtocolBM.cpp new file mode 100644 index 0000000..aa4f086 --- /dev/null +++ b/protocol/PhaseProtocolBM.cpp @@ -0,0 +1,78 @@ +#include "PhaseProtocolBM.h" +#include + +PhaseProtocolBM::PhaseProtocolBM(QObject *parent) : QObject(parent) +{ + +} + +PhaseProtocolBM::~PhaseProtocolBM() +{ + +} + +bool PhaseProtocolBM::parseMessureData(QByteArray rawData, PhaseDataDto * dataObj) +{ + // 获取帧头——帧计数 + QByteArray head = rawData.left(PHASE_FRAME_ID_LENGTH); + dataObj->frameId = QByteUtil::binToHexString(head); + + int j = 0; // 用于转换通道顺序 + + // 获取每个通道的测量数据 + for (int i = 1; i <= PHASE_MESSURE_CHANNEL; i++) + { + if (i <= 8) + { + j = 2 * i - 1; + + } else + { + j = 2 * (i - 8); + } + + QByteArray channelRaw = rawData.left(PHASE_MESSURE_SIZE * j + PHASE_FRAME_ID_LENGTH).right(PHASE_MESSURE_SIZE); + qulonglong channelRawData = QByteUtil::binToULong(channelRaw, 8); + + if (channelRawData == CALCULATE_OFFSET) + { + dataObj->channelActive.append("0"); + dataObj->channelData.append(0.00); + dataObj->channelDataStr.append("0.00"); + } else + { + double phase = (channelRawData - CALCULATE_OFFSET) * CALCULATE_FACTOR; + dataObj->channelActive.append("1"); + dataObj->channelData.append(phase); + dataObj->channelDataStr.append(QString::number(phase, 'f', 12)); + } + } + + return true; +} + +QString PhaseProtocolBM::startMessure() +{ + return "$START*"; +} +QString PhaseProtocolBM::stopMessure() +{ + return "$$STOP*"; +} + +bool PhaseProtocolBM::checkFrame(QByteArray rawData) +{ + // 帧长度小于最小的长度 + if (rawData.length() != PHASE_FRAM_LENGTH) + { + return false; + } + + // 帧尾不是0xEEEEEEEE + if (rawData.mid(rawData.length() - PHASE_FRAME_TAIL.size()) != PHASE_FRAME_TAIL) + { + return false; + } + + return true; +} diff --git a/protocol/PhaseProtocolBM.h b/protocol/PhaseProtocolBM.h new file mode 100644 index 0000000..048a9c2 --- /dev/null +++ b/protocol/PhaseProtocolBM.h @@ -0,0 +1,36 @@ +#ifndef PHASEPROTOCOLBM_H +#define PHASEPROTOCOLBM_H + +#include + +#include "dto/PhaseDataDto.h" +#include "common/utils/QByteUtil.h" + +static const QByteArray PHASE_FRAME_TAIL("\xEE\xEE\xEE\xEE", 4); // 帧尾 + +static const int PHASE_FRAME_ID_LENGTH = 4; // 帧头id计数器为4个字节 +static const int PHASE_MESSURE_CHANNEL = 16; +static const int PHASE_MESSURE_SIZE = 8; +static const int PHASE_FRAM_LENGTH = PHASE_FRAME_ID_LENGTH + PHASE_FRAME_TAIL.size() + + PHASE_MESSURE_CHANNEL * PHASE_MESSURE_SIZE; + +static const qulonglong CALCULATE_OFFSET = 0X0080000000000000; +static const double CALCULATE_FACTOR = 1.6810E-15; + +class PhaseProtocolBM : public QObject +{ +public: + explicit PhaseProtocolBM(QObject *parent = nullptr); + ~PhaseProtocolBM(); + + // 解析比相仪测量数据 + static bool parseMessureData(QByteArray rawData, PhaseDataDto * phaseData); + + static QString startMessure(); + static QString stopMessure(); + + // 检测帧格式,帧头帧尾 + static bool checkFrame(QByteArray rawData); +}; + +#endif // PHASEROTOCOLBM_H diff --git a/protocol/dto/PhaseDataDto.cpp b/protocol/dto/PhaseDataDto.cpp new file mode 100644 index 0000000..5163335 --- /dev/null +++ b/protocol/dto/PhaseDataDto.cpp @@ -0,0 +1,21 @@ +#include "PhaseDataDto.h" + +PhaseDataDto::PhaseDataDto(QObject *parent) : QObject(parent) +{ + +} + +QJsonObject PhaseDataDto::toJSON(int i) +{ + QJsonObject jsonObj; + + QJsonObject dataObj; + dataObj.insert("dataValue", this->channelDataStr.at(i)); + dataObj.insert("frameId", this->frameId); + + jsonObj.insert("channelNo", (i + 1)); + jsonObj.insert("ts", this->milisecond); + jsonObj.insert("data", dataObj); + + return jsonObj; +} diff --git a/protocol/dto/PhaseDataDto.h b/protocol/dto/PhaseDataDto.h new file mode 100644 index 0000000..0317a83 --- /dev/null +++ b/protocol/dto/PhaseDataDto.h @@ -0,0 +1,31 @@ +#ifndef PHASEDATADTO_H +#define PHASEDATADTO_H + +#include +#include +#include + +class PhaseDataDto : public QObject +{ + Q_OBJECT +public: + explicit PhaseDataDto(QObject *parent = nullptr); + + QString frameId; // 帧id + QString timestamp; // 时间戳字符串 + qlonglong milisecond; // 毫秒计数 + QByteArray rawFrame; // 原始帧字节数组 + + QString devCode; + QString devStatus; + QList channelActive; + QList channelData; + QList channelDataStr; + + QJsonObject toJSON(int i); + +signals: + +}; + +#endif // PHASEDATADTO_H diff --git a/ChannelItem.cpp b/ChannelItem.cpp new file mode 100644 index 0000000..8e66b15 --- /dev/null +++ b/ChannelItem.cpp @@ -0,0 +1,14 @@ +#include "ChannelItem.h" +#include "ui_ChannelItem.h" + +ChannelItem::ChannelItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChannelItem) +{ + ui->setupUi(this); +} + +ChannelItem::~ChannelItem() +{ + delete ui; +} diff --git a/ChannelItem.h b/ChannelItem.h new file mode 100644 index 0000000..3ccd5e3 --- /dev/null +++ b/ChannelItem.h @@ -0,0 +1,22 @@ +#ifndef CHANNELITEM_H +#define CHANNELITEM_H + +#include + +namespace Ui { +class ChannelItem; +} + +class ChannelItem : public QWidget +{ + Q_OBJECT + +public: + explicit ChannelItem(QWidget *parent = nullptr); + ~ChannelItem(); + +private: + Ui::ChannelItem *ui; +}; + +#endif // CHANNELITEM_H diff --git a/ChannelItem.ui b/ChannelItem.ui new file mode 100644 index 0000000..897632a --- /dev/null +++ b/ChannelItem.ui @@ -0,0 +1,660 @@ + + + ChannelItem + + + + 0 + 0 + 1300 + 160 + + + + + 0 + 160 + + + + Form + + + + + 430 + 0 + 81 + 20 + + + + + 微软雅黑 + 12 + + + + 稳定度 + + + + + + 1170 + 0 + 101 + 20 + + + + + 微软雅黑 + 12 + + + + 通道操作 + + + + + + 430 + 50 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 1 + + + + + + + + 微软雅黑 + 12 + + + + 4.78e-13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52262 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 1.47e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 52 + + + Qt::AlignCenter + + + + + + + + + 430 + 85 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 10 + + + + + + + + 微软雅黑 + 12 + + + + 6.38e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5226 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + 1000 + + + + + + + + 微软雅黑 + 12 + + + + 4.45e-15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 5 + + + Qt::AlignCenter + + + + + + + + + 430 + 120 + 681 + 35 + + + + + + + + 微软雅黑 + 12 + + + + 100 + + + + + + + + 微软雅黑 + 12 + + + + 1.65e-14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 522 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 372 + 20 + + + + + + + + + + 1160 + 30 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 查看曲线 + + + + + + 1160 + 70 + 101 + 35 + + + + + 微软雅黑 + 11 + 50 + false + + + + 清除数据 + + + + + + 60 + 10 + 101 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 测量数据: + + + + + + + + 微软雅黑 + 12 + + + + 时延补偿: + + + + + + + + 微软雅黑 + 12 + + + + 补偿后值: + + + + + + + + 微软雅黑 + 12 + + + + 准确度: + + + + + + + + + 190 + 10 + 171 + 160 + + + + + + + + 微软雅黑 + 12 + + + + 3.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.00e-12 + + + + + + + + 微软雅黑 + 12 + + + + 4.61751e-12s + + + + + + + + 微软雅黑 + 12 + + + + 1.02e-15 + + + + + + + + + 430 + 20 + 681 + 41 + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 80 + 20 + + + + + + + + + 微软雅黑 + 12 + + + + Tau(s) + + + + + + + + 微软雅黑 + 12 + + + + Allen方差 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 12 + + + + 采样数 + + + Qt::AlignCenter + + + + + + + + + diff --git a/PhaseDevice.cpp b/PhaseDevice.cpp new file mode 100644 index 0000000..90f1b4d --- /dev/null +++ b/PhaseDevice.cpp @@ -0,0 +1,142 @@ +#include "PhaseDevice.h" +#include +#include + +PhaseDevice::PhaseDevice(QObject *parent) : QObject(parent) +{ + connect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); + +// kafkaUtil.setBrokers(SettingConfig::getInstance().KAFKA_BROKERS); +// kafkaUtil.setTopic(SettingConfig::getInstance().KAFKA_DATA_TOPIC); +// kafkaUtil.createProducer(); +} + +PhaseDevice::~PhaseDevice() +{ + disconnect(&this->serialUtil, &QSerialPortUtil::dataRecieved, + this, &PhaseDevice::dataReceivedHandler); +} + +void PhaseDevice::setComName(QString comName) +{ + this->comName = comName; +} +void PhaseDevice::setBaudRate(int baudRate) +{ + this->baudRate = baudRate; +} +QString PhaseDevice::getDevCode() +{ + return this->devCode; +} +void PhaseDevice::setDevCode(QString devCode) +{ + this->devCode = devCode; +} +void PhaseDevice::setDeviceId(QString deviceId) +{ + this->deviceId = deviceId; +} + +bool PhaseDevice::isSerialOpen() +{ + return this->serialUtil.isOpen(); +} + +void PhaseDevice::initSerialPort() +{ + this->serialUtil.openSerialPort(this->comName, this->baudRate); +} + +void PhaseDevice::startWork() +{ + QString startCommand = PhaseProtocolBM::startMessure(); + this->serialUtil.sendData(startCommand.toLocal8Bit()); +} + +void PhaseDevice::stopWork() +{ + +} + +void PhaseDevice::dataReceivedHandler(QByteArray data) +{ + this->dataBuff.append(data); + + std::cout << QByteUtil::binToHexString(this->dataBuff).toStdString() << std::endl; + + PhaseDataDto * phaseData = new PhaseDataDto(this); + if (PhaseProtocolBM::checkFrame(this->dataBuff) == true) + { + phaseData->rawFrame = this->dataBuff; + + // ★解析成数据对象 + bool parse = PhaseProtocolBM::parseMessureData(this->dataBuff, phaseData); + + // 解析成功 + if (parse == true) + { + QDateTime now = QDateTime::currentDateTime(); + phaseData->devCode = this->devCode; + phaseData->timestamp = now.toString("yyyy-MM-dd HH:mm:ss.zzz"); + phaseData->milisecond = now.toMSecsSinceEpoch(); + this->afterFramePhase(phaseData); + } + } else if (this->dataBuff.size() > PHASE_FRAM_LENGTH) + { + std::cout << QString("%1").arg(this->dataBuff.size()).toStdString() << std::endl; + this->dataBuff.clear(); + } + + // 在此处释放内存,不影响后续显示 + // 不在此处释放内存则会导致内存持续增加 + // 具体原因不明 + delete phaseData; +} + +void PhaseDevice::afterFramePhase(PhaseDataDto * phaseData) +{ + // 1. 清空dataBuff,等待下一帧的数据 + this->dataBuff.clear(); + + // 2. 输出到日志文件中 + QString date = phaseData->timestamp.mid(0, 10); + + // 2.1 原始字节数组数据 + QString filename = "raw_" + devCode + ".log"; + QString content = phaseData->timestamp + " " + QByteUtil::binToHexString(phaseData->rawFrame); + QLogUtil::writeRawDataLogByDate(date, filename, content); + + // 2.2 各个通道的相差数据 + for (int i = 1; i <= phaseData->channelActive.size(); i++) + { + if (phaseData->channelActive.at(i-1).toUInt() == 1) + { + QString chFilename("%1_CH_%2.log"); + chFilename = chFilename.arg(devCode); + if (i < 10) + { + chFilename = chFilename.arg(QString("0%1").arg(i)); + } else + { + chFilename = chFilename.arg(i); + } + QString channelDataStr = QString("%1 [%2] %3").arg(phaseData->timestamp).arg(phaseData->frameId).arg(phaseData->channelDataStr.at(i-1)); + + QLogUtil::writeChannelDataLogByDate(date, chFilename, channelDataStr); + + // 3. 输出到中间件,执行后续处理过程 + if (SettingConfig::getInstance().NEED_KAFKA == 1) + { + QJsonObject jsonObj = phaseData->toJSON(i - 1); + jsonObj.insert("clientId", SettingConfig::getInstance().CLIENT_ID); + jsonObj.insert("deviceId", deviceId); +// kafkaUtil.produceMessage(QString(QJsonDocument(jsonObj).toJson(QJsonDocument::Compact))); + } + } + } + + // 4. 在界面上简单显示相差数据结果 + emit this->sendDataToDraw(phaseData); +} diff --git a/PhaseDevice.h b/PhaseDevice.h new file mode 100644 index 0000000..aa7d822 --- /dev/null +++ b/PhaseDevice.h @@ -0,0 +1,49 @@ +#ifndef PHASEDEVICE_H +#define PHASEDEVICE_H + +#include +#include "common/utils/QSerialPortUtil.h" +#include "common/utils/QLogUtil.h" +#include "common/utils/SettingConfig.h" +//#include "common/utils/QKafkaUtil.h" +#include "protocol/PhaseProtocolBM.h" + +class PhaseDevice : public QObject +{ + Q_OBJECT +public: + explicit PhaseDevice(QObject *parent = nullptr); + ~PhaseDevice(); + + void initSerialPort(); + void startWork(); + void stopWork(); + + void afterFramePhase(PhaseDataDto * phaseData); + + 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; + + QSerialPortUtil serialUtil; +// QKafkaUtil kafkaUtil; + QByteArray dataBuff; + +signals: + void sendDataToDraw(PhaseDataDto * phaseData); + +public slots: + void dataReceivedHandler(QByteArray data); + +}; + +#endif // PHASEDEVICE_H diff --git a/PhaseMeasure.pro b/PhaseMeasure.pro new file mode 100644 index 0000000..dc1c3b6 --- /dev/null +++ b/PhaseMeasure.pro @@ -0,0 +1,35 @@ +QT += core gui serialport network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +FORMS += \ + ChannelItem.ui \ + PhaseWindow.ui + +include(common/common.pri) +include(protocol/protocol.pri) + +HEADERS += PhaseDevice.h \ + ChannelItem.h +HEADERS += PhaseWindow.h + +SOURCES += PhaseDevice.cpp \ + ChannelItem.cpp +SOURCES += PhaseWindow.cpp +SOURCES += main.cpp + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +#unix:!macx: LIBS += -L$$PWD/lib/librdkafka/ -lrdkafka -lrdkafka++ +#INCLUDEPATH += $$PWD/include/librdkafka +#DEPENDPATH += $$PWD/include/librdkafka + +DISTFILES += conf/config.ini + +RESOURCES += \ + images.qrc diff --git a/PhaseMeasure.pro.user b/PhaseMeasure.pro.user new file mode 100644 index 0000000..5658fcc --- /dev/null +++ b/PhaseMeasure.pro.user @@ -0,0 +1,562 @@ + + + + + + EnvironmentId + {58895c32-e1e9-4248-b30e-d2ac0dfba9c9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 0 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MinGW 32-bit + Desktop Qt 5.14.2 MinGW 32-bit + qt.qt5.5142.win32_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + E:/workspace/ZXSSCJ/PhaseMeasure/PhaseMeasure.pro + + false + + false + true + true + false + false + true + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MinGW 64-bit + Desktop Qt 5.14.2 MinGW 64-bit + qt.qt5.5142.win64_mingw73_kit + 0 + 0 + 0 + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + E:/workspace/ZXSSCJ/build-PhaseMeasure-Desktop_Qt_5_14_2_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/PhaseWindow.cpp b/PhaseWindow.cpp new file mode 100644 index 0000000..27af4fc --- /dev/null +++ b/PhaseWindow.cpp @@ -0,0 +1,143 @@ +#include "PhaseWindow.h" +#include "ui_PhaseWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PhaseWindow::PhaseWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhaseWindow) +{ + ui->setupUi(this); + + // 无边框 + this->setWindowFlags(Qt::FramelessWindowHint); + + // 窗口大小为占满一屏 + QRect screenRect = QApplication::desktop()->screenGeometry(); + resize(screenRect.width(), screenRect.height()); + + // 将窗口移动到左上角 + move(0, 0); + ui->exitButt->move(screenRect.width() - 80, 10); + ui->minButt->move(screenRect.width() - 140, 10); + ui->settingButt->move(screenRect.width() - 200, 10); + ui->line->setGeometry(0, 89, screenRect.width(), 1); + ui->pointsList->setGeometry(250,30,screenRect.width()-500,40); + ui->labelsList->setGeometry(250,60,screenRect.width()-500,30); + + // 设置主体区域的大小和位置 + ui->scrollArea->setGeometry(0, 90, screenRect.width(), screenRect.height() - 90); + ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + +// httpReq = new HttpRequestController(this); +// // 1. 获取访问接口需要的token +// int retCode = this->initHttpToken(); +// if (retCode != 200) +// { +// QMessageBox::information(this, "错误", "获取http请求的token失败,程序即将退出"); + +// QTimer::singleShot(1000, qApp, SLOT(quit())); +// } + // 2. 获取字典值:设备类型 +// retCode = this->initDictDeviceTypes(); + + this->generateWidgetForDevice(); +} + +PhaseWindow::~PhaseWindow() +{ + delete ui; +} + +void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData) +{ + // 当前显示的设备编号 +// QString currentDevCode = ui->devSelect->currentData().toString(); + + // 如果不是当前设备的帧,直接返回 +// if (phaseData->devCode != currentDevCode) +// { +// return; +// } + + // 更新所有通道BOX的值 + for (int i = 0; i < phaseData->channelActive.size(); i++) + { + // 获取对应的通道BOX + QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1); + + // 赋值,对应的lineEdit/label + ((QLineEdit *)channelBox->children().at(2))->setText(phaseData->timestamp); + ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); + ((QLineEdit *)channelBox->children().at(6))->setText(phaseData->frameId); + ((QLabel *)channelBox->children().at(7))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); + } +} + +void PhaseWindow::generateWidgetForDevice() +{ + // 获取设备数据 + int channelNum = 16; + + QRect screenRect = QApplication::desktop()->screenGeometry(); + + ui->scrollContents->setGeometry(0, 90, screenRect.width(), channelNum * 170); + + QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents); + const QFont labelFont("微软雅黑", 10); + + for (int i = 0; i < channelNum; i++) + { + QGroupBox * group = new QGroupBox(ui->scrollContents); + group->setTitle(QString("通道 - %1").arg(i + 1)); + group->setFont(QFont("微软雅黑", 12)); + group->setGeometry(20, i * 160 + 10, screenRect.width() - 40, 160); + + QHBoxLayout * vbox = new QHBoxLayout(group); + ChannelItem *widget=new ChannelItem(); + widget->setGeometry(10, 0, screenRect.width() - 60, 160); + + vbox->addWidget(widget); + group->setLayout(vbox); + layout->addWidget(group); + + + } +} + +int PhaseWindow::initHttpToken() +{ + QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID, + SettingConfig::getInstance().APP_KEY); + return response.find("code")->toInt(); +} +int PhaseWindow::initDictDeviceTypes() +{ + QJsonObject response = httpReq->initDictDeviceType(); + return response.find("code")->toInt(); +} +QJsonObject PhaseWindow::initDeviceList() +{ + QJsonObject response = httpReq->initDeviceList("比相仪"); + return response; +} + +void PhaseWindow::on_minButt_clicked() +{ + setWindowState(Qt::WindowMinimized | windowState()); +} + +void PhaseWindow::on_exitButt_clicked() +{ + QApplication::exit(0); +} diff --git a/PhaseWindow.h b/PhaseWindow.h new file mode 100644 index 0000000..02a7908 --- /dev/null +++ b/PhaseWindow.h @@ -0,0 +1,47 @@ +#ifndef PHASEWINDOW_H +#define PHASEWINDOW_H + +#include +#include +#include +#include + +#include "PhaseDevice.h" +#include "common/utils/SettingConfig.h" +#include "common/HttpRequestController.h" + +namespace Ui { +class PhaseWindow; +} + +class PhaseWindow : public QWidget +{ + Q_OBJECT + +public: + explicit PhaseWindow(QWidget *parent = nullptr); + ~PhaseWindow(); + +public slots: + void drawPhaseDataOnPage(PhaseDataDto * phaseData); + +private slots: + void on_minButt_clicked(); + + void on_exitButt_clicked(); + +private: + int initHttpToken(); + int initDictDeviceTypes(); + QJsonObject initDeviceList(); + + Ui::PhaseWindow *ui; + + HttpRequestController * httpReq; + + QList deviceList; + + void generateWidgetForDevice(); +}; + +#endif // PHASEWINDOW_H diff --git a/PhaseWindow.ui b/PhaseWindow.ui new file mode 100644 index 0000000..97edbe1 --- /dev/null +++ b/PhaseWindow.ui @@ -0,0 +1,712 @@ + + + PhaseWindow + + + + 0 + 0 + 1366 + 720 + + + + + 1366 + 0 + + + + 比相仪测量软件 + + + + + 0 + 0 + 100 + 30 + + + + + 微软雅黑 + 10 + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 100 + 30 + + + + + + + + 1300 + 10 + 40 + 40 + + + + + + + 退出 + + + + + + 100 + 0 + 200 + 41 + + + + + 微软雅黑 + 14 + + + + 比相仪测量软件 + + + + + + 0 + 90 + 1371 + 16 + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + 1250 + 10 + 40 + 40 + + + + + + + 最小化 + + + + + + 1200 + 10 + 40 + 40 + + + + + + + 配置 + + + + + + 40 + 40 + 141 + 51 + + + + + 微软雅黑 + 14 + 75 + true + + + + Qt::RightToLeft + + + 2021-12-10 +10:00:00 + + + Qt::AlignCenter + + + + + + 230 + 35 + 941 + 40 + + + + + 1 + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/white.png + + + Qt::AlignCenter + + + + + + + + + + :/points/images/green.png + + + Qt::AlignCenter + + + + + + + + + 230 + 65 + 941 + 30 + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 1 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 2 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 3 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 4 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 5 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 6 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 7 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 8 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 9 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 10 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 11 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 12 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 13 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 14 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 15 + + + Qt::AlignCenter + + + + + + + + 微软雅黑 + 10 + + + + Qt::LeftToRight + + + 16 + + + Qt::AlignCenter + + + + + + + + + + + diff --git a/common/ConstCache.h b/common/ConstCache.h new file mode 100644 index 0000000..6cc831b --- /dev/null +++ b/common/ConstCache.h @@ -0,0 +1,30 @@ +#ifndef CONSTCACHE_H +#define CONSTCACHE_H + +#include +#include +#include +#include + +class ConstCache : public QObject +{ + Q_OBJECT +public: + ~ConstCache() {}; + ConstCache(const ConstCache&)=delete; + ConstCache& operator=(const ConstCache&)=delete; + + static ConstCache& getInstance() { + static ConstCache instance; + return instance; + } + + QMap deviceTypes; + QList deviceList; + +private: + ConstCache() {}; + +}; + +#endif // CONSTCACHE_H diff --git a/common/HttpRequestController.cpp b/common/HttpRequestController.cpp new file mode 100644 index 0000000..6abb5af --- /dev/null +++ b/common/HttpRequestController.cpp @@ -0,0 +1,155 @@ +#include "HttpRequestController.h" + +HttpRequestController::HttpRequestController(QObject *parent) : QObject(parent) +{ + httpUtil = new HttpRequestUtil(this); + baseUrl = SettingConfig::getInstance().getProperty("http", "baseUrl").toString(); + system = SettingConfig::getInstance().getProperty("client", "clientId").toString(); +} + +QJsonObject HttpRequestController::getTokenByClientId(QString clientId, QString key) +{ + QJsonObject resultObj; + + // 获取token的url地址 + QUrl url = baseUrl + "/getTokenByClientId"; + + // 请求对象 + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + + // 生成随机数作为salt + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + float random = (qrand() % 10000) / (float)10000; + QString salt = QByteUtil::binToHexString(QByteUtil::floatToBytes(random)); + QString clientSecret = clientId + "_" + key + "_" + salt; + + // MD5加密clientSecret + char secretEn[CHAR_MD5_LEN]; + MD5::MD5Encode(clientSecret.toStdString().data(), clientSecret.length(), secretEn); + QString secretMD5(secretEn); + + QJsonObject paramObj; + paramObj.insert("clientId", clientId); + paramObj.insert("salt", salt); + paramObj.insert("clientSecret", secretMD5); + QJsonDocument document; + document.setObject(paramObj); + QByteArray content = document.toJson(QJsonDocument::Compact); + + QNetworkReply * reply = httpUtil->sendPostRequest(request, content); + + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + if(jsonDocument.isNull() == false) { + resultObj = jsonDocument.object(); + + if (resultObj.find("code")->toInt() == 200) + { + QString token = resultObj.find("data")->toString(); + this->token = token; + } + } else + { + resultObj.insert("code", -1); + } + + return resultObj; +} + +QJsonObject HttpRequestController::initDictDeviceType() +{ + QJsonObject resultObj; + + // 获取字典值的接口地址 + QUrl url = baseUrl + "/sys/dict/code/deviceType"; + + // + QNetworkRequest request; + request.setUrl(url); + + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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++) + { + 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(QString devType) +{ + QJsonObject resultObj; + + QString counterDevType = ""; + QMapIterator it(ConstCache::getInstance().deviceTypes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(devType) == true) + { + counterDevType = it.key(); + break; + } + } + + // 获取设备列表的接口地址 + QUrl url = baseUrl + "/device/list"; + QUrlQuery query; + query.addQueryItem("type", counterDevType); + url.setQuery(query); + + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("Content-type", "application/json"); + request.setRawHeader("token", token.toLocal8Bit()); + request.setRawHeader("system", system.toLocal8Bit()); + + QNetworkReply * reply = httpUtil->sendGetRequest(request); + const QByteArray reply_data = reply->readAll(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(reply_data); + 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; + + return resultObj; +} diff --git a/common/HttpRequestController.h b/common/HttpRequestController.h new file mode 100644 index 0000000..77fc3db --- /dev/null +++ b/common/HttpRequestController.h @@ -0,0 +1,35 @@ +#ifndef HTTPREQUESTCONTROLLER_H +#define HTTPREQUESTCONTROLLER_H + +#include +#include + +#include "utils/HttpRequestUtil.h" +#include "utils/SettingConfig.h" +#include "utils/MD5.h" +#include "utils/QByteUtil.h" +#include "ConstCache.h" + +class HttpRequestController : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestController(QObject *parent = nullptr); + + QJsonObject getTokenByClientId(QString clientId, QString key); + QJsonObject initDictDeviceType(); + QJsonObject initDeviceList(QString devType); + +private: + HttpRequestUtil * httpUtil; + + QString baseUrl; + + QString token; + QString system; + +signals: + +}; + +#endif // HTTPREQUESTCONTROLLER_H diff --git a/common/common.pri b/common/common.pri new file mode 100644 index 0000000..84f57ae --- /dev/null +++ b/common/common.pri @@ -0,0 +1,20 @@ + +SOURCES += $$PWD/utils/SettingConfig.cpp +SOURCES += $$PWD/utils/QByteUtil.cpp +SOURCES += $$PWD/utils/QSerialPortUtil.cpp +SOURCES += $$PWD/utils/QLogUtil.cpp +#SOURCES += $$PWD/utils/QKafkaUtil.cpp +SOURCES += $$PWD/utils/HttpRequestUtil.cpp +SOURCES += $$PWD/utils/MD5.cpp +SOURCES += $$PWD/HttpRequestController.cpp + +HEADERS += $$PWD/utils/SettingConfig.h +HEADERS += $$PWD/utils/QByteUtil.h +HEADERS += $$PWD/utils/QSerialPortUtil.h +HEADERS += $$PWD/utils/QLogUtil.h +#HEADERS += $$PWD/utils/QKafkaUtil.h +HEADERS += $$PWD/utils/HttpRequestUtil.h +HEADERS += $$PWD/utils/DefHead.h +HEADERS += $$PWD/utils/MD5.h +HEADERS += $$PWD/HttpRequestController.h +HEADERS += $$PWD/ConstCache.h diff --git a/common/utils/DefHead.h b/common/utils/DefHead.h new file mode 100644 index 0000000..2171b0e --- /dev/null +++ b/common/utils/DefHead.h @@ -0,0 +1,59 @@ +/***********************************************Copyright:Pluviophile******************************************/ +/**********************************************Email:1565203609@qq.com*****************************************/ +#pragma once + +#define _In_ +#define _Inout_ +#define SOCKET_ERROR -1 + +#define cu_long unsigned long +#define cu_char unsigned char +#define cu_int unsigned int +#define cu_short unsigned short + +#define __ERROR 0X00000 +#define __SUCCESS 0X00001 +//PE FILE DEFINE +#define __FILE_OPEN_ERROR 0X00002 +#define __FILE_READ_ERROR 0X00003 +#define __FILE_NO_PE 0X00004 +#define __FILE_NO_NT 0X00005 +#define __FILE_SAVE_ERROR 0X00006 +#define __FILE_WRITE_ERROR 0X00007 +#define __LASTSECTION_NO_NULL 0X00008 +#define __FILE_WRITESIZE_MISMATCH 0X00009 +#define __FILE_TOO_BIG 0X0000A + +#define __SECTION_SIZE 0X00028 + +#define __I386_FILE_MAX 0XFFFFFFFF + +//UDPSocket DEINE +#define __SOCK_WSAINIT_ERROR 0X0000B +#define __SOCK_INIT_ERROR __SOCK_WSAINIT_ERROR+1 +#define __SOCK_PORT_ERROR __SOCK_WSAINIT_ERROR+2 +#define __SOCK_IP_ERROR __SOCK_WSAINIT_ERROR+3 +#define __SOCK_LISTEN_ERROR __SOCK_WSAINIT_ERROR+4 +#define __SOCKET_CLOSE_ERROR __SOCK_WSAINIT_ERROR+5 +#define __SOCKET_LISTENNUM_TOOBIG __SOCK_WSAINIT_ERROR+6 +#define __SOCK_ACCEPT_ERROR __SOCK_WSAINIT_ERROR+7 +#define __SOCK_CONNECT_ERROR __SOCK_WSAINIT_ERROR+8 +#define __SOCK_IP_ISNULL __SOCK_WSAINIT_ERROR+9 +#define __SOCKET_NO_RECV __SOCK_WSAINIT_ERROR+10 +#define __SOCKET_SEND_ERROR __SOCK_WSAINIT_ERROR+11 +#define __SOCKET_RECV_ERROR __SOCK_WSAINIT_ERROR+12 + +//base64 +#define __BASE_NO_BASE64 0X00018 + +//SMTP +#define __SMTP_ERROR 0X00019 +#define __SMTP_HELO_ERROR __SMTP_ERROR+1 +#define __SMTP_AUTH_ERROR __SMTP_ERROR+2 +#define __SMTP_USERPASSWD_ERROR __SMTP_ERROR+3 +#define __SMTP_PASSWD_ERROR __SMTP_ERROR+4 +#define __SMTP_FROM_ERROR __SMTP_ERROR+5 +#define __SMTP_RECPTO_ERROR __SMTP_ERROR+6 +#define __SMTP_QUIT_ERROR __SMTP_ERROR+7 +#define __SMTP_DATAFLAG_ERROR __SMTP_ERROR+8 +#define __SMTP_EMAILSEND_ERROR __SMTP_ERROR+9 \ No newline at end of file diff --git a/common/utils/HttpRequestUtil.cpp b/common/utils/HttpRequestUtil.cpp new file mode 100644 index 0000000..e537083 --- /dev/null +++ b/common/utils/HttpRequestUtil.cpp @@ -0,0 +1,33 @@ +#include "HttpRequestUtil.h" + +HttpRequestUtil::HttpRequestUtil(QObject *parent) : QObject(parent) +{ + manager = new QNetworkAccessManager(this); +} + + +QNetworkReply * HttpRequestUtil::sendGetRequest(QNetworkRequest request) +{ + //发送请求 + QNetworkReply * reply = manager->get(request); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} + +QNetworkReply * HttpRequestUtil::sendPostRequest(QNetworkRequest request, QByteArray params) +{ + //发送请求 + QNetworkReply * reply = manager->post(request, params); + + // 同步等待 + QEventLoop eventLoop; + connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + + return reply; +} diff --git a/common/utils/HttpRequestUtil.h b/common/utils/HttpRequestUtil.h new file mode 100644 index 0000000..ee0478b --- /dev/null +++ b/common/utils/HttpRequestUtil.h @@ -0,0 +1,28 @@ +#ifndef HTTPREQUESTUTIL_H +#define HTTPREQUESTUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class HttpRequestUtil : public QObject +{ + Q_OBJECT +public: + explicit HttpRequestUtil(QObject *parent = nullptr); + + QNetworkAccessManager * manager; + + QNetworkReply * sendGetRequest(QNetworkRequest request); + QNetworkReply * sendPostRequest(QNetworkRequest request, QByteArray params); + +signals: + +}; + +#endif // HTTPREQUESTUTIL_H diff --git a/common/utils/MD5.cpp b/common/utils/MD5.cpp new file mode 100644 index 0000000..dc422ca --- /dev/null +++ b/common/utils/MD5.cpp @@ -0,0 +1,144 @@ +#include"MD5.h" + +MD5::MD5() +{ + nullptr; +} + +void MD5::MD5Encode +( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst +) +{ + //用于存放最终结果,以便转化为字符串 + short output[16]; + char dest[16]; + memset(dest, 0, SHORT_MD5_LEN); + memset(dst, 0, CHAR_MD5_LEN); + //四组幻数 + unsigned int h[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; + static const unsigned int k[64] = + { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + //四轮循环(GG,FF,HH,II)每轮循环每一步所要位移的位数 + static const unsigned int qz[] = + { + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + }; + //每一轮所要读取的元素下表 + static const unsigned int s[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 + }; + + unsigned int i = 0, j = 0; + //N*512+448 + //N=(数据长度+64(bit))/512(bit),长度+8是为了防止数据长度>=56 + //任意数据长度+64bit刚好是512倍数,最后+8空出存放数据原始长度的位置 + size_t n_len = ((len + 8) / 64) * 64 + 56 + 8; + unsigned char *n_text = (unsigned char *)malloc(n_len); + memset(n_text, 0x00, n_len); + memcpy(n_text, text, len); + //末尾添加二进制1000 0000 + n_text[len] = 0x80; + //追加长度 + //注意此处末尾添加的是一个64位的数据!!! + unsigned char len_s[8]; + memset(len_s, 0x00, 8); + unsigned long temp_len = 0x00000000; + temp_len = (unsigned long)(len * 8); + //此处注意,只拷贝4个字节数据,因为 + //unsigned long只有四个字节 + memcpy(len_s, &temp_len, 4); + memcpy(n_text + (n_len-8), len_s, 8); + + //每64字节(512位) + //处理一次,因为填充过后的数刚好是64的倍数 + for (j = 0; j < n_len; j += 64) + { + unsigned int H[4] = { 0,0,0,0 }; + memcpy(H, h, 4 * sizeof(unsigned int)); + //分段拷贝内容,以供处理多组数据 + unsigned char temp_text[64]; + memset(temp_text, 0x00, 64); + memcpy(temp_text, n_text + j, 64); + + //一共循环64次,分为四组 + for (i = 0; i < 64; i++) + { + //四组非线性函数运算,用开关语句来判断是第几组 + // 0~16第一组,16~32第二组 + //32~48第三组,48~64第四组 + unsigned int R = 0, f = 0, tmp = 0; + switch ((int)i / 16) + { + //H[1]=X,H[2]=Y,H[3]=Z + //F(X,Y,Z) + case 0: f = (H[1] & H[2]) | ((~H[1]) & H[3]); break; + //G(X,Y,Z) + case 1: f = (H[3] & H[1]) | (H[2] & (~H[3])); break; + //H(X,Y,Z) + case 2: f = H[1] ^ H[2] ^ H[3]; break; + //I + case 3: f = H[2] ^ (H[1] | (~H[3])); break; + } + //abcd分别交换位置 + tmp = H[3]; + H[3] = H[2]; + H[2] = H[1]; + //R=(a+?(bcd)+M?+ti),四个字节一运算不是一个字节 + R = H[0] + f + k[i] + (((unsigned int *)temp_text)[s[i]]); + //b+((a+?(bcd)+M?+ti)<> (32 - qz[i]))); + H[0] = tmp; + } + //每轮循环结束后,ABCD分别与abcd相加 + for (i = 0; i < 4; i++) h[i] += H[i]; + } + + free(n_text); + memcpy(dest, h, 16); + + //与0xff位与将高位的ff变为00 + for (int i = 0; i < 16; i++) + output[i] = dest[i] & 0xff; + //将十六进制数据打印成字符串 + for (int i = 0; i < SHORT_MD5_LEN; i++) + sprintf(dst + i * 2, "%02x", output[i]); +} + + +bool MD5::MD5StrValidate +( + _In_ const char * input1, + _In_ const char * input2 +) +{ + if (strcmp(input1, input2) == 0) + return true; + return false; +} diff --git a/common/utils/MD5.h b/common/utils/MD5.h new file mode 100644 index 0000000..5d86d32 --- /dev/null +++ b/common/utils/MD5.h @@ -0,0 +1,33 @@ +#ifndef MD5_H +#define MD5_H + +#include +#include +#include +#include"DefHead.h" + +#define SHORT_MD5_LEN 16 +#define CHAR_MD5_LEN 34 + + +class MD5 +{ +public: + explicit MD5(); + static void MD5Encode + ( + _In_ const char* text, + _In_ size_t len, + _Inout_ char* dst + ); + + static bool MD5StrValidate + ( + _In_ const char* input1, + _In_ const char* input2 + ); +private: + ; +}; + +#endif // !MD5_H diff --git a/common/utils/QByteUtil.cpp b/common/utils/QByteUtil.cpp new file mode 100644 index 0000000..1d49a51 --- /dev/null +++ b/common/utils/QByteUtil.cpp @@ -0,0 +1,190 @@ +#include "QByteUtil.h" +#include + +static uchar uc = 0x00; +const int FLOAT_BYTE_LENGTH = 4; +const int DOUBLE_BYTE_LENGTH = 8; + +QByteUtil::QByteUtil(QObject *parent) : QObject(parent) +{ + +} + +QByteArray QByteUtil::appendZeroAlign(QByteArray array, int count) +{ + // 如果字节数组的长度不足cout的倍数,在字节数组的前段补0x00 + int rem = array.length() % count; + if (rem > 0) + { + array.insert(0, count - rem, uc); + } + + return array; +} + +QString QByteUtil::binToHexString(QByteArray bytes) +{ + return bytes.toHex().toUpper(); +} + +QByteArray QByteUtil::hexStringToBytes(QString hexString) +{ + hexString = hexString.toUpper(); + if (hexString.length() % 2 == 1) + { + hexString = "0" + hexString; + } + + bool ok; + QByteArray bytes; + for (int i = 0; i < hexString.length() - 1; i = i + 2) + { + QString str = hexString.mid(i, 2); + bytes.append(str.toInt(&ok, 16)); + } + + return bytes; +} + +qulonglong QByteUtil::binToULong(QByteArray bytes, quint8 length) +{ + qulonglong value = 0; + + for (int i = 0; i < bytes.length() && i < length; i++) + { + value = value * 256 + (quint8) bytes.at(i); + } + + return value; +} + +QByteArray QByteUtil::ULongToBytes(qulonglong value, qint8 length) +{ + QByteArray ba; + + for (int i = 0; i < length; i++) + { + ba.prepend(value % 256); + value = value / 256; + } + + return ba; +} + + +float QByteUtil::binToFloat(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // 如果字节数组长度超过4位,取前4位 + QString str = QByteUtil::binToHexString(bytes.mid(0, FLOAT_BYTE_LENGTH)); + int hex = str.toUInt(0, 16); + float ret = *(float*) &hex; + + return ret; +} + +QVector QByteUtil::binToFloatArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, FLOAT_BYTE_LENGTH); + + // float用4字节浮点数表示 + int length = bytes.length() / FLOAT_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 4个字节的浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * FLOAT_BYTE_LENGTH, FLOAT_BYTE_LENGTH)); + + int hex = str.toUInt(0, 16); + float fl = *(float*) &hex; + + ret.append(fl); + } + + return ret; +} + +QByteArray QByteUtil::floatToBytes(float value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < FLOAT_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::floatArrayToBytes(QVector floatArray) +{ + QByteArray ret; + for (int i = 0; i < floatArray.length(); i++) + { + ret.append(floatToBytes(floatArray.at(i))); + } + return ret; +} + + +double QByteUtil::binToDouble(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // 如果字节数组长度超过8位,取前8位 + QString str = QByteUtil::binToHexString(bytes.mid(0, DOUBLE_BYTE_LENGTH)); + qulonglong hex = str.toULongLong(0, 16); + double ret = *(double*) &hex; + + return ret; +} + +QVector QByteUtil::binToDoubleArray(QByteArray bytes) +{ + bytes = appendZeroAlign(bytes, DOUBLE_BYTE_LENGTH); + + // double用8字节浮点数表示 + int length = bytes.length() / DOUBLE_BYTE_LENGTH; + + // 返回值 + QVector ret; + + // 8个字节的双精度浮点数,转换为 + for (int i = 0; i < length; i++) + { + QString str = QByteUtil::binToHexString(bytes.mid(i * DOUBLE_BYTE_LENGTH, DOUBLE_BYTE_LENGTH)); + + qulonglong hex = str.toULongLong(0, 16); + double dl = *(double*) &hex; + + ret.append(dl); + } + + return ret; +} + +QByteArray QByteUtil::doubleToBytes(double value) +{ + uchar * hex = (uchar *) &value; + QByteArray ret; + for (int i = 0; i < DOUBLE_BYTE_LENGTH; i++) + { + ret.insert(0, hex[i]); + } + + return ret; +} + +QByteArray QByteUtil::doubleArrayToBytes(QVector doubleArray) +{ + QByteArray ret; + for (int i = 0; i < doubleArray.length(); i++) + { + ret.append(doubleToBytes(doubleArray.at(i))); + } + return ret; +} diff --git a/common/utils/QByteUtil.h b/common/utils/QByteUtil.h new file mode 100644 index 0000000..f02d2f9 --- /dev/null +++ b/common/utils/QByteUtil.h @@ -0,0 +1,115 @@ +#ifndef QBYTEUTIL_H +#define QBYTEUTIL_H + +#include + +class QByteUtil : public QObject +{ + Q_OBJECT +public: + explicit QByteUtil(QObject *parent = nullptr); + + + /******** 字节数组与字符串互转 ********/ + /** + * @brief binToHexString + * @param bytes + * @note 16进制字节数组转字符串,用于输出显示,不含空格 + * @return + */ + static QString binToHexString(QByteArray bytes); + /** + * @brief hexStringToBytes + * @param hexString + * @note 16进制字符串转字节数组,不含空格 + * @return + */ + static QByteArray hexStringToBytes(QString hexString); + + /******** 字节数组与long互转 ********/ + /** + * @brief binToULong + * @param bytes + * @note 16进制字节数组转无符号long,length个字节。字符串顺序,高位在前,低位在后 + * 如0x0080000000086A43 = 36028797019515459 + * @return + */ + static qulonglong binToULong(QByteArray bytes, quint8 length); + static QByteArray ULongToBytes(qulonglong value, qint8 length); + + /******** 字节数组与float互转 ********/ + /** + * @brief binToFloat + * @param bytes + * @note 4个字节转float浮点数,从左到右排序 + * @example {0x42, 0xF6, 0xE6, 0x66} 转换为 123.45 + * @return + */ + static float binToFloat(QByteArray bytes); + /** + * @brief binToFloatArray + * @param bytes + * @note 字节数组转float数组,16进制浮点数,4个字节表示1个float浮点数,从左到右排序 + * @example {0xBD, 0x1F, 0xB1, 0xDA, 0x40, 0x63, 0x02, 0x0C, 0x40, 0x49, 0x0F, 0xDA} 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToFloatArray(QByteArray bytes); + /** + * @brief floatToBytes + * @param value + * @note 单个float数转4字节数组,从左至右排序 + * @example 123.45 转换为 {0x42, 0xF6, 0xE6, 0x66} + * @return + */ + static QByteArray floatToBytes(float value); + /** + * @brief floatArrayToBytes + * @param floatArray + * @note float数组转换为字节数组,每一个float浮点数4字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 {0x3D, 0x79, 0x09, 0x6C, 0x40, 0x12, 0x7C, 0x5B, 0x3B, 0xDE, 0x9A, 0x3F} + * @return + */ + static QByteArray floatArrayToBytes(QVector floatArray); + + /******** 字节数组与double互转 ********/ + /** + * @brief binToDouble + * @param bytes + * @note 8个字节转double双精度浮点数,从左到右排序 + * @example C00921FB53D92715 转换为 -3.141592650475 + * @return + */ + static double binToDouble(QByteArray bytes); + /** + * @brief binToDoubleArray + * @param bytes + * @note 字节数组转double数组,16进制双精度浮点数,8个字节表示1个double浮点数,从左到右排序 + * @example BFA3F63C31DF761D400C604189374BC74039B2DE00D1B717 转换为 -0.038988, 3.547, 3.141593 + * @return + */ + static QVector binToDoubleArray(QByteArray bytes); + /** + * @brief doubleToBytes + * @param value + * @note 单个double数转换为8字节数组,从左到右排序 + * @example 123.45 转换为 405EDCCCCCCCCCCD + * @return + */ + static QByteArray doubleToBytes(double value); + /** + * @brief doubleArrayToBytes + * @param doubleArray + * @note double数组转换为字节数组,每个double双精度浮点数8字节,从左到右排序 + * @example 0.0608, 2.28884, 0.00679329 转换为 3FAF212D77318FC540024F8B588E368F3F7BD347E61DABB7 + * @return + */ + static QByteArray doubleArrayToBytes(QVector doubleArray); + +private: + static QByteArray appendZeroAlign(QByteArray array, int count); + +signals: + +}; + +#endif // QBYTEUTIL_H diff --git a/common/utils/QKafkaUtil.cpp b/common/utils/QKafkaUtil.cpp new file mode 100644 index 0000000..0cd1639 --- /dev/null +++ b/common/utils/QKafkaUtil.cpp @@ -0,0 +1,68 @@ +#include "QKafkaUtil.h" +#include "SettingConfig.h" +#include + +QKafkaUtil::QKafkaUtil(QObject *parent) : QObject(parent) +{ + this->conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); +} + +void QKafkaUtil::setBrokers(QString brokers) +{ + this->brokers = brokers; +} +void QKafkaUtil::setTopic(QString topic) +{ + this->topic = topic; +} + + +int QKafkaUtil::createProducer() +{ + int result; + result = this->conf->set("bootstrap.servers", this->brokers.toStdString(), errStr); + if (SettingConfig::getInstance().NEED_SASL == 1) + { + conf->set("sasl.username", SettingConfig::getInstance().SASL_USERNAME.toStdString(), errStr); + conf->set("sasl.password", SettingConfig::getInstance().SASL_PASSWORD.toStdString(), errStr); + conf->set("security.protocol", "sasl_plaintext", errStr); + conf->set("sasl.mechanisms", "PLAIN", errStr); + } + + + if (result != RdKafka::Conf::CONF_OK) + { + std::cerr << errStr << std::endl; + + return RdKafka::Conf::CONF_INVALID; // -1 + } + + this->producer = RdKafka::Producer::create(this->conf, errStr); + if (producer == 0) + { + std::cerr << "Failed to create producer: " << errStr << std::endl; + return -2; + } + + result = 1; + return result; +} + +int QKafkaUtil::produceMessage(QString message) +{ + auto retCode = producer->produce(topic.toStdString(), RdKafka::Topic::PARTITION_UA, RdKafka::Producer::RK_MSG_COPY, + const_cast(message.toStdString().c_str()), message.size(), + nullptr, 0, 0, nullptr, nullptr); + + if (retCode != RdKafka::ERR_NO_ERROR) + { + std::cerr << "Failed to produce to topic " << topic.toStdString() << ": " << + RdKafka::err2str(retCode) << std::endl; + } else + { + std::cerr << "Enqueued message (" << message.size() << " bytes) " << + "for topic " << topic.toStdString() << "[" << message.toStdString() <<"]" << std::endl; + } + + return retCode; +} diff --git a/common/utils/QKafkaUtil.h b/common/utils/QKafkaUtil.h new file mode 100644 index 0000000..289ea6f --- /dev/null +++ b/common/utils/QKafkaUtil.h @@ -0,0 +1,33 @@ +#ifndef QKAFKAUTIL_H +#define QKAFKAUTIL_H + +#include + +#include "include/librdkafka/rdkafkacpp.h" + +class QKafkaUtil : public QObject +{ + Q_OBJECT +public: + explicit QKafkaUtil(QObject *parent = nullptr); + + void setBrokers(QString brokers); + void setTopic(QString topic); + + int createProducer(); + int produceMessage(QString message); + +private: + QString brokers; + QString topic; + + std::string errStr; + + RdKafka::Conf * conf; + + RdKafka::Producer * producer = 0; +signals: + +}; + +#endif // QKAFKAUTIL_H diff --git a/common/utils/QLogUtil.cpp b/common/utils/QLogUtil.cpp new file mode 100644 index 0000000..43d8655 --- /dev/null +++ b/common/utils/QLogUtil.cpp @@ -0,0 +1,92 @@ +#include "QLogUtil.h" + + +QLogUtil::QLogUtil(QObject *parent) : QObject(parent) +{ + +} + +void QLogUtil::writeRawDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile rawLogFile(filename); + rawLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + rawLogFile.write(content.toUtf8()); + rawLogFile.close(); +} + +void QLogUtil::writeChannelDataLog(QString filename, QString content) +{ + content.append("\n"); + QFile chLogFile(filename); + chLogFile.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text); + chLogFile.write(content.toUtf8()); + chLogFile.close(); +} + +void QLogUtil::writeDebugLog(QString message) +{ + +} + +void QLogUtil::writeInfoLog(QString message) +{ + +} + +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/common/utils/QLogUtil.h b/common/utils/QLogUtil.h new file mode 100644 index 0000000..1d1ef0f --- /dev/null +++ b/common/utils/QLogUtil.h @@ -0,0 +1,30 @@ +#ifndef QLOGUTIL_H +#define QLOGUTIL_H + +#include +#include +#include +#include +#include "SettingConfig.h" + +class QLogUtil : public QObject +{ + Q_OBJECT +public: + explicit QLogUtil(QObject *parent = nullptr); + + static void writeRawDataLog(QString filename, QString content); + static void writeChannelDataLog(QString filename, QString content); + 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: + +}; + +#endif // QLOGUTIL_H diff --git a/common/utils/QSerialPortUtil.cpp b/common/utils/QSerialPortUtil.cpp new file mode 100644 index 0000000..64da0f7 --- /dev/null +++ b/common/utils/QSerialPortUtil.cpp @@ -0,0 +1,77 @@ +#include "QSerialPortUtil.h" + +#include +#include +#include +#include "common/utils/QByteUtil.h" + +QSerialPortUtil::QSerialPortUtil(QObject *parent) : QObject(parent) +{ + // 其他默认配置 + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); +} + +void QSerialPortUtil::openSerialPort(QString portName, int baudRate) +{ + serial.setPortName(portName); // 串口名 + serial.setBaudRate(baudRate); // 波特率 + + open = serial.open(QIODevice::ReadWrite); + + if (open == true) + { + // 绑定信号与槽 + connect(&serial, &QSerialPort::readyRead, + this, &QSerialPortUtil::readData); + + // mock data received per second +// QTimer * timer = new QTimer(this); +// connect(timer, &QTimer::timeout, +// this, &QSerialPortUtil::mockReceivData); +// timer->start(1000); + } +} + +void QSerialPortUtil::sendData(QByteArray data) +{ + if (this->open == true) + { + std::cout << data.toStdString() << std::endl; + serial.write(data); + } +} + +void QSerialPortUtil::readData() +{ + QByteArray buffer = serial.readAll(); + + emit dataRecieved(buffer); +} + +bool QSerialPortUtil::isOpen() +{ + return this->open; +} + +void QSerialPortUtil::mockReceivData() +{ + QDateTime now = QDateTime::currentDateTime(); + + QString frameId = now.toString("HHmmsszzz"); + + QByteArray buffer; + buffer.append(QByteUtil::hexStringToBytes(frameId.mid(0, 8))); + + for (int i = 1; i <= 16; i++) + { + int value = qrand() % 10000; + buffer.append(QByteUtil::hexStringToBytes("00800000")).append(QByteUtil::ULongToBytes(value, 4)); + } + + buffer.append(QByteUtil::hexStringToBytes("EEEEEEEE")); + + emit dataRecieved(buffer); +} diff --git a/common/utils/QSerialPortUtil.h b/common/utils/QSerialPortUtil.h new file mode 100644 index 0000000..accf403 --- /dev/null +++ b/common/utils/QSerialPortUtil.h @@ -0,0 +1,30 @@ +#ifndef QSERIALPORTUTIL_H +#define QSERIALPORTUTIL_H + +#include +#include + +class QSerialPortUtil : public QObject +{ + Q_OBJECT +public: + explicit QSerialPortUtil(QObject *parent = nullptr); + + void openSerialPort(QString portName, int baudRate); + void sendData(QByteArray data); + void readData(); + + bool isOpen(); + +private: + QSerialPort serial; + + bool open; + + void mockReceivData(); + +signals: + void dataRecieved(QByteArray data); // 收到数据的信号 +}; + +#endif // QSERIALPORTUTIL_H diff --git a/common/utils/SettingConfig.cpp b/common/utils/SettingConfig.cpp new file mode 100644 index 0000000..9a84a43 --- /dev/null +++ b/common/utils/SettingConfig.cpp @@ -0,0 +1,29 @@ +#include "SettingConfig.h" + +SettingConfig::SettingConfig() +{ + filename = QApplication::applicationDirPath() + "/conf/config.ini"; + setting = new QSettings(this->filename, QSettings::IniFormat); + + BAUD_RATE = getProperty("com", "baudRate").toInt(); + + NEED_KAFKA = getProperty("kafka", "needKafka").toInt(); + KAFKA_BROKERS = getProperty("kafka", "brokers").toString(); + KAFKA_DATA_TOPIC = getProperty("kafka", "dataTopic").toString(); + NEED_SASL = getProperty("kafka", "needSasl").toInt(); + SASL_USERNAME = getProperty("kafka", "saslUsername").toString(); + SASL_PASSWORD = getProperty("kafka", "saslPassword").toString(); + + CLIENT_ID = getProperty("client", "clientId").toString(); + APP_KEY = getProperty("client", "appKey").toString(); + + BASE_URL = getProperty("http", "baseUrl").toString(); + + BASE_LOG_PATH = getProperty("log", "basePath").toString(); +} + + +QVariant SettingConfig::getProperty(QString nodeName, QString keyName) { + QVariant var = this->setting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/common/utils/SettingConfig.h b/common/utils/SettingConfig.h new file mode 100644 index 0000000..0038ecc --- /dev/null +++ b/common/utils/SettingConfig.h @@ -0,0 +1,53 @@ +#ifndef SETTINGCONFIG_H +#define SETTINGCONFIG_H + +#include +#include +#include + +class SettingConfig : public QObject +{ +public: + ~SettingConfig() {}; + SettingConfig(const SettingConfig&)=delete; + SettingConfig& operator=(const SettingConfig&)=delete; + + static SettingConfig& getInstance() { + static SettingConfig instance; + return instance; + } + + /** + * @brief get + * @param nodeName + * @param keyName + * @return QVariant + * @title + */ + QVariant getProperty(QString nodeName, QString keyName); + + /******** 以下为需要的各类参数 ********/ + int BAUD_RATE; + + int NEED_KAFKA; + QString KAFKA_BROKERS; + QString KAFKA_DATA_TOPIC; + int NEED_SASL; + QString SASL_USERNAME; + QString SASL_PASSWORD; + + QString CLIENT_ID; + QString APP_KEY; + + QString BASE_URL; + + QString BASE_LOG_PATH; + +private: + SettingConfig(); + + QString filename; + QSettings * setting; +}; + +#endif // SETTINGCONFIG_H diff --git a/conf/config.ini b/conf/config.ini new file mode 100644 index 0000000..46d97d7 --- /dev/null +++ b/conf/config.ini @@ -0,0 +1,20 @@ +[com] +baudRate=115200 + +[kafka] +needKafka=1 +brokers="111.198.10.15:12502" +dataTopic="cppTest" +needSasl=0 +sasl.username="admin" +sasl.password="casicss" + +[client] +clientId="phase" +appKey="bd593bdd20943d2db8af217c3712a460" + +[http] +baseUrl="http://111.198.10.15:11410" + +[log] +basePath="/home/admin/Qt/ZXSSCJ-Release/PhaseCompAcq/logs/" diff --git a/images.qrc b/images.qrc new file mode 100644 index 0000000..0fc1f3e --- /dev/null +++ b/images.qrc @@ -0,0 +1,6 @@ + + + images/white.png + images/green.png + + diff --git a/images/green.png b/images/green.png new file mode 100644 index 0000000..a33ee4b --- /dev/null +++ b/images/green.png Binary files differ diff --git a/images/white.png b/images/white.png new file mode 100644 index 0000000..337df06 --- /dev/null +++ b/images/white.png Binary files differ diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..adf5eeb --- /dev/null +++ b/main.cpp @@ -0,0 +1,11 @@ +#include "PhaseWindow.h" + +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + PhaseWindow w; + w.show(); + return a.exec(); +} diff --git a/protocol/PhaseProtocolBM.cpp b/protocol/PhaseProtocolBM.cpp new file mode 100644 index 0000000..aa4f086 --- /dev/null +++ b/protocol/PhaseProtocolBM.cpp @@ -0,0 +1,78 @@ +#include "PhaseProtocolBM.h" +#include + +PhaseProtocolBM::PhaseProtocolBM(QObject *parent) : QObject(parent) +{ + +} + +PhaseProtocolBM::~PhaseProtocolBM() +{ + +} + +bool PhaseProtocolBM::parseMessureData(QByteArray rawData, PhaseDataDto * dataObj) +{ + // 获取帧头——帧计数 + QByteArray head = rawData.left(PHASE_FRAME_ID_LENGTH); + dataObj->frameId = QByteUtil::binToHexString(head); + + int j = 0; // 用于转换通道顺序 + + // 获取每个通道的测量数据 + for (int i = 1; i <= PHASE_MESSURE_CHANNEL; i++) + { + if (i <= 8) + { + j = 2 * i - 1; + + } else + { + j = 2 * (i - 8); + } + + QByteArray channelRaw = rawData.left(PHASE_MESSURE_SIZE * j + PHASE_FRAME_ID_LENGTH).right(PHASE_MESSURE_SIZE); + qulonglong channelRawData = QByteUtil::binToULong(channelRaw, 8); + + if (channelRawData == CALCULATE_OFFSET) + { + dataObj->channelActive.append("0"); + dataObj->channelData.append(0.00); + dataObj->channelDataStr.append("0.00"); + } else + { + double phase = (channelRawData - CALCULATE_OFFSET) * CALCULATE_FACTOR; + dataObj->channelActive.append("1"); + dataObj->channelData.append(phase); + dataObj->channelDataStr.append(QString::number(phase, 'f', 12)); + } + } + + return true; +} + +QString PhaseProtocolBM::startMessure() +{ + return "$START*"; +} +QString PhaseProtocolBM::stopMessure() +{ + return "$$STOP*"; +} + +bool PhaseProtocolBM::checkFrame(QByteArray rawData) +{ + // 帧长度小于最小的长度 + if (rawData.length() != PHASE_FRAM_LENGTH) + { + return false; + } + + // 帧尾不是0xEEEEEEEE + if (rawData.mid(rawData.length() - PHASE_FRAME_TAIL.size()) != PHASE_FRAME_TAIL) + { + return false; + } + + return true; +} diff --git a/protocol/PhaseProtocolBM.h b/protocol/PhaseProtocolBM.h new file mode 100644 index 0000000..048a9c2 --- /dev/null +++ b/protocol/PhaseProtocolBM.h @@ -0,0 +1,36 @@ +#ifndef PHASEPROTOCOLBM_H +#define PHASEPROTOCOLBM_H + +#include + +#include "dto/PhaseDataDto.h" +#include "common/utils/QByteUtil.h" + +static const QByteArray PHASE_FRAME_TAIL("\xEE\xEE\xEE\xEE", 4); // 帧尾 + +static const int PHASE_FRAME_ID_LENGTH = 4; // 帧头id计数器为4个字节 +static const int PHASE_MESSURE_CHANNEL = 16; +static const int PHASE_MESSURE_SIZE = 8; +static const int PHASE_FRAM_LENGTH = PHASE_FRAME_ID_LENGTH + PHASE_FRAME_TAIL.size() + + PHASE_MESSURE_CHANNEL * PHASE_MESSURE_SIZE; + +static const qulonglong CALCULATE_OFFSET = 0X0080000000000000; +static const double CALCULATE_FACTOR = 1.6810E-15; + +class PhaseProtocolBM : public QObject +{ +public: + explicit PhaseProtocolBM(QObject *parent = nullptr); + ~PhaseProtocolBM(); + + // 解析比相仪测量数据 + static bool parseMessureData(QByteArray rawData, PhaseDataDto * phaseData); + + static QString startMessure(); + static QString stopMessure(); + + // 检测帧格式,帧头帧尾 + static bool checkFrame(QByteArray rawData); +}; + +#endif // PHASEROTOCOLBM_H diff --git a/protocol/dto/PhaseDataDto.cpp b/protocol/dto/PhaseDataDto.cpp new file mode 100644 index 0000000..5163335 --- /dev/null +++ b/protocol/dto/PhaseDataDto.cpp @@ -0,0 +1,21 @@ +#include "PhaseDataDto.h" + +PhaseDataDto::PhaseDataDto(QObject *parent) : QObject(parent) +{ + +} + +QJsonObject PhaseDataDto::toJSON(int i) +{ + QJsonObject jsonObj; + + QJsonObject dataObj; + dataObj.insert("dataValue", this->channelDataStr.at(i)); + dataObj.insert("frameId", this->frameId); + + jsonObj.insert("channelNo", (i + 1)); + jsonObj.insert("ts", this->milisecond); + jsonObj.insert("data", dataObj); + + return jsonObj; +} diff --git a/protocol/dto/PhaseDataDto.h b/protocol/dto/PhaseDataDto.h new file mode 100644 index 0000000..0317a83 --- /dev/null +++ b/protocol/dto/PhaseDataDto.h @@ -0,0 +1,31 @@ +#ifndef PHASEDATADTO_H +#define PHASEDATADTO_H + +#include +#include +#include + +class PhaseDataDto : public QObject +{ + Q_OBJECT +public: + explicit PhaseDataDto(QObject *parent = nullptr); + + QString frameId; // 帧id + QString timestamp; // 时间戳字符串 + qlonglong milisecond; // 毫秒计数 + QByteArray rawFrame; // 原始帧字节数组 + + QString devCode; + QString devStatus; + QList channelActive; + QList channelData; + QList channelDataStr; + + QJsonObject toJSON(int i); + +signals: + +}; + +#endif // PHASEDATADTO_H diff --git a/protocol/protocol.pri b/protocol/protocol.pri new file mode 100644 index 0000000..d998e2e --- /dev/null +++ b/protocol/protocol.pri @@ -0,0 +1,6 @@ + +SOURCES += $$PWD/PhaseProtocolBM.cpp +SOURCES += $$PWD/dto/PhaseDataDto.cpp + +HEADERS += $$PWD/PhaseProtocolBM.h +HEADERS += $$PWD/dto/PhaseDataDto.h