From: xue <2144439972@qq.com> Date: Sat, 25 Apr 2026 03:26:53 +0000 (+0800) Subject: 开机自动发送开始产测 X-Git-Url: http://git.snicker.com.cn/?a=commitdiff_plain;h=db408ddec058b538235333ad5e5bcdccae9e20bd;p=mirrors%2Ffactory_tool.git 开机自动发送开始产测 --- diff --git a/mainwindow.cpp b/mainwindow.cpp index f436833..a97a573 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -535,6 +535,32 @@ void MainWindow::readSerialData() if (line.startsWith("fac:")) { appendToLogFile(processLine); } + + // 设备打印 InitBroadcastService start:未在产测则自动等同点击「开始产测」;已在等待开机则直接视为就绪并进入 PMADDVOTE + { + const QString kInitBc = QStringLiteral("InitBroadcastService start"); + const bool hasInitBc = line.contains(kInitBc, Qt::CaseInsensitive) || + processLine.contains(kInitBc, Qt::CaseInsensitive); + if (hasInitBc && serial && serial->isOpen()) { + if (!isProductionTestRunning) { + qDebug() << "检测到 InitBroadcastService start,将自动开始产测流程"; + QTimer::singleShot(0, this, [this, kInitBc]() { + if (!serial || !serial->isOpen() || isProductionTestRunning) { + return; + } + ui->recvTextEdit->append(">>> 检测到 InitBroadcastService start,自动开始产测"); + appendToLogFile("=== 检测到 InitBroadcastService start,自动开始产测 ===\n"); + beginProductionTestSession(); + tryAdvanceProductionAfterBootKeywords(kInitBc); + }); + } else if (currentTestStep == TEST_WAIT_BOOT) { + tryAdvanceProductionAfterBootKeywords(line); + if (currentTestStep == TEST_WAIT_BOOT && processLine != line) { + tryAdvanceProductionAfterBootKeywords(processLine); + } + } + } + } // 开机检测(仅在未检测到开机时执行) // 同时检查原始行和去掉fac:前缀的行,确保能匹配到关键字 @@ -1930,30 +1956,42 @@ void MainWindow::tryAdvanceProductionAfterBootKeywords(const QString& data) return; } + const QString kInitBroadcast = QStringLiteral("InitBroadcastService start"); const QStringList keywords = configManager.getBootDetectionKeywords(); - if (keywords.isEmpty()) { + + QString matchedReason; + if (data.contains(kInitBroadcast, Qt::CaseInsensitive)) { + matchedReason = kInitBroadcast; + } else { + if (keywords.isEmpty()) { + return; + } + for (const QString& keyword : keywords) { + if (data.contains(keyword, Qt::CaseInsensitive)) { + matchedReason = keyword; + break; + } + } + } + + if (matchedReason.isEmpty()) { return; } - for (const QString& keyword : keywords) { - if (data.contains(keyword, Qt::CaseInsensitive)) { - qDebug() << "产测:检测到开机完成关键字:" << keyword << ",数据片段:" << data.left(120); - appendToLogFile(QString("=== 产测流程-检测到开机完成: %1 ===\n").arg(keyword)); + qDebug() << "产测:检测到开机完成:" << matchedReason << ",数据片段:" << data.left(120); + appendToLogFile(QString("=== 产测流程-检测到开机完成: %1 ===\n").arg(matchedReason)); - bootDetected = true; - currentTestStep = TEST_PMADDVOTE_INIT; + bootDetected = true; + currentTestStep = TEST_PMADDVOTE_INIT; - if (testTimeoutTimer->isActive()) { - testTimeoutTimer->stop(); - } + if (testTimeoutTimer->isActive()) { + testTimeoutTimer->stop(); + } - ui->statusbar->showMessage("设备已开机,正在发送 PMADDVOTE / ENTERTESTVIEW…", 3000); - ui->recvTextEdit->append(">>> 已检测到开机完成,进入 PMADDVOTE / ENTERTESTVIEW 初始化链(未发 AT^FACTORY=1)"); + ui->statusbar->showMessage("设备已开机,正在发送 PMADDVOTE / ENTERTESTVIEW…", 3000); + ui->recvTextEdit->append(">>> 已检测到开机完成,进入 PMADDVOTE / ENTERTESTVIEW 初始化链(未发 AT^FACTORY=1)"); - runPostFactoryProductionInit(); - return; - } - } + runPostFactoryProductionInit(); } void MainWindow::tryApplyProductionStartGreenAfterPmaddvoteOk(const QString& line) @@ -2376,45 +2414,17 @@ void MainWindow::on_openRecordsFolderButton_clicked() } } -void MainWindow::on_openButton_2_clicked() +void MainWindow::beginProductionTestSession() { - // 检查串口是否已打开 - if (!serial->isOpen()) { - QMessageBox::warning(this, "警告", "请先打开串口连接"); + if (isProductionTestRunning) { + qDebug() << "beginProductionTestSession: 已在产测中,忽略"; return; } - - if (isProductionTestRunning) { - // 如果正在测试,则停止测试 - lcdTestTimer->stop(); - motorTestTimer->stop(); - testTimeoutTimer->stop(); - gSensorIntervalTimer->stop(); - bluetoothTestTimer->stop(); - isProductionTestRunning = false; - postFactoryVoteSequenceStarted = false; - waitingPmaddvoteOkForGreenButton = false; - currentTestStep = TEST_IDLE; - - // 关闭测试日志文件 - if (testLogFile && testLogStream) { - *testLogStream << QString("=== 测试被用户停止: %1 ===\n").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")); - testLogStream->flush(); - } - closeTestLogFile(); - - ui->statusbar->showMessage("产测已停止", 2000); - qDebug() << "产测被用户停止"; - - // 恢复产测按钮状态 - 变回蓝色并启用 - ui->openButton_2->setStyleSheet("QPushButton { background-color: #4A90E2; color: white; padding: 5px 10px; border: none; border-radius: 3px; }"); - ui->openButton_2->setEnabled(true); - qDebug() << "产测停止 - 按钮已恢复蓝色并启用"; - + if (!serial || !serial->isOpen()) { + qDebug() << "beginProductionTestSession: 串口未打开,忽略"; return; } - // 开始产测流程 isProductionTestRunning = true; postFactoryVoteSequenceStarted = false; waitingPmaddvoteOkForGreenButton = false; @@ -2424,27 +2434,27 @@ void MainWindow::on_openButton_2_clicked() testDurationSecMap.clear(); currentTestStep = TEST_WAIT_BOOT; currentLcdColor = 1; // 从红色开始 - + // 在开始新测试前,尽量保存当前UI日志(如果有内容) saveRecvTextEditToLog(); productionDeviceMac.clear(); // 创建测试日志文件 createTestLogFile(); - + // 清空所有UI内容 ui->recvTextEdit->clear(); // 清空串口接收文本框 ui->sendTextEdit->clear(); // 清空发送文本框 ui->statusbar->clearMessage(); // 清空状态栏 - + // 重置开机检测状态 bootDetected = false; factoryModeChecked = false; versionInfoFetched = false; - + // 清空设备信息 ui->VerlineEdit->clear(); // 清空版本信息 - + // 重置弹窗状态 lcdTestPopupShown = false; motorTestPopupShown = false; @@ -2453,7 +2463,7 @@ void MainWindow::on_openButton_2_clicked() deepsleepTestPopupShown = false; isWaitingForUserConfirm = false; keyTestStarted = false; - + // 重置状态指示器 updateTestStatus("lcd", STATUS_UNTESTED); updateTestStatus("tp", STATUS_UNTESTED); @@ -2468,14 +2478,14 @@ void MainWindow::on_openButton_2_clicked() updateTestStatus("bluetooth", STATUS_UNTESTED); updateTestStatus("sechip", STATUS_UNTESTED); updateTestStatus("gps", STATUS_UNTESTED); - + qDebug() << "已清空所有UI内容,准备开始新的产测"; - + ui->statusbar->showMessage("开始产测流程...", 2000); qDebug() << "=== 开始产测流程 ==="; qDebug() << "流程: 等待开机完成 → 跳过 AT^FACTORY=1 → PMADDVOTE/ENTERTESTVIEW → 各测试项 → 完成后弹窗确认等"; qDebug() << "LCD测试: 仅发送 AT^LCDTEST=1"; - + // 不再发送 AT^FACTORY=1:固件侧常会触发整机重启;在开机完成后再发 PMADDVOTE / ENTERTESTVIEW qDebug() << "Step 1: 等待串口开机关键字(bootDetectionKeywords),然后 PMADDVOTE / ENTERTESTVIEW"; @@ -2498,6 +2508,47 @@ void MainWindow::on_openButton_2_clicked() } } +void MainWindow::on_openButton_2_clicked() +{ + // 检查串口是否已打开 + if (!serial->isOpen()) { + QMessageBox::warning(this, "警告", "请先打开串口连接"); + return; + } + + if (isProductionTestRunning) { + // 如果正在测试,则停止测试 + lcdTestTimer->stop(); + motorTestTimer->stop(); + testTimeoutTimer->stop(); + gSensorIntervalTimer->stop(); + bluetoothTestTimer->stop(); + isProductionTestRunning = false; + postFactoryVoteSequenceStarted = false; + waitingPmaddvoteOkForGreenButton = false; + currentTestStep = TEST_IDLE; + + // 关闭测试日志文件 + if (testLogFile && testLogStream) { + *testLogStream << QString("=== 测试被用户停止: %1 ===\n").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")); + testLogStream->flush(); + } + closeTestLogFile(); + + ui->statusbar->showMessage("产测已停止", 2000); + qDebug() << "产测被用户停止"; + + // 恢复产测按钮状态 - 变回蓝色并启用 + ui->openButton_2->setStyleSheet("QPushButton { background-color: #4A90E2; color: white; padding: 5px 10px; border: none; border-radius: 3px; }"); + ui->openButton_2->setEnabled(true); + qDebug() << "产测停止 - 按钮已恢复蓝色并启用"; + + return; + } + + beginProductionTestSession(); +} + // 执行录音测试(单轮;有等级标准则 mic level 与标准比较一次,无标准则只采样不判等级) void MainWindow::performAudioTest() { @@ -2597,11 +2648,13 @@ void MainWindow::checkAudioTestResult(const QString& data) qDebug() << "发送AT^AUDIOTEST=6"; } - // 固件在 =6 后异步停止 AI 语音/解码线程;稍候再判定/切下一项,减轻与后续 AT 的竞态。 + // 顺序说明:上面已立刻发送 AT^AUDIOTEST=6,这一步才是「通知固件停止录音」。 + // 固件收到 =6 后会异步停线程/拆音频(需数百 ms~1s+);此处延迟后再 skipToNext/发电池 AT, + // 避免与收尾并发导致异常。日志里在延迟期间仍可能出现 [AudioTest]/mic level,那是设备仍在打印,并非未先关再进下一项。 static const int kMsAfterAudiotestStop = 2000; - ui->statusbar->showMessage(QStringLiteral("录音本轮已结束,等待设备完成音频收尾…"), 2000); - appendToLogFile(QString(">>> 等待 %1 ms 后再继续(避开 AUDIOTEST 异步停止)\n").arg(kMsAfterAudiotestStop)); - qDebug() << "录音测试:已发 AUDIOTEST=6," << kMsAfterAudiotestStop << "ms 后再判定/切下一项"; + ui->statusbar->showMessage(QStringLiteral("已发送停止录音(AT^AUDIOTEST=6),等待设备收尾…"), 2000); + appendToLogFile(QString(">>> 已发送 AT^AUDIOTEST=6;延迟 %1 ms 待设备异步停止完毕,再进入下一项测试\n").arg(kMsAfterAudiotestStop)); + qDebug() << "录音测试:已发 AUDIOTEST=6," << kMsAfterAudiotestStop << "ms 后再进入下一项"; QTimer::singleShot(kMsAfterAudiotestStop, this, [this, micLevel]() { if (!isProductionTestRunning || currentTestStep != TEST_AUDIO) { diff --git a/mainwindow.h b/mainwindow.h index c3275a0..9bb4747 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -250,6 +250,7 @@ private: void finalizeGsensorTest(); void stopGsensorCollectionAndFinalizeSoon(const QString& reasonSuffix); + void beginProductionTestSession(); // 开始产测(与「开始产测」按钮启动逻辑一致,串口须已打开) void finalizeAfterProductionResultDialog(); // 恢复产测按钮并 clearProductionTestState // G-sensor XYZ窗口采集状态