#include "myiothread.h" #include #include #include #include #include #include #include string snErrorsnError("snErrNoSn"); QQueue writeCommondPack; MyIoThread::~MyIoThread() { io_runflag = false; for( int i = 0 ; i < vector_camera_signal_pack_ptr.size();i++) { if(vector_camera_signal_pack_ptr.at(i)) delete vector_camera_signal_pack_ptr.at(i); } wait(100); exit(); qDebug() << "[INFO] " << " ~MyIoThread success! "; } void writeToDataSheetCSV(bool isOK); //IO线程 void MyIoThread::run() { bool isInitTcp = true; int times = 0; m_timer = new QTimer(); m_timer->setInterval(8000); connect(m_timer, &QTimer::timeout, [this] { qDebug() << "[TCP Error] " << QString::fromUtf8("注意心跳发送超时") << endl; }); if (m_IoType == "Heart")//心跳线程 { m_heartCmd = bridge.back.json.tcp.heartCmd; while (io_runflag) { QMutexLocker locker(m_iomutex); QString cmd1 = m_heartCmd;//心跳 bridge.back.sendFinsMsg("writeHeart_DM8054_1"); if (bridge.back.sendFinsMsg(cmd1)) { m_timer->setInterval(8000); m_timer->start(); } QThread::msleep(100); } } else//解析fins线程 { //初始化 m_readAllCmd = bridge.back.json.tcp.finstcp_readAllCmd; /*for (int i = 0; i < 1000; i++) bridge.back.sendFinsMsg( QString::fromStdString("write_DM" + to_string(bridge.back.json.tcp.startPos + i) + "_0"));*/ workThread = new threadConroller(); for (auto thread : threadlist) thread->cameraImgsPtr = &workThread->cameraImgs; msleep(1000); while (io_runflag) { reciveCommond(); QThread::msleep(1); } } } // 写入数据 void MyIoThread::writeCommond() { while( !writeCommondPack.isEmpty()) { //qDebug() << __FUNCTION__ << " line:" << __LINE__ << " writeCommondPack len:" << writeCommondPack.length(); QByteArray write_byte = writeCommondPack.dequeue(); if ( !bridge.back.sendFinsMsg(write_byte) ) { qCritical() << "[TCP] " << " finstcp_ptr reciveData error!"; return; } } } void MyIoThread::reciveCommond() { auto start = std::chrono::high_resolution_clock::now(); QByteArray byte = m_readAllCmd.toUtf8(); // 设置 从起始位开始读取的指令 if (!bridge.back.sendFinsMsg(byte)) { qCritical() << "[TCP] " << " finstcp_ptr reciveData error!"; } // 读取到的信息解析 QByteArray readByte; if (!bridge.back.reciveFinsMsg(readByte)) { qCritical() << "[TCP] " << " finstcp_ptr sendData error!"; } auto end = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast(end - start); //std::cout << "cost: " << duration.count() << " mm" << std::endl; tLocker.reFreshLocker(readByte); decodeCameraCMD(readByte); workThread->snDatas.checkSnFromWaittingVec(readByte); } void MyIoThread::setIOMutex(QMutex *mutex) { m_iomutex = mutex; } void MyIoThread::setStationObject( QJsonObject camera_obj) { QVector camera_trigger_cmds; QJsonArray stationlist = camera_obj.value("stationlist").toArray(); for ( int i = 0; i < stationlist.size(); i++ ) { QJsonObject station_obj = stationlist.at(i).toObject(); QJsonArray cameramodulelist = station_obj.value("cameramodulelist").toArray(); QString stationKey = station_obj.value("key").toString(); #if 1 for( int val = 0 ; val < cameramodulelist.size();val++) { trigger_camera_pack *m_pack = new trigger_camera_pack; QJsonObject m_obj = cameramodulelist.at(val).toObject(); QString trigger_camera_name = m_obj.value("key").toString(); QJsonArray trigger_camera_startpos = m_obj.value("trigger_camera_startpos").toArray(); QJsonArray plc_feedback_msg = m_obj.value("plc_feedback_msg").toArray(); QString read_clear_plc_startpos = m_obj.value("read_clear_plc_startpos").toString(); QString clear_plc_data_msg = m_obj.value("clear_plc_data_msg").toString(); QString clear_camera_startpos_flag = m_obj.value("clear_camera_startpos_flag").toString(); if(stationKey == m_stationKey) m_StationCameraIndexMap.insert(trigger_camera_name, 0); // 添加相机名称 if ( !trigger_camera_name.isEmpty() ) m_pack->trigger_camera_name = trigger_camera_name; if ( !trigger_camera_startpos.isEmpty()) { m_pack->trigger_camera_startpos = trigger_camera_startpos; } if ( !plc_feedback_msg.isEmpty() ) { m_pack->plc_feedback_msg = plc_feedback_msg; } if( !read_clear_plc_startpos.isEmpty()) { QString clear_startpos = read_clear_plc_startpos.split("_")[0]; QString clear_value = read_clear_plc_startpos.split("_")[1]; if ( !clear_startpos.isEmpty() && !clear_value.isEmpty()) { m_pack->read_clear_plc_startpos = clear_startpos; m_pack->read_clear_plc_value = clear_value; } } if( !clear_plc_data_msg.isEmpty()) { m_pack->clear_plc_data_msg = clear_plc_data_msg; } // 是否清楚当前点位的信号 if( !clear_camera_startpos_flag.isEmpty()) { m_pack->clear_camera_startpos_flag = clear_camera_startpos_flag; } vector_camera_signal_pack_ptr.push_back(m_pack); // 添加 } // #endif //if (stationKey == m_stationKey) //{ //获取write指令 QJsonObject writeCmdObject = station_obj.value("plcwrite_area").toObject(); QString snOkCmd = writeCmdObject.value("snOkCmd").toString(); QString snErrorCmd = writeCmdObject.value("snErrorCmd").toString(); QString overOkCmd = writeCmdObject.value("overOkCmd").toString(); QString overErrorCmd = writeCmdObject.value("overErrorCmd").toString(); QString dateCmd = writeCmdObject.value("dateCmd").toString(); writeCmdMap.insert("snOkCmd", snOkCmd); writeCmdMap.insert("snErrorCmd", snErrorCmd); writeCmdMap.insert("overOkCmd", overOkCmd); writeCmdMap.insert("overErrorCmd", overErrorCmd); writeCmdMap.insert("dateCmd", dateCmd); //qDebug() << m_stationKey; m_cameralist = cameramodulelist; cameraSize = cameramodulelist.size(); //qDebug() << cameraSize; readPlcCmd = station_obj.value("plcread_area").toObject(); m_readAllCmd = readPlcCmd.value("finstcp_readAllCmd").toString(); writePlcCmd = station_obj.value("plcwrite_area").toObject(); //} //addReadAndWritePlcCmd(stationKey, readPlcCmd, writePlcCmd); } } void MyIoThread::writeSnFromString(string SN, int startPos, bool highLowConversion) { std::vectorasciiCodes; for (auto a : SN) asciiCodes.push_back(toascii(a)); if (highLowConversion == false) for (int i = 0; i < asciiCodes.size(); i += 2) { if (i != asciiCodes.size() - 1) bridge.back.sendFinsMsg("write_DM" + QString::number(startPos + i / 2) + "_" + QString::number(asciiCodes[i + 1] * 256 + asciiCodes[i]));//SN else bridge.back.sendFinsMsg("write_DM" + QString::number(startPos + i / 2) + "_" + QString::number(asciiCodes[i] * 256));//SN } else for (int i = 0; i < asciiCodes.size(); i += 2)//未测试 { if (i != asciiCodes.size() - 1) bridge.back.sendFinsMsg("write_DM" + QString::number(startPos + i / 2) + "_" + QString::number(asciiCodes[i] * 256));//SN else bridge.back.sendFinsMsg("write_DM" + QString::number(startPos + i / 2) + "_" + QString::number(asciiCodes[i + 1] * 256 + asciiCodes[i]));//SN } } void writeToDataSheetCSV(bool isOK) { QDateTime currentDateTime = QDateTime::currentDateTime(); //年-月-日 QString ymd = currentDateTime.toString("yyyy-MM-dd"); int h = currentDateTime.time().hour(); string hour; if (h < 10) hour = "0" + to_string(h); else hour = to_string(h); QStringList dataList; QString filePathCurrentDay =".//DataSheet//statics_" + ymd+".csv"; // 创建CSV文件 QFile file(filePathCurrentDay); if (!file.exists()) { QFile sourceFile(".//DataSheet//statics_default.csv"); if (!sourceFile.open(QIODevice::ReadOnly)) { qDebug() << "无法打开源文件: " << sourceFile.errorString(); } else { QString destinationFilePath = filePathCurrentDay; QFile destinationFile(destinationFilePath); if (!destinationFile.open(QIODevice::WriteOnly)) { qDebug() << "无法打开目标文件: " << destinationFile.errorString(); } else { QByteArray fileData = sourceFile.readAll(); destinationFile.write(fileData); sourceFile.close(); destinationFile.close(); } } } QList data; QStringList headers; // 打开CSV文件并写入数据 if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream stream(&file); ///// while (!stream.atEnd()) { QString line = stream.readLine(); QStringList fields = line.split(','); if (headers.isEmpty()) { // 如果headers为空,则当前行为标题行 headers = fields; } else { data.append(fields); } } for (int i = 0; i < data.size(); i++) { QStringList& row = data[i]; // 在当前行中检索字符串 if (row[0].contains(QString::fromStdString(hour), Qt::CaseInsensitive)) { // 匹配到字符串,进行修改 if (row.size() >= 4) { int goods = row[1].toInt(); int bads = row[2].toInt(); double rate = row[3].toDouble(); if (isOK == true) goods++; else bads++; rate = row[1].toDouble() / (row[1].toDouble() + row[2].toDouble()); rate = round(rate * 100) / 100; row[1] = QString::number(goods); row[2] = QString::number(bads); row[3] = QString::number(rate*100); } } } } file.close(); QFile writeFile(filePathCurrentDay); if (!writeFile.open(QIODevice::WriteOnly | QIODevice::Text)) { qDebug() << "Error opening file for writing."; } QTextStream out(&writeFile); // 写入标题行 out << headers.join(",") << "\n"; // 写入修改后的数据行 for (const auto& row : data) { out << row.join(",") << "\n"; } writeFile.close(); //else // qWarning() << "无法打开CSV文件:" << filePath; } /// /// 检测QByteArray中某位置的值是否和输入一样,使用了绝对位置 /// /// 绝对位置 /// 想判断的值 /// QByteArray /// bool MyIoThread::checkTrigger(int dmPos, int value, QByteArray byte) { int triggerPos = (dmPos - bridge.back.json.tcp.startPos) * 2 + 1; if (byte.size() < triggerPos) return false; if (byte.at(triggerPos) == value) { if (tLocker.checkLocker(triggerPos) == false) return false; tLocker.adddLocker(triggerPos); return true; } else return false; }/// /// 目前只负责检测fins信号,拍照和传递数据到等待队列 /// /// 从reciveCommond传入,从fins(JSON->finstcp_readAllCmd)读取的数据 void MyIoThread::decodeCameraCMD(QByteArray byte) { if ( byte.isEmpty() ) return; if (checkTrigger(9200, 1, byte) == true)//后段主体1 { int snPos = 9300; bridge.back.sendFinsMsg("write_DM9200_0");//触发信号清零 bridge.back.sendFinsMsg("write_DM9201_1");//开始检测信号 /////////数据初始化//////// detData* data = dController.insertDetData("2.5D-1", "2.5D-1-Thread", workThread->snDatas.readSnFromQByteArray(byte, snPos, false, true, 0), 0); // qDebug() << "[ Station 10 ] " << QString::fromUtf8("2.5D1第一次拍照开始 timeCode:") << data->timeCode; /////////SN码读取操作/////// if (!data->SNcode.compare(snErrorsnError))//查不到SN,送到snWaittingVec继续查询 workThread->snDatas.snWaittingVec.push_back({ data->timeCode ,data->SNcode,snPos }); ////////拍照//////////////// threadlist[0]->takeImg(data->timeCode, MyThread::normal, "", data, "write_DM9202_1"); workThread->addTask(data);//添加任务 emit SendStationLabel(1);//播放动画 } if (checkTrigger(9600, 1, byte) == true) //2D-2 8020负极 { int snPos = 9700; bridge.back.sendFinsMsg("write_DM9600_0");//触发信号清零 bridge.back.sendFinsMsg("write_DM9601_1");//开始检测信号 /////////数据初始化//////// detData* data = dController.insertDetData("2.5D-2", "2.5D-2-Thread", workThread->snDatas.readSnFromQByteArray(byte, snPos, false, true, 0), 0); // qDebug() << "[ Station 10 ] " << QString::fromUtf8("2.5D2第一次拍照开始 timeCode:") << data->timeCode; /////////SN码读取操作/////// if (!data->SNcode.compare(snErrorsnError))//查不到SN,送到snWaittingVec继续查询 workThread->snDatas.snWaittingVec.push_back({ data->timeCode ,data->SNcode,snPos }); ////////拍照//////////////// threadlist[1]->takeImg(data->timeCode, MyThread::normal, "", data, "write_DM9602_1"); workThread->addTask(data);//添加任务 emit SendStationLabel(1);//播放动画 } if (checkTrigger(9400, 1, byte) == true)//汇总1 { bridge.back.sendFinsMsg("write_DM9400_0"); ///////////将数据请求发往算法线程///////////// string SN=workThread->snDatas.readSnFromQByteArray(byte, 9500, -1, false, true, 0);//读SN码 /////////发送////////////// qDebug() << "汇总请求1 SN:" << QString::fromStdString(SN); cout << "summarry1 SN:" << SN <snDatas.readSnFromQByteArray(byte, 9900, -1, false, true, 0);//读SN码 /////////发送////////////// qDebug() << "汇总请求2 SN:" << QString::fromStdString(SN); cout << "summarry2 SN:" << SN << endl; requestSummary(SN, 400);//8095 } } void MyIoThread::requestSummary(std::string SN, int offset) { qDebug() << "汇总请求 SN:" << QString::fromStdString(SN); cout << "summarry SN:" << SN << endl; sqlDataStruct sqlData = workThread->sql->selectData(SN, 0);//请求数据库 bool isOK = true; if (sqlData.dataVec.size() == 0) { for (auto data : bridge.back.json.summaryData.datas) { QString messageBase = QString::fromStdString("writeInt_DM" + to_string(data.second.toInt() + offset) + "_"); bridge.back.sendFinsMsg(messageBase + "-99"); // "空" } } else { for (auto data : sqlData.dataVec) { QThread::msleep(10); auto it = bridge.back.json.summaryData.datas.find(QString::fromStdString(data.dataName)); if (it != bridge.back.json.summaryData.datas.end()) { std::string messageBase = "writeInt_DM" + to_string(it->second.toInt() + offset) + "_"; std::string messageBase2 = "write_DM" + to_string(it->second.toInt() + offset) + "_"; if (!data.valueText.compare("NULL") || data.valueText.empty()) { bridge.back.sendFinsMsg(QString::fromStdString(messageBase2 + "-1")); // "空" std::cout << data.dataName << " empty" << "SN" << SN << endl;// } else { int value = stoi(data.valueText); if (value < 0) value = -value; if (value < 10) { string finsSend(messageBase2 + std::to_string(value)); bridge.back.sendFinsMsg(QString::fromStdString(finsSend)); } else { string finsSend(messageBase + std::to_string(value)); bridge.back.sendFinsMsg(QString::fromStdString(finsSend)); } if (stoi(data.valueText) == 2) isOK = false; } } } } writeToDataSheetCSV(isOK); } // 防重入 void MyIoThread::checkReentrySign(QVector vec_value) { for( int i = 0; i < vector_camera_signal_pack_ptr.size(); i++) { QJsonArray trigger_camera_startpos = vector_camera_signal_pack_ptr.at(i)->trigger_camera_startpos; for ( int val = 0; val < trigger_camera_startpos.size(); val++ ) { QString trigger_startpos = trigger_camera_startpos.at(val).toString(); QString m_startpos = trigger_startpos.split("_")[0]; QString m_value = trigger_startpos.split("_")[1]; int trigger_index = m_startpos.mid(3,m_startpos.length()-3).toInt(); if(trigger_index < 0) { qCritical() << "[Error] " << " value is error! m_startpos:" << m_startpos; } else if( vec_value.size() > trigger_index ) { if ( vec_value.at(trigger_index) == 0 ) { // qDebug() << __FUNCTION__ << " line:" << " 00000 camera_reentry_sign:" << vector_camera_signal_pack_ptr.at(i)->camera_reentry_sign; vector_camera_signal_pack_ptr.at(i)->camera_reentry_sign = 0; // 赋值为0 // qDebug() << __FUNCTION__ << " line:" << " 11111 camera_reentry_sign:" << vector_camera_signal_pack_ptr.at(i)->camera_reentry_sign; } } } } } void MyIoThread::checkTriggerCamera(QVector vec_value) { for( int i = 0; i < vector_camera_signal_pack_ptr.size(); i++) { QString camera_key = vector_camera_signal_pack_ptr.at(i)->trigger_camera_name; QJsonArray trigger_camera_startpos = vector_camera_signal_pack_ptr.at(i)->trigger_camera_startpos; QJsonArray plc_feedback_msg = vector_camera_signal_pack_ptr.at(i)->plc_feedback_msg; // 反馈信号包 for ( int val = 0; val < trigger_camera_startpos.size(); val++ ) { QString trigger_startpos = trigger_camera_startpos.at(val).toString(); QString m_startpos = trigger_startpos.split("_")[0]; QString m_value = trigger_startpos.split("_")[1]; int trigger_index = m_startpos.mid(3,m_startpos.length()-3).toInt(); if(trigger_index < 0) { qCritical() << "[Error] " << " value is error! m_startpos:" << m_startpos; } else if ( vec_value.size() > trigger_index ) { if ( vec_value.at(trigger_index) == m_value.toInt() && vector_camera_signal_pack_ptr.at(i)->camera_reentry_sign == 0 ) { vector_camera_signal_pack_ptr.at(i)->camera_reentry_sign = 1; // 放重入 赋值为1 if(vector_camera_signal_pack_ptr.at(i)->clear_camera_startpos_flag == "true") { // 写清除当前信号 修改 if ( checkCameraTriggerLastPos(camera_key,trigger_startpos) ) { QString clear_signal = trigger_startpos.split("_")[0]; clear_signal = "write_" + clear_signal + "_0"; QByteArray m_byte = clear_signal.toUtf8(); if ( !bridge.back.sendFinsMsg(m_byte) ) { qCritical() << "[Error] " << " finstcp_ptr reciveData error! "; return; } // 写入反馈信号 QString trigger_startpos_signal = trigger_startpos.split("_")[0]; for ( auto iii = 0; iii < plc_feedback_msg.size(); iii++ ) { QStringList plc_feedback_msg_list = plc_feedback_msg.at(iii).toString().split("_"); if(plc_feedback_msg_list.size() != 4) { qWarning() << "[Error] " << " plc_feedback_msg_list num is error! plc_feedback_msg_list num:" << plc_feedback_msg_list.length(); } else { if ( plc_feedback_msg_list.contains(trigger_startpos_signal) ) { // 发送反馈信号 QString feedback_signal_type = plc_feedback_msg_list.at(1); QString feedback_signal_pos = plc_feedback_msg_list.at(2); QString feedback_signal_value = plc_feedback_msg_list.at(3); QString send_msg = feedback_signal_type + "_" + feedback_signal_pos + "_" + feedback_signal_value; QByteArray send_byte = send_msg.toUtf8(); if ( !bridge.back.sendFinsMsg(send_byte) ) { qCritical() << "[Error] " << " finstcp_ptr reciveData error! "; return; } } } } } } else { // 写反馈信号 QString clear_plc_data_msg = vector_camera_signal_pack_ptr.at(i)->clear_plc_data_msg; QByteArray m_byte = clear_plc_data_msg.toUtf8(); if ( !bridge.back.sendFinsMsg(m_byte) ) { qCritical() << "[Error] " << " finstcp_ptr reciveData error! "; return; } } // 添加被触发的相机名称 QString trigger_camera_name = vector_camera_signal_pack_ptr.at(i)->trigger_camera_name; if ( !trigger_camera_name.isEmpty() ) { QByteArray camera_Byte = trigger_camera_name.toUtf8(); IoCommondPack.append(camera_Byte); } } } } } } bool MyIoThread::checkCameraTriggerLastPos ( QString camera_key,QString camera_trigger_pos) { // qDebug() << " ------------------------------- checkCameraTriggerLastPos camera_key:" << camera_key << " camera_trigger_pos:" << camera_trigger_pos; int camera_index = 0; for ( int i = 0; i < m_cameralist.size(); i++ ) { QJsonObject m_obj = m_cameralist.at(i).toObject(); QString camera_key = m_obj.value("key").toString(); QJsonArray trigger_camera_startpos = m_obj.value("trigger_camera_startpos").toArray(); for ( int val = 0; val < trigger_camera_startpos.size(); val++ ) { QString trigger_pos = trigger_camera_startpos.at(val).toString(); if ( camera_trigger_pos == trigger_pos ) { camera_index = i; // qDebug() << " ------------- camera_index:" << camera_index ; break; } } } QJsonObject m_obj = m_cameralist.at(camera_index).toObject(); QString m_key = m_obj.value("key").toString(); // qDebug() << " ------------- camera_key:" << camera_key << " ----------- m_key:" << m_key; if( camera_key == m_key ) { return true; } return false;; } void MyIoThread::setReadAndWritePlcCmd( QJsonObject readArray, QJsonObject writeArray) { readPlcCmd = readArray; writePlcCmd = writeArray; } void MyIoThread::setCameraIndexMap( QMap cameraIndexMap) { m_StationCameraIndexMap = cameraIndexMap; m_StationCameraIndexMap.detach(); } void MyIoThread::clearPlcData(QVector vec_value ) { for ( int i = 0; i < vector_camera_signal_pack_ptr.size(); i++ ) { QString read_clear_plc_startpos = vector_camera_signal_pack_ptr.at(i)->read_clear_plc_startpos; QString read_clear_plc_value = vector_camera_signal_pack_ptr.at(i)->read_clear_plc_value; QString clear_plc_data_msg = vector_camera_signal_pack_ptr.at(i)->clear_plc_data_msg; int trigger_index = read_clear_plc_startpos.mid(3,read_clear_plc_startpos.length()-3).toInt(); if ( trigger_index < 0 ) { qCritical() << "[Error] " << " value is error! read_clear_plc_startpos:" << read_clear_plc_startpos; } else if( vec_value.size() > trigger_index ) { if ( vec_value.at(trigger_index) == read_clear_plc_value.toInt() ) { // 所有位归零 if(!clear_plc_data_msg.isEmpty()) { QByteArray mm_byte = clear_plc_data_msg.toUtf8(); // 0-9 if ( !bridge.back.sendFinsMsg(mm_byte) ) { qCritical() << "[Error] " << " finstcp_ptr reciveData error!"; } } } } } } /*************************读取io包******************************/ ReadPackThread::~ReadPackThread() { runflag = true; exit(); wait(1); qDebug() << "[INFO] " << "ReadPackThread delete success! " ; } void ReadPackThread::run() { while (true) { if(runflag) { return; } while (!IoCommondPack.isEmpty()) { QMutexLocker locker ( m_mutex ); QByteArray byte = IoCommondPack.dequeue(); QString cameraName = QString(byte); } QThread::msleep(1); } } bool ReadPackThread::runModule(QString cameraName) { // qDebug() << __FUNCTION__ << " line:" << __LINE__ << " cameraName:" << cameraName << " threadlist size:" << threadlist.size(); try { for ( int i = 0; i < threadlist.size();i++ ) { QString name = threadlist.at(i)->getName(); if ( name == cameraName ) { threadlist.at(i)->start(); break; } } } catch ( QString ev ) { qCritical() << "[Error] " << " ev:" << ev; } return true; } ///////////////////DEBUG////////////////////////////////