新增识别少于指定车厢数的异常报警

This commit is contained in:
Mr.V 2024-05-21 17:08:53 +08:00
parent 37228b3841
commit 36459f12af
12 changed files with 330 additions and 22 deletions

Binary file not shown.

View File

@ -5,17 +5,22 @@ track_name=2
have_magnet_steel=true
magnet_steel_order=8421
up_result=true
use_socket_server=false
use_socket_server=true
use_device_warn=true
[interface]
http_ip=192.168.2.212
http_port=20004
token_path=/api/token_path
up_result_path=/api/train-carriage/identification/rfid-save
up_warning_path=/api/blade-train/deviceInfo/save
username=guest_01
password=d55b0f642e817eea24725d2f2a31dd08
[socket_server]
server_ip=192.168.2.1
server_ip=127.0.0.1
server_port=7000
delayed_upload=4
[device_warn]
min_train_size=10

View File

@ -27,6 +27,7 @@ bool ConfigUtil::readBaseConfig(const QString &configFile, QString &errorMessage
config.magnetSteelOrder = mset->value("magnet_steel_order", "").toString();
config.upResult = mset->value("up_result", false).toBool();
config.useSocketServer = mset->value("use_socket_server", false).toBool();
config.useDeviceWarn = mset->value("use_device_warn", false).toBool();
mset->endGroup();
} catch (const std::exception &e) {
@ -49,7 +50,8 @@ bool ConfigUtil::readInterfaceConfig(const QString &configFile, QString &errorMe
config.httpIp = mset->value("http_ip", "").toString();
config.httpPort = mset->value("http_port", "").toInt();
config.tokenPath = mset->value("token_path", 19200).toString();
config.upResultPath = mset->value("up_result_path", 1).toString();
config.upResultPath = mset->value("up_result_path", "").toString();
config.upWarningPath = mset->value("up_warning_path", "").toString();
config.username = mset->value("username", "").toString();
config.password = mset->value("password", false).toString();
@ -80,4 +82,24 @@ bool ConfigUtil::readSocketServerConfig(const QString &configFile, QString &erro
return false;
}
return true;
}
bool ConfigUtil::readDeviceWarnConfig(const QString &configFile, QString &errorMessage,
ai_matrix::DeviceWarnConfig &config) {
try {
if (configFile.isEmpty() || configFile.isNull()) {
errorMessage = "配置文件地址为空,读取配置文件失败!";
return false;
}
QSettings* mset = new QSettings(configFile, QSettings::IniFormat);
mset->setIniCodec(QTextCodec::codecForName("UTF-8"));
mset->beginGroup("device_warn");
config.min_train_size = mset->value("min_train_size", 99).toInt();
mset->endGroup();
} catch (const std::exception &e) {
errorMessage = e.what();
return false;
}
return true;
}

View File

@ -20,6 +20,7 @@ public:
static bool readBaseConfig(const QString& configFile, QString &errorMessage, ai_matrix::BaseConfig &config);
static bool readInterfaceConfig(const QString& configFile, QString &errorMessage, ai_matrix::InterfaceConfig &config);
static bool readSocketServerConfig(const QString& configFile, QString &errorMessage, ai_matrix::SServerConfig &config);
static bool readDeviceWarnConfig(const QString& configFile, QString &errorMessage, ai_matrix::DeviceWarnConfig &config);
};

View File

@ -37,6 +37,8 @@ namespace ai_matrix {
bool upResult;
// 使用socket来车通讯
bool useSocketServer;
// 是否使用设备异常报警
bool useDeviceWarn;
};
struct InterfaceConfig {
@ -49,6 +51,8 @@ namespace ai_matrix {
QString tokenPath;
// 上传识别结果的方法
QString upResultPath;
// 上传报警的方法
QString upWarningPath;
// 用户名
QString username;
// 密码
@ -63,6 +67,12 @@ namespace ai_matrix {
// 识别结果延后X节上传以等待Socket反馈火车运行方向
int delayed_upload;
};
struct DeviceWarnConfig {
// 识别车厢结束允许的最小值(小于这个值会报警)
int min_train_size;
};
// --- 配置文件 ---
struct TrainInfo {

View File

@ -15,7 +15,7 @@ MainWindow::MainWindow(QWidget *parent)
this->statusBar = new QStatusBar();
this->statusInfo = new QLabel("初始化完成",this);
this->statusBar->addPermanentWidget(this->statusInfo);//显示正常信息
QLabel* statusVersion = new QLabel("开启时间:" + QDateTime::currentDateTime().toString("yy.MM.dd.hh.mm"),this);
QLabel* statusVersion = new QLabel("开启时间:" + QDateTime::currentDateTime().toString("yy-MM-dd hh:mm"),this);
this->statusBar->addWidget(statusVersion);
layout()->addWidget(this->statusBar);
@ -71,12 +71,15 @@ MainWindow::MainWindow(QWidget *parent)
// 初始化LED指示灯
this->upResultType(this->baseConfig_.upResult);
this->readComThread = new ReadComThread(&this->queueTrainInfo_, this);
this->readComThread = new ReadComThread(&this->queueTrainInfo_, &this->queueWarn_, this);
this->readComThread->start();
this->upResultThread = new UpResultThread(&this->queueTrainInfo_, this);
this->upResultThread->start();
this->upWarnThread = new UpWarnThread(&this->queueWarn_, this);
this->upWarnThread->start();
connect(this, &MainWindow::openCom_signals, this->readComThread, &ReadComThread::openCom);
connect(this, &MainWindow::readTestRfid_signals, this->readComThread, &ReadComThread::readTestInfo);
@ -97,6 +100,11 @@ MainWindow::MainWindow(QWidget *parent)
connect(this->upResultThread, &UpResultThread::WarnSignals, this, &MainWindow::WarnSlots);
connect(this->upResultThread, &UpResultThread::ErrorSignals, this, &MainWindow::ErrorSlots);
connect(this->upWarnThread, &UpWarnThread::DebugSignals, this, &MainWindow::DebugSlots);
connect(this->upWarnThread, &UpWarnThread::InfoSignals, this, &MainWindow::InfoSlots);
connect(this->upWarnThread, &UpWarnThread::WarnSignals, this, &MainWindow::WarnSlots);
connect(this->upWarnThread, &UpWarnThread::ErrorSignals, this, &MainWindow::ErrorSlots);
ui->openComButton->click();
}

View File

@ -54,6 +54,7 @@
#include "UpResultThread.h"
#include "ReadComThread.h"
#include "UpWarnThread.h"
QT_BEGIN_NAMESPACE
@ -92,6 +93,7 @@ public:
private:
UpResultThread *upResultThread;
UpWarnThread *upWarnThread;
ReadComThread *readComThread;
QString logRfidRecvName;
@ -116,6 +118,7 @@ private:
QStringList vecTrain;
MQueue<QString> queue_{}; // RFID读取的数据队列
MQueue<TrainInfo> queueTrainInfo_{}; // RFID读取的磁钢信息队列
MQueue<QString> queueWarn_{}; // 报警信息队列
QString rfidSourceInfo;
QString tmpRfid; //临时存储的RFID原始数据用于防止接收的数据不完整

View File

@ -5,6 +5,7 @@
#include "ReadComThread.h"
ReadComThread::ReadComThread(MQueue<TrainInfo> *queueTrainInfo,
MQueue<QString> *queueWarnInfo,
QObject *parent) :
QThread(parent)
{
@ -18,8 +19,13 @@ ReadComThread::ReadComThread(MQueue<TrainInfo> *queueTrainInfo,
{
emit this->ErrorSignals(errorMessage);
}
if (!ConfigUtil::readDeviceWarnConfig(g_config_path, errorMessage, this->deviceWarnConfig_))
{
emit this->ErrorSignals(errorMessage);
}
this->queueTrainInfo_ = queueTrainInfo;
this->queueWarnInfo_ = queueWarnInfo;
this->logRfidRecvName = "./Logs/rfid_data.txt";
this->recvLog.setFileName(logRfidRecvName);
@ -282,7 +288,6 @@ void ReadComThread::getQueueDataThread()
QString rfidinfo = this->rfidSourceInfo;
this->rfidSourceInfo = "";
emit this->upRfid_signals(rfidinfo);
}
}
else if (i.size() == 7)
@ -327,7 +332,10 @@ void ReadComThread::IdentifyTypeUpdate() {
}
else if (!this->rfidHasTrain && !this->videoHasTrain)
{
this->rfidSourceInfo
if (this->vecTrain.size() < this->deviceWarnConfig_.min_train_size
&& this->iDirection > 0
&& (this->rfidSourceInfo.size() > 128 || this->vecTrain.size() > 1))
this->queueWarnInfo_->push("火车驶过疑似RFID设备故障读取到的车厢号有丢失");
this->initParam();
emit this->InfoSignals("火车离开了");
}

View File

@ -19,12 +19,14 @@ class ReadComThread : public QThread{
Q_OBJECT
public:
ReadComThread(MQueue<TrainInfo> *queueTrainInfo,
MQueue<QString> *queueWarnInfo,
QObject *parent = nullptr);
~ReadComThread() {};
void run() override;
private:
MQueue<TrainInfo> *queueTrainInfo_ = nullptr;
MQueue<QString> *queueWarnInfo_ = nullptr;
MQueue<TrainInfo> queueTmpTrainInfo_{}; // RFID临时信息队列
QSerialPort *serial_; //串口
bool auto_reconnect_serial_ = false;
@ -32,6 +34,7 @@ private:
ai_matrix::BaseConfig baseConfig_;
ai_matrix::SServerConfig socketServerConfig_;
ai_matrix::DeviceWarnConfig deviceWarnConfig_;
TcpClient* tcpClient;
QTcpSocket* tcp_ = nullptr;
@ -101,6 +104,7 @@ public slots:
void getQueueDataThread();
void IdentifyTypeUpdate();
void upRfid(const QString &rfidInfo);
// void upWarn(const QString &warnInfo);
void tryToReconnect();
void readTestInfo(const QString &filePath);

View File

@ -14,11 +14,11 @@ UpResultThread::UpResultThread(MQueue<TrainInfo> *queueTrainInfo, QObject *paren
QString errorMessage = "";
if (!ConfigUtil::readBaseConfig(g_config_path, errorMessage, this->baseConfig_))
{
this->ErrorSignals(errorMessage);
emit this->ErrorSignals(errorMessage);
}
if (!ConfigUtil::readInterfaceConfig(g_config_path, errorMessage, this->interfaceConfig_))
{
this->ErrorSignals(errorMessage);
emit this->ErrorSignals(errorMessage);
}
}
@ -68,7 +68,7 @@ bool UpResultThread::upWeb(TrainInfo &trainInfo)
Json::StreamWriterBuilder writer;
std::string str = Json::writeString(writer, arrayObj);
this->InfoSignals("" + QString::fromStdString(trainInfo.strOrder) + "发送web: " + QString::fromStdString(str));
emit this->InfoSignals("" + QString::fromStdString(trainInfo.strOrder) + "发送web: " + QString::fromStdString(str));
httplib::Client cli(this->interfaceConfig_.httpIp.toStdString(), this->interfaceConfig_.httpPort);
cli.set_connection_timeout(3, 0);
@ -100,23 +100,23 @@ bool UpResultThread::upWeb(TrainInfo &trainInfo)
{
if (root["msg"].asString() == "请求未授权") {
this->WarnSignals("" + QString::fromStdString(trainInfo.strOrder) + "因请求未授权而上传识别结果失败重新请求token。");
emit this->WarnSignals("" + QString::fromStdString(trainInfo.strOrder) + "因请求未授权而上传识别结果失败重新请求token。");
if (!this->getToken()) return false;
return this->upWeb(trainInfo);
}
this->ErrorSignals("" + QString::fromStdString(trainInfo.strOrder) + "节,识别结果上传失败,原因:" + QString::fromStdString(root["msg"].asString()));
emit this->ErrorSignals("" + QString::fromStdString(trainInfo.strOrder) + "节,识别结果上传失败,原因:" + QString::fromStdString(root["msg"].asString()));
}
}
else
{
this->ErrorSignals("" + QString::fromStdString(trainInfo.strOrder) + "识别结果上传失败返回数据解析异常返回数据非json" + QString::fromStdString(res->body));
emit this->ErrorSignals("" + QString::fromStdString(trainInfo.strOrder) + "识别结果上传失败返回数据解析异常返回数据非json" + QString::fromStdString(res->body));
}
}
else
{
this->ErrorSignals("" + QString::fromStdString(trainInfo.strOrder) + "节,识别结果上传失败,原因:" + QString::number(res->status) + " - " + QString::fromStdString(res->body));
emit this->ErrorSignals("" + QString::fromStdString(trainInfo.strOrder) + "节,识别结果上传失败,原因:" + QString::number(res->status) + " - " + QString::fromStdString(res->body));
if (res->status == 401) {
this->WarnSignals("因请求未授权而上传识别结果失败重新请求token。");
emit this->WarnSignals("因请求未授权而上传识别结果失败重新请求token。");
this->getToken();
return this->upWeb(trainInfo);
}
@ -124,12 +124,12 @@ bool UpResultThread::upWeb(TrainInfo &trainInfo)
}
else
{
this->ErrorSignals("" + QString::fromStdString(trainInfo.strOrder) + "节,上传数据失败,请检查网络,或者上传地址!");
emit this->ErrorSignals("" + QString::fromStdString(trainInfo.strOrder) + "节,上传数据失败,请检查网络,或者上传地址!");
}
}
catch (std::exception &e)
{
this->ErrorSignals("" + QString::fromStdString(trainInfo.strOrder) + "节,上传识别结果失败,原因:" + QString::fromStdString(e.what()));
emit this->ErrorSignals("" + QString::fromStdString(trainInfo.strOrder) + "节,上传识别结果失败,原因:" + QString::fromStdString(e.what()));
}
return false;
}
@ -173,17 +173,17 @@ bool UpResultThread::getToken()
this->webToken = root["token_type"].asString();
this->webToken.append(" ");
this->webToken.append(root["access_token"].asString());
this->InfoSignals("已获取到web token");
emit this->InfoSignals("已获取到web token");
return true;
}
else
{
this->ErrorSignals("获取web token失败原因" + QString::fromStdString(res->body));
emit this->ErrorSignals("获取web token失败原因" + QString::fromStdString(res->body));
}
}
else
{
this->ErrorSignals("获取web token返回数据解析异常返回数据非json。详细" + QString::fromStdString(res->body));
emit this->ErrorSignals("获取web token返回数据解析异常返回数据非json。详细" + QString::fromStdString(res->body));
}
}
}
@ -193,12 +193,12 @@ bool UpResultThread::getToken()
// if (err == httplib::Error::Connection) {
// std::cout << " (连接出错)" << std::endl;
// }
this->ErrorSignals("获取web token失败请检查网络或请求地址。详细" + QString::fromStdString(to_string(err)));
emit this->ErrorSignals("获取web token失败请检查网络或请求地址。详细" + QString::fromStdString(to_string(err)));
}
}
catch (std::exception &e)
{
this->ErrorSignals("获取授权失败,原因:" + QString::fromStdString(e.what()));
emit this->ErrorSignals("获取授权失败,原因:" + QString::fromStdString(e.what()));
}
return false;
}

View File

@ -0,0 +1,204 @@
//
// Created by Mr.V on 2024/4/3.
//
#include "UpWarnThread.h"
UpWarnThread::UpWarnThread(MQueue<QString> *queueWarnInfo, QObject *parent) :
QThread(parent)
{
this->queueWarnInfo_ = queueWarnInfo;
// 配置文件读取
QString errorMessage = "";
if (!ConfigUtil::readBaseConfig(g_config_path, errorMessage, this->baseConfig_))
{
emit this->ErrorSignals(errorMessage);
}
if (!ConfigUtil::readInterfaceConfig(g_config_path, errorMessage, this->interfaceConfig_))
{
emit this->ErrorSignals(errorMessage);
}
}
void UpWarnThread::run()
{
while (true)
{
while (!this->queueWarnInfo_->isEmpty())
{
QString info = this->queueWarnInfo_->pop();
if (!this->upWarn(info))
{
}
}
QThread::sleep(1);
}
}
/**
* @brief:Http发送RFID设备异常
* @paraminfoRFID的原始数据
* @return: :true
* :false
*/
bool UpWarnThread::upWarn(const QString &info)
{
try {
Json::Value arrayObj; //构建对象
arrayObj["tainsModule"] = "2";
arrayObj["networkStatus"] = "正常";
arrayObj["devName"] = "RFID设备";
arrayObj["devSn"] = this->baseConfig_.trackName + "股道";
arrayObj["cpuData"] = "";
arrayObj["memoryUsage"] = "";
arrayObj["devRunningStatus"] = "异常";
arrayObj["devCheckResult"] = info.toStdString();
arrayObj["devIp"] = "";
arrayObj["devAccount"] = "";
Json::Value trainParams;
trainParams["poundNo"] = std::to_string(this->baseConfig_.trackName);
arrayObj["trainParams"] = trainParams;
Json::StreamWriterBuilder writer;
std::string str = Json::writeString(writer, arrayObj);
this->WarnSignals("根据RFID反馈的信号判断疑似丢失车厢磁条标签。已发送web: " + QString::fromStdString(str));
httplib::Client cli(this->interfaceConfig_.httpIp.toStdString(), this->interfaceConfig_.httpPort);
cli.set_connection_timeout(3, 0);
cli.set_read_timeout(3, 0);
httplib::Headers header;
httplib::Params params;
header.emplace("blade-auth", this->webToken);
header.emplace("charset", "utf-8");
//header.emplace("Content-Type", "application/json");
auto res = cli.Post(this->interfaceConfig_.upWarningPath.toStdString(), header, str, "application/json");
if (res)
{
if (res->status == 200)
{
emit this->InfoSignals("反馈报警信息web返回: " + QString::fromStdString(res->body));
Json::CharReaderBuilder readerBuilder;
std::istringstream iss(res->body);
Json::Value root;
std::string errs;
bool parsingSuccessful = Json::parseFromStream(readerBuilder, iss, &root, &errs);
if (parsingSuccessful)
{
if (root["success"].asBool())
{
return true;
}
else
{
if (root["msg"].asString() == "请求未授权") {
emit this->WarnSignals("反馈报警信息因请求未授权而上传识别结果失败重新请求token。");
if (!this->getToken()) return false;
return this->upWarn(info);
}
emit this->ErrorSignals("报警信息上传失败,原因:" + QString::fromStdString(root["msg"].asString()));
}
}
else
{
emit this->ErrorSignals("报警信息上传失败返回数据解析异常返回数据非json" + QString::fromStdString(res->body));
}
}
else
{
emit this->ErrorSignals("报警信息上传失败,原因:" + QString::number(res->status) + " - " + QString::fromStdString(res->body));
if (res->status == 401) {
emit this->WarnSignals("报警信息上传失败重新请求token。");
this->getToken();
return this->upWarn(info);
}
}
}
else
{
emit this->ErrorSignals("报警信息,上传数据失败,请检查网络,或者上传地址!");
}
}
catch (std::exception &e)
{
emit this->ErrorSignals("报警信息,上传识别结果失败,原因:" + QString::fromStdString(e.what()));
}
return false;
}
/**
* @brief:Http获取授权
* @param
* @return:
*/
bool UpWarnThread::getToken()
{
try
{
httplib::Client cli(this->interfaceConfig_.httpIp.toStdString(), this->interfaceConfig_.httpPort);
cli.set_connection_timeout(0, 300 * 1000);
cli.set_read_timeout(0,300*1000);
httplib::Headers header;
httplib::Params params;
header.emplace("Authorization", "Basic Y2xpZW50X2VudGVycHJpc2U6Y2xpZW50X2VudGVycHJpc2Vfc2VjcmV0");
params.emplace("username", this->interfaceConfig_.username.toStdString());
params.emplace("password", this->interfaceConfig_.password.toStdString());
params.emplace("tenantId", "000000");
params.emplace("grant_type", "password");
auto res = cli.Post("/api/blade-auth/oauth/token", header, params);
if (res)
{
if (res->status == 200)
{
Json::CharReaderBuilder readerBuilder;
std::istringstream iss(res->body);
Json::Value root;
std::string errs;
bool parsingSuccessful = Json::parseFromStream(readerBuilder, iss, &root, &errs);
if (parsingSuccessful)
{
if (!root.get("token_type", "").asString().empty())
{
this->webToken = root["token_type"].asString();
this->webToken.append(" ");
this->webToken.append(root["access_token"].asString());
emit this->InfoSignals("已获取到web token");
return true;
}
else
{
emit this->ErrorSignals("获取web token失败原因" + QString::fromStdString(res->body));
}
}
else
{
emit this->ErrorSignals("获取web token返回数据解析异常返回数据非json。详细" + QString::fromStdString(res->body));
}
}
}
else
{
auto err = res.error();
// if (err == httplib::Error::Connection) {
// std::cout << " (连接出错)" << std::endl;
// }
emit this->ErrorSignals("获取web token失败请检查网络或请求地址。详细" + QString::fromStdString(to_string(err)));
}
}
catch (std::exception &e)
{
emit this->ErrorSignals("获取授权失败,原因:" + QString::fromStdString(e.what()));
}
return false;
}

View File

@ -0,0 +1,43 @@
//
// Created by Mr.V on 2024/4/3.
//
#ifndef TRAIN_RFID_UPWARNTHREAD_H
#define TRAIN_RFID_UPWARNTHREAD_H
#include <QThread>
#include "common.h"
#include "MQueue.h"
#include "httplib.h"
#include "json.h"
#include "ConfigUtil.h"
using namespace ai_matrix;
class UpWarnThread : public QThread{
Q_OBJECT
public:
~UpWarnThread() {};
UpWarnThread(MQueue<QString> *queueWarnInfo, QObject *parent = nullptr);
void run() override;
private:
MQueue<QString> *queueWarnInfo_ = nullptr;
ai_matrix::BaseConfig baseConfig_;
ai_matrix::InterfaceConfig interfaceConfig_;
std::string webToken; //授权信息
bool upWarn(const QString &info);
bool getToken();
signals:
void DebugSignals(const QString &info);
void InfoSignals(const QString &info);
void WarnSignals(const QString &info);
void ErrorSignals(const QString &info);
};
#endif //TRAIN_RFID_UPWARNTHREAD_H