|
|
@@ -14,6 +14,10 @@ import java.util.TimerTask;
|
|
|
public class WorkTimer {
|
|
|
private static final Logger log = LoggerFactory.getLogger(WorkTimer.class);
|
|
|
|
|
|
+ /** 非 OK 状态需连续确认次数,避免 20→21 等过渡码被立刻判 NG */
|
|
|
+ private static final int NG_CONFIRM_NEEDED = 2;
|
|
|
+ private static int ngConfirmCount = 0;
|
|
|
+ private static int pendingNgStatusCode = -1;
|
|
|
|
|
|
private static Timer stopTimer = null;
|
|
|
private static Timer workTimer = null;
|
|
|
@@ -23,9 +27,9 @@ public class WorkTimer {
|
|
|
|
|
|
public static void start() {
|
|
|
if(workTimer != null){
|
|
|
- workTimer.cancel();
|
|
|
workTimer = null;
|
|
|
}
|
|
|
+ resetEndConfirm();
|
|
|
workTimer = new Timer();
|
|
|
workTimer.schedule(new WorkTimerTask(), 1000, 2000);
|
|
|
}
|
|
|
@@ -35,23 +39,13 @@ public class WorkTimer {
|
|
|
workTimer.cancel();
|
|
|
workTimer = null;
|
|
|
}
|
|
|
+ resetEndConfirm();
|
|
|
}
|
|
|
|
|
|
- /** 常态每 5 秒发送停止/复位报文(站号来自配置,默认 01) */
|
|
|
- public static void startStopTimer() {
|
|
|
- stopStopTimer();
|
|
|
- stopTimer = new Timer("ateq-stop-timer", true);
|
|
|
- stopTimer.schedule(new StopTimerTask(), 0, 5000);
|
|
|
- log.info("已启动气密仪停止/复位定时器(5s)");
|
|
|
- }
|
|
|
-
|
|
|
- /** 点击启动前停止复位定时器,避免与测程抢串口 */
|
|
|
- public static void stopStopTimer() {
|
|
|
- if (stopTimer != null) {
|
|
|
- stopTimer.cancel();
|
|
|
- stopTimer = null;
|
|
|
- log.info("已停止气密仪停止/复位定时器");
|
|
|
- }
|
|
|
+ /** 扫下一件 / 复位时清空结束确认状态 */
|
|
|
+ public static void resetEndConfirm() {
|
|
|
+ ngConfirmCount = 0;
|
|
|
+ pendingNgStatusCode = -1;
|
|
|
}
|
|
|
|
|
|
// 发送禁止运行的定时任务
|
|
|
@@ -59,12 +53,11 @@ public class WorkTimer {
|
|
|
@Override
|
|
|
public void run() {
|
|
|
try {
|
|
|
- if (MesClient.serialPortUtils == null || !MesClient.serialPortUtils.isOpen) {
|
|
|
- return;
|
|
|
+ if (MesClient.work_status == 0 || !MesClient.check_quality_result) {
|
|
|
+ ATEQ.stop(); // 发送重置命令, 禁止设备启动
|
|
|
}
|
|
|
- ATEQ.stop(); // 发送重置命令, 禁止设备启动
|
|
|
} catch (Exception e) {
|
|
|
- log.error("向设备发送禁止运行的定时任务报错: {}", e.getMessage());
|
|
|
+ log.error("向设备发送禁止运行的定时任务报错");
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -80,84 +73,42 @@ public class WorkTimer {
|
|
|
final ATEQ.MeasureResult measureResult = ATEQ.readMeasureResult();
|
|
|
log.info(measureResult.toString());
|
|
|
|
|
|
+ // 先在定时线程判定是否真正结束(OK 立刻结束;疑似 NG 需连续确认)
|
|
|
+ final boolean isEnd = resolveTestEnd(measureResult);
|
|
|
+
|
|
|
// 测完提交前:若稳压/测试时长为空,再读一次程序参数
|
|
|
- boolean willEnd = measureResult.isCycleEnd && MesClient.mesStartFlag == 1;
|
|
|
- ATEQ.FinalResult finalResult = null;
|
|
|
- if (willEnd) {
|
|
|
- log.info("2204周期结束 status=0x{}, bit5=1, bit0参考={}, 开始读LastTime 2303",
|
|
|
- String.format("%04X", measureResult.statusCode), measureResult.isPass);
|
|
|
- try {
|
|
|
- finalResult = ATEQ.readLastTimeFinalResult();
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("读LastTime最终结果失败: {}", e.getMessage());
|
|
|
- }
|
|
|
+ if (isEnd) {
|
|
|
if ((MesClient.curStabilizeTime == null || MesClient.curStabilizeTime.trim().isEmpty())
|
|
|
|| (MesClient.curTestDuration == null || MesClient.curTestDuration.trim().isEmpty())) {
|
|
|
log.info("提交前补读稳压时长/测试时长");
|
|
|
MesClient.loadAteqProgramTimes();
|
|
|
}
|
|
|
}
|
|
|
- final ATEQ.FinalResult endResult = finalResult;
|
|
|
|
|
|
SwingUtilities.invokeLater(new Runnable() {
|
|
|
@Override
|
|
|
public void run() {
|
|
|
try {
|
|
|
- boolean isEnd = false;
|
|
|
if (measureResult.isTesting) {
|
|
|
- MesClient.mesStartFlag = 1;
|
|
|
- MesClient.setStartButtonEnabled(false);
|
|
|
- MesClient.refreshRetestButton();
|
|
|
MesClient.setMenuStatus("测试中", 0);
|
|
|
- } else if (MesClient.mesStartFlag == 1 && measureResult.isCycleEnd) {
|
|
|
- // bit5=1:周期结束,用 2303 最终判定
|
|
|
- isEnd = true;
|
|
|
+ } else if (MesClient.mesStartFlag == 1 && !isEnd && !measureResult.isPass) {
|
|
|
+ MesClient.setMenuStatus(
|
|
|
+ String.format("结果确认中(0x%02X)...", measureResult.statusCode), 0);
|
|
|
}
|
|
|
|
|
|
- Double pressureVal = measureResult.pressureValue;
|
|
|
- String pressureUnit = measureResult.pressureUnit;
|
|
|
- Double leakVal = measureResult.leakValue;
|
|
|
- String leakUnit = measureResult.leakUnit;
|
|
|
- boolean isPass = measureResult.isPass;
|
|
|
-
|
|
|
- if (isEnd) {
|
|
|
- if (endResult != null) {
|
|
|
- isPass = endResult.isPass;
|
|
|
- if (endResult.pressureValue != null) {
|
|
|
- pressureVal = endResult.pressureValue;
|
|
|
- }
|
|
|
- if (endResult.pressureUnit != null && !endResult.pressureUnit.isEmpty()) {
|
|
|
- pressureUnit = endResult.pressureUnit;
|
|
|
- }
|
|
|
- if (endResult.leakValue != null) {
|
|
|
- leakVal = endResult.leakValue;
|
|
|
- }
|
|
|
- if (endResult.leakUnit != null && !endResult.leakUnit.isEmpty()) {
|
|
|
- leakUnit = endResult.leakUnit;
|
|
|
- }
|
|
|
- log.info("最终判定: 2204=0x{}, 2303=0x{}, OK/NG={}",
|
|
|
- String.format("%04X", measureResult.statusCode),
|
|
|
- String.format("%04X", endResult.statusWord),
|
|
|
- isPass ? "OK" : "NG");
|
|
|
- } else {
|
|
|
- isPass = false;
|
|
|
- log.error("未读到2303最终状态,按NG处理");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- String pressureText = formatValue(pressureVal, pressureUnit);
|
|
|
- String leakText = formatValue(leakVal, leakUnit);
|
|
|
+ String pressureText = formatValue(measureResult.pressureValue, measureResult.pressureUnit);
|
|
|
+ String leakText = formatValue(measureResult.leakValue, measureResult.leakUnit);
|
|
|
|
|
|
// 实时更新显示(不因单项失败而整页空白)
|
|
|
MesClient.param1.setText(pressureText);
|
|
|
MesClient.param2.setText(leakText);
|
|
|
|
|
|
if (isEnd) {
|
|
|
- if (leakVal != null && leakVal == 0 && !isPass) {
|
|
|
+ if (measureResult.leakValue == 0 && !measureResult.isPass) {
|
|
|
MesClient.param2.setText("9999");
|
|
|
}
|
|
|
|
|
|
- String lastRet = isPass ? "OK" : "NG";
|
|
|
+ String lastRet = measureResult.isPass ? "OK" : "NG";
|
|
|
|
|
|
if (lastRet.equals("OK")) {
|
|
|
MesClient.result.setText("OK");
|
|
|
@@ -175,10 +126,10 @@ public class WorkTimer {
|
|
|
testParam.setLineSn(MesClient.configParam.getLineSn());
|
|
|
testParam.setOprno(MesClient.configParam.getOprno());
|
|
|
testParam.setOprnoTitle(MesClient.configParam.getOprnoTitle());
|
|
|
- testParam.setParam1(pressureVal + "");
|
|
|
- testParam.setParam2(pressureUnit);
|
|
|
- testParam.setParam3(leakVal + "");
|
|
|
- testParam.setParam4(leakUnit);
|
|
|
+ testParam.setParam1(measureResult.pressureValue + "");
|
|
|
+ testParam.setParam2(measureResult.pressureUnit);
|
|
|
+ testParam.setParam3(measureResult.leakValue + "");
|
|
|
+ testParam.setParam4(measureResult.leakUnit);
|
|
|
testParam.setParam5(MesClient.programNo.getText().trim());
|
|
|
testParam.setResult(lastRet);
|
|
|
testParam.setDeviceType("ateq");
|
|
|
@@ -188,11 +139,9 @@ public class WorkTimer {
|
|
|
testParam.setStabilizeTime(byVal);
|
|
|
testParam.setTestDuration(csVal);
|
|
|
log.info("准备提交时长: by(稳压时长)={}, cs(测试时长)={}", byVal, csVal);
|
|
|
- int remarkStatus = endResult != null ? endResult.statusWord : measureResult.statusCode;
|
|
|
- testParam.setRemark(isPass ? "" : String.format("状态字:0x%04X", remarkStatus));
|
|
|
+ testParam.setRemark(measureResult.isPass ? "" : String.format("状态码:0x%02X", measureResult.statusCode));
|
|
|
testParam.setCreateTime(testDate);
|
|
|
JdbcUtils.insertTestRecord(testParam);
|
|
|
- MesClient.saveLastSubmittedSn(testParam.getSn());
|
|
|
|
|
|
if (MesClient.mes_enable) { // MES开启
|
|
|
JSONObject retObj = DataUtil.qmResultData(testParam);
|
|
|
@@ -224,6 +173,45 @@ public class WorkTimer {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 判定测试是否结束:
|
|
|
+ * - 0x00:测试中
|
|
|
+ * - 0x21:OK,立即结束
|
|
|
+ * - 其他非 00:疑似 NG,需连续 {@link #NG_CONFIRM_NEEDED} 次相同状态才结束,
|
|
|
+ * 期间若变为 0x21 则按 OK 结束,避免过渡码误判
|
|
|
+ */
|
|
|
+ private static boolean resolveTestEnd(ATEQ.MeasureResult measureResult) {
|
|
|
+ if (measureResult.isTesting) {
|
|
|
+ MesClient.mesStartFlag = 1;
|
|
|
+ resetEndConfirm();
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (MesClient.mesStartFlag != 1) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (measureResult.isPass) {
|
|
|
+ log.info("状态码 0x21,判定 OK");
|
|
|
+ resetEndConfirm();
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ // 疑似 NG:连续确认
|
|
|
+ if (pendingNgStatusCode != measureResult.statusCode) {
|
|
|
+ pendingNgStatusCode = measureResult.statusCode;
|
|
|
+ ngConfirmCount = 1;
|
|
|
+ log.info("疑似 NG 状态 0x{},等待确认 {}/{}",
|
|
|
+ String.format("%02X", measureResult.statusCode), ngConfirmCount, NG_CONFIRM_NEEDED);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ ngConfirmCount++;
|
|
|
+ log.info("疑似 NG 状态 0x{},确认 {}/{}",
|
|
|
+ String.format("%02X", measureResult.statusCode), ngConfirmCount, NG_CONFIRM_NEEDED);
|
|
|
+ if (ngConfirmCount >= NG_CONFIRM_NEEDED) {
|
|
|
+ resetEndConfirm();
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
private static String formatValue(Double value, String unit) {
|
|
|
if (value == null) {
|
|
|
return "";
|