Gas safety management system written in Qt 27- commissioning

I. Introduction

Commissioning core is unified display all the print data in the entire system into a module, usually to send and receive data and the corresponding analytical signal hardware communication sent to or qdebug out, this is very useful in debugging phase, can be specifically tracking problem where, data analysis which does not directly positioning the past, leave this module directly interfaces such as print view, you can catch a variety of abnormal conditions in the field, so that the data field engineers debug distributed to the save developers to help analyze problems because very often the family company tested properly, to live all manner of situations will arise, developers can not spend all day running around in a variety of on-site, a waste of energy, it is better to do directly corresponding equipment debugging module, data capture error log file analysis sent me.

As a decade of doing this kind of communication hardware and software project development staff, more equipment debugging module that is certainly taken into account, such as a communication port can be filtered, a device directly on the screen capture, you can listens only to send data, receive data, analytical data, the most crucial point, can be freely set keywords to capture, data specific keyword color display, you can set multiple keywords, such efficiency is greatly improved, after all device data the transceiver is fast, brush brush, and a second screen passed a set keyword-capture automatic printing of different colors, to prevent eye fatigue, a far away to see, and how good, in this module also can check output to a log file, set the maximum number of lines used to automatically clear the data, after all, a text box can not load data has been down, to the maximum number of lines automatically cleared.

Log open source tools: https://gitee.com/feiyangqingyun/QWidgetDemo https://github.com/feiyangqingyun/QWidgetDemo
File name: savelog

Experience Address: https://gitee.com/feiyangqingyun/QWidgetExe https://github.com/feiyangqingyun/QWidgetExe
File name: bin_sams.zip

Second, the functional characteristics

  1. Collect data port, serial port support + network port, serial port supports baud rate set free + serial number, network support freely set the IP address + communication ports, each port supports acquisition cycle, default 1 second address, set the communication timeout support frequency default 3 times, support the largest reconnection time for the re-read off-line equipment.
  2. Controller information, the controller can be added to the name, address + control model selection controller, the controller is provided below the number of detectors.
  3. Probe information, the bit number can be added, can be freely selected probe type, gas type, gas symbol, the value of the high alarm, low reported values, buffer values, a value is cleared, if enabled, an alarm sound, a background map, the storage period, the value conversion of decimal places, the alarm delay time, alarm type (HH, LL, HL) and the like.
  4. Detector Model Controller Model + + + gas symbol gas species, can be freely arranged.
  5. Map supports importing and delete all the corresponding map position detector can freely drag saved.
  6. Port information + + probe information controller information, import and export support + + print exported to Excel.
  7. + + Alarm log record recording the user, the query condition combination to support multiple, such as + period + Controller detectors, all record print support exported to Excel +.
  8. Export to excel record of support for all forms such as excel + wps file versions, does not rely on software such as excel.
  9. You can delete data within a specified time frame, auto clean up early data, set the maximum number of record-keeping.
  10. Support forwarding alarm messages, the plurality of support receiving phone number, the transmission interval can be set, such as instant or the transmission 6 hours send all the alarm messages, message content is too long, a number of messages automatically split.
  11. Support alarm mail forwarding, support for receiving a plurality of mailboxes, the transmission interval can be set, such as instant transmission or six hours all the alarm information once transmitted, to support attachments.
  12. High + Low message packets Color Color values ​​Color + + + 0 normal color profile curves + background color, etc., can be freely selected.
  13. Software English title Chinese title + + + logo Copyright paths can be freely set.
  14. Provides switch switched on the alarm sound + + + automatic login remember passwords.
  15. Sound the alarm can be set to play frequency interface available in 17 skin file selection.
  16. Support cloud data synchronization, cloud database information can be set, such as database name, username + password.
  17. Support network forwarding and receiving network, the network is open to receive, parse udp software to receive data from. Network forwarding support multiple target IP, thus achieving a local collection of software, free data to the client, at any time to view the detector data.
  18. Automatically remembers the last stop of the user interface + additional information, automatic application restart.
  19. Alarm automatically switches to a map corresponding to the detector button flashes.
  20. Double-click the probe icon, you can back control.
  21. Support user rights management, administrators + operator into two categories, user login + user exits, you can remember the password and automatic login, more than three times error prompt and close the program.
  22. Supports four monitoring mode, the monitoring device panel monitor + Map + table + curve data monitoring data monitoring, are free to switch the four synchronization application.
  23. Support alarm relay linkage, a bit serial number can be linked across a plurality of modules and a relay number, support-many.
  24. Local data storage support sqlite + mysql, supports remote data synchronization to the cloud database. Automatic reconnection.
  25. Real-time local device collected data uploaded to the cloud, so that the phone APP or web and other ways to extract.
  26. Supports two data sources, one serial port and the data acquisition devices through a network protocol, one is the collection database. Acquisition mode database can be used as a general system.
  27. Carrying equipment simulation tools, devices 16 support analog data, but also with the database data simulation, when there is no data to test the device.
  28. Default communication protocol using modbus protocol, later adding support mqtt and other things of the agreement, made common system.
  29. Supports all windows operating system + linux operating system and other operating systems.

Third, renderings

Fourth, the core code

#include "frmconfigdebug.h"
#include "ui_frmconfigdebug.h"
#include "quiwidget.h"
#include "deviceserver.h"
#include "dblocalthread.h"
#include "dbtcpclientthread.h"
#include "dbreceive.h"

frmConfigDebug::frmConfigDebug(QWidget *parent) : QWidget(parent), ui(new Ui::frmConfigDebug)
{
    ui->setupUi(this);
    this->initForm();
    this->initConfig();
}

frmConfigDebug::~frmConfigDebug()
{
    delete ui;
}

void frmConfigDebug::initForm()
{
    QFont font;
    font.setPixelSize(QUIConfig::FontSize + 5);
    ui->txtMain->setFont(font);
    ui->frameRight->setFixedWidth(App::RightWidth);

    ui->cboxPortName->addItem("所有端口");
    ui->cboxPortName->addItems(DBData::PortInfo_PortName);

    QUIHelper::setLabStyle(ui->labPortName, 1);
    QUIHelper::setLabStyle(ui->labDeviceName, 1);
    QUIHelper::setLabStyle(ui->labKeyValue1, 3);
    QUIHelper::setLabStyle(ui->labKeyValue2, 3);
    QUIHelper::setPushButtonQss(ui->btnClearData);
    QUIHelper::setPushButtonQss(ui->btnReadValueAll);

#if (QT_VERSION >= QT_VERSION_CHECK(5,2,0))
    ui->txtKeyValue1->setPlaceholderText("支持多个关键字,用 | 隔开");
    ui->txtKeyValue2->setPlaceholderText("支持多个关键字,用 | 隔开");
#endif

    //颜色下拉框
    QStringList colorList = QColor::colorNames();
    foreach (QString strColor, colorList) {
        QPixmap pix(ui->cboxKeyColor1->iconSize());
        pix.fill(strColor);
        ui->cboxKeyColor1->addItem(QIcon(pix), strColor);
        ui->cboxKeyColor2->addItem(QIcon(pix), strColor);
    }

    //绑定设备采集服务信号槽
    connect(DeviceServer::Instance(), SIGNAL(sendData(QString, quint8, QByteArray)),
            this, SLOT(sendData(QString, quint8, QByteArray)));
    connect(DeviceServer::Instance(), SIGNAL(receiveData(QString, quint8, QByteArray)),
            this, SLOT(receiveData(QString, quint8, QByteArray)));
    connect(DeviceServer::Instance(), SIGNAL(receiveInfo(QString, quint8, QString)),
            this, SLOT(receiveInfo(QString, quint8, QString)));
    connect(DeviceServer::Instance(), SIGNAL(receiveError(QString, quint8, QString)),
            this, SLOT(receiveError(QString, quint8, QString)));
}

void frmConfigDebug::initConfig()
{
    ui->cboxPortName->setCurrentIndex(App::PortNameIndex);
    connect(ui->cboxPortName, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));

    ui->cboxDeviceName->setCurrentIndex(App::DeviceNameIndex);
    connect(ui->cboxDeviceName, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));

    keys1 = App::KeyValue1.split("|");
    ui->txtKeyValue1->setText(App::KeyValue1);
    connect(ui->txtKeyValue1, SIGNAL(textChanged()), this, SLOT(saveConfig()));

    ui->cboxKeyColor1->setCurrentIndex(ui->cboxKeyColor1->findText(App::KeyColor1));
    connect(ui->cboxKeyColor1, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));

    keys2 = App::KeyValue2.split("|");
    ui->txtKeyValue2->setText(App::KeyValue2);
    connect(ui->txtKeyValue2, SIGNAL(textChanged()), this, SLOT(saveConfig()));

    ui->cboxKeyColor2->setCurrentIndex(ui->cboxKeyColor2->findText(App::KeyColor2));
    connect(ui->cboxKeyColor2, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
}

void frmConfigDebug::saveConfig()
{
    App::PortNameIndex = ui->cboxPortName->currentIndex();
    App::DeviceNameIndex = ui->cboxDeviceName->currentIndex();
    App::KeyValue1 = ui->txtKeyValue1->toPlainText().trimmed();
    App::KeyColor1 = ui->cboxKeyColor1->currentText();
    App::KeyValue2 = ui->txtKeyValue2->toPlainText().trimmed();
    App::KeyColor2 = ui->cboxKeyColor2->currentText();

    if (App::KeyValue1.isEmpty()) {
        App::KeyValue1 = "|";
    }

    if (App::KeyValue2.isEmpty()) {
        App::KeyValue2 = "|";
    }

    App::writeConfig();

    keys1 = App::KeyValue1.split("|");
    keys2 = App::KeyValue2.split("|");
}

void frmConfigDebug::append(int type, const QString &portName, quint8 addr, const QString &data, bool clear)
{
    static int currentCount = 0;
    static int maxCount = 500;

    //执行清空数据命令
    if (clear) {
        ui->txtMain->clear();
        currentCount = 0;
        return;
    }

    //执行条数到了清空数据
    if (currentCount >= maxCount) {
        ui->txtMain->clear();
        currentCount = 0;
    }

    //暂停显示
    if (ui->ckPause->isChecked()) {
        return;
    }

    //过滤端口
    QString currentPortName = ui->cboxPortName->currentText();
    if (currentPortName != "所有端口") {
        if (currentPortName != portName) {
            return;
        }
    }

    //过滤地址
    quint8 deviceAddr = ui->cboxDeviceName->itemData(App::DeviceNameIndex).toInt();
    if (deviceAddr != 255) {
        if (deviceAddr != addr) {
            return;
        }
    }

    //过滤回车换行符
    QString strData = data;
    strData = strData.replace("\r", "");
    strData = strData.replace("\n", "");

    //不同类型不同颜色显示
    QString strType;
    if (type == 0) {
        strType = "发送";
        ui->txtMain->setTextColor(QColor("#009679"));
    } else if (type == 1) {
        strType = "接收";
        ui->txtMain->setTextColor(QColor("#D64D54"));
    } else if (type == 2) {
        strType = "解析";
        ui->txtMain->setTextColor(QColor("#B59481"));
    } else if (type == 3) {
        strType = "错误";
        ui->txtMain->setTextColor(QColor("#A279C5"));
    } else if (type == 4) {
        strType = "解析";
        ui->txtMain->setTextColor(QColor("#047058"));
    } else if (type == 5) {
        strType = "解析";
        ui->txtMain->setTextColor(QColor("#9157C8"));
    } else if (type == 6) {
        strType = "解析";
        ui->txtMain->setTextColor(QColor("#BA5656"));
    }

    //过滤关键字1,设置不同颜色
    foreach (QString key, keys1) {
        if (!key.isEmpty() && data.contains(key)) {
            ui->txtMain->setTextColor(QColor(App::KeyColor1));
            break;
        }
    }

    //过滤关键字2,设置不同颜色
    foreach (QString key, keys2) {
        if (!key.isEmpty() && data.contains(key)) {
            ui->txtMain->setTextColor(QColor(App::KeyColor2));
            break;
        }
    }

    QString strAddr = QString("%1").arg(addr, 3, 10, QChar('0'));
    strData = QString("%1 %2[%3] %4: %5").arg(TIMEMS).arg(portName).arg(strAddr).arg(strType).arg(strData);
    ui->txtMain->append(strData);
    currentCount++;

    //输出数据
    if (ui->ckDebug->isChecked()) {
        qDebug() << strData;
    }
}

void frmConfigDebug::sendData(const QString &portName, quint8 addr, const QByteArray &data)
{
    if (!ui->ckSendData->isChecked()) {
        return;
    }

    append(0, portName, addr, QUIHelper::byteArrayToHexStr(data));
}

void frmConfigDebug::receiveData(const QString &portName, quint8 addr, const QByteArray &data)
{
    if (!ui->ckReceiveData->isChecked()) {
        return;
    }

    append(1, portName, addr, QUIHelper::byteArrayToHexStr(data));
}

void frmConfigDebug::receiveInfo(const QString &portName, quint8 addr, const QString &data)
{
    if (!ui->ckReceiveInfo->isChecked()) {
        return;
    }

    append(2, portName, addr, data);
}

void frmConfigDebug::receiveError(const QString &portName, quint8 addr, const QString &data)
{
    append(3, portName, addr, data);
}

void frmConfigDebug::debugDbLocalThread(const QString &msg)
{
    append(4, "本地数据库", 255, msg);
}

void frmConfigDebug::debugDbTcpClientThread(const QString &msg)
{
    append(5, "云端数据库", 255, msg);
}

void frmConfigDebug::debugDbReceive(const QString &msg)
{
    append(6, "下载数据库", 255, msg);
}

void frmConfigDebug::on_btnClearData_clicked()
{
    append(0, "", 255, "", true);
}

void frmConfigDebug::on_btnReadValueAll_clicked()
{
    DeviceServer::Instance()->readValueAll();
}

void frmConfigDebug::on_cboxPortName_currentIndexChanged(const QString &arg1)
{
    //重新载入该端口对应的所有设备
    ui->cboxDeviceName->clear();
    ui->cboxDeviceName->addItem("所有设备", 255);

    for (int i = 0; i < DBData::DeviceInfo_Count; i++) {
        if (DBData::DeviceInfo_PortName.at(i) == arg1) {
            QString deviceName = DBData::DeviceInfo_DeviceName.at(i);
            quint8 deviceAddr = DBData::DeviceInfo_DeviceAddr.at(i);
            ui->cboxDeviceName->addItem(deviceName, deviceAddr);
        }
    }
}

void frmConfigDebug::on_ckOther_stateChanged(int arg1)
{
    on_btnClearData_clicked();
    if (arg1 != 0) {
        //先解除设备采集服务信号槽
        disconnect(DeviceServer::Instance(), SIGNAL(sendData(QString, quint8, QByteArray)),
                   this, SLOT(sendData(QString, quint8, QByteArray)));
        disconnect(DeviceServer::Instance(), SIGNAL(receiveData(QString, quint8, QByteArray)),
                   this, SLOT(receiveData(QString, quint8, QByteArray)));
        disconnect(DeviceServer::Instance(), SIGNAL(receiveInfo(QString, quint8, QString)),
                   this, SLOT(receiveInfo(QString, quint8, QString)));
        disconnect(DeviceServer::Instance(), SIGNAL(receiveError(QString, quint8, QString)),
                   this, SLOT(receiveError(QString, quint8, QString)));

        //绑定其他信号槽
        connect(DbLocalThread::Instance(), SIGNAL(debug(QString)), this, SLOT(debugDbLocalThread(QString)));
        connect(DbTcpClientThread::Instance(), SIGNAL(debug(QString)), this, SLOT(debugDbTcpClientThread(QString)));
        connect(DbReceive::Instance(), SIGNAL(debug(QString)), this, SLOT(debugDbReceive(QString)));
    } else {
        //先绑定设备采集服务信号槽
        connect(DeviceServer::Instance(), SIGNAL(sendData(QString, quint8, QByteArray)),
                this, SLOT(sendData(QString, quint8, QByteArray)));
        connect(DeviceServer::Instance(), SIGNAL(receiveData(QString, quint8, QByteArray)),
                this, SLOT(receiveData(QString, quint8, QByteArray)));
        connect(DeviceServer::Instance(), SIGNAL(receiveInfo(QString, quint8, QString)),
                this, SLOT(receiveInfo(QString, quint8, QString)));
        connect(DeviceServer::Instance(), SIGNAL(receiveError(QString, quint8, QString)),
                this, SLOT(receiveError(QString, quint8, QString)));

        //解除其他信号槽
        disconnect(DbLocalThread::Instance(), SIGNAL(debug(QString)), this, SLOT(debugDbLocalThread(QString)));
        disconnect(DbTcpClientThread::Instance(), SIGNAL(debug(QString)), this, SLOT(debugDbTcpClientThread(QString)));
        disconnect(DbReceive::Instance(), SIGNAL(debug(QString)), this, SLOT(debugDbReceive(QString)));
    }
}

Guess you like

Origin www.cnblogs.com/feiyangqingyun/p/11994614.html