Kaynağa Gözat

qm初始化

liuwei 8 saat önce
ebeveyn
işleme
91208d4021

+ 111 - 96
src/com/mes/plc/QmPlcPoller.java

@@ -16,7 +16,12 @@ import java.util.TimerTask;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
- * 框架气密 PLC 定时轮询:扫码进站 + 检测完成上传。
+ * 框架气密 PLC 轮询(每秒一次)。
+ * <pre>
+ * 扫码反馈=1 → 读框架码校验 → 写允许进站=1、扫码反馈=0
+ * 检测完成:记录上一秒;上一秒=0 且本秒=1 → 上传 OK/NG
+ * 上传成功后:MES 复位允许进站=0;检测完成由 PLC 厂家清
+ * </pre>
  */
 public class QmPlcPoller {
 
@@ -28,13 +33,12 @@ public class QmPlcPoller {
     private static QmPlcConfig config;
     private static QmS7Client s7Client;
 
+    /** 已允许进站,等待完成位 0→1 */
+    private static boolean armed;
+    private static boolean uploadDone;
+    /** 上一秒读到的检测完成 */
     private static boolean lastComplete;
-    private static boolean handshakeBusy;
-    private static boolean uploadBusy;
-    private static String currentSn = "";
-    private static boolean entered;
-    private static String lastCheckedSn = "";
-    private static String lastUploadedSn = "";
+    private static boolean busy;
 
     public static void start() {
         config = QmPlcConfig.load();
@@ -58,10 +62,9 @@ public class QmPlcPoller {
             }
         }, 1000, 1000);
         log.info("框架气密PLC轮询已启动 host={} DB{}", config.host, config.db);
-        SwingUtilities.invokeLater(() -> MesClient.setMenuStatus("等待PLC扫码", 0));
+        SwingUtilities.invokeLater(() -> MesClient.setMenuStatus("等待PLC扫码反馈(框架码从DB读取)", 0));
     }
 
-    /** 调试页改 IP 后刷新轮询连接 */
     public static void reloadHost(String host) {
         if (config != null && s7Client != null) {
             s7Client.updateHost(host);
@@ -80,13 +83,10 @@ public class QmPlcPoller {
     }
 
     public static void resetCycle() {
-        currentSn = "";
-        entered = false;
+        armed = false;
+        uploadDone = false;
         lastComplete = false;
-        handshakeBusy = false;
-        uploadBusy = false;
-        lastCheckedSn = "";
-        // lastUploadedSn 保留,防止清完成位失败后重复上传;新进站时覆盖
+        busy = false;
     }
 
     private static void pollOnce() {
@@ -95,9 +95,10 @@ public class QmPlcPoller {
         }
         try {
             handleScanFeedback();
-            handleComplete();
+            handleCompleteRisingEdge();
         } catch (Exception e) {
             log.error("框架气密PLC轮询异常: {}", e.getMessage());
+            updateStatus("PLC异常: " + e.getMessage(), false);
             if (s7Client != null) {
                 s7Client.close();
             }
@@ -106,8 +107,12 @@ public class QmPlcPoller {
         }
     }
 
+    /**
+     * 扫码反馈=1 → 校验 → 写允许进站=1 并清扫码反馈=0。
+     * 反馈保持为1时每秒可重试(不因 entered 卡住)。
+     */
     private static void handleScanFeedback() throws Exception {
-        if (handshakeBusy || entered || MesClient.work_status == 1) {
+        if (busy) {
             return;
         }
         boolean feedback = s7Client.readBit(config.scanFeedbackByte, config.scanFeedbackBit);
@@ -115,92 +120,82 @@ public class QmPlcPoller {
             return;
         }
 
-        handshakeBusy = true;
+        busy = true;
         try {
             String sn = s7Client.readFrameCode();
             if (sn == null || sn.isEmpty()) {
                 updateStatus("PLC框架码为空,保持扫码反馈待重试", false);
                 return;
             }
-            if (sn.equals(lastCheckedSn)) {
-                return;
-            }
+
+            log.info("PLC扫码反馈=1,读取框架码并校验 sn={}", sn);
+            updateStatus("读取框架码校验中: " + sn, true);
 
             JSONObject resp = DataUtil.checkQualityHttp(sn);
             if (resp == null) {
-                lastCheckedSn = sn;
                 s7Client.clearScanFeedback();
                 updateStatus("质量校验请求失败: " + sn, false);
                 return;
             }
             boolean pass = "true".equalsIgnoreCase(String.valueOf(resp.get("result")));
-            lastCheckedSn = sn;
-            if (pass) {
-                s7Client.allowEntryAndClearScanFeedback();
-                currentSn = sn;
-                entered = true;
-                lastComplete = s7Client.readBit(config.completeByte, config.completeBit);
-                SwingUtilities.invokeLater(() -> {
-                    MesClient.product_sn.setText(sn);
-                    MesClient.product_sn.setEditable(false);
-                    MesClient.check_quality_result = true;
-                    MesClient.work_status = 1;
-                    MesClient.tjFlag = 1;
-                    if (MesClient.result != null) {
-                        MesClient.result.setText("等待结果");
-                        MesClient.result.setForeground(Color.GRAY);
-                    }
-                });
-                updateStatus("允许进站: " + sn + ",等待检测完成", true);
-            } else {
+            if (!pass) {
                 s7Client.clearScanFeedback();
                 String msg = resp.getString("message");
                 if (msg == null || msg.isEmpty()) {
                     msg = "不可加工";
                 }
                 updateStatus(msg + " [" + sn + "]", false);
+                log.warn("校验未通过 sn={} msg={}", sn, msg);
+                return;
             }
+
+            s7Client.allowEntryAndClearScanFeedback();
+
+            // 同步当前完成位,避免进站瞬间把已是1的完成位当成本次0→1
+            lastComplete = s7Client.readBit(config.completeByte, config.completeBit);
+            armed = true;
+            uploadDone = false;
+
+            SwingUtilities.invokeLater(() -> {
+                if (MesClient.product_sn != null) {
+                    MesClient.product_sn.setText(sn);
+                    MesClient.product_sn.setEditable(false);
+                    MesClient.product_sn.setFocusable(false);
+                }
+                MesClient.check_quality_result = true;
+                MesClient.work_status = 1;
+                if (MesClient.result != null) {
+                    MesClient.result.setText("等待结果");
+                    MesClient.result.setForeground(Color.GRAY);
+                }
+            });
+
+            updateStatus("已允许进站: " + sn + ",等待检测完成0→1", true);
+            log.info("已写允许进站并清扫码反馈 sn={} lastComplete={}", sn, lastComplete);
         } finally {
-            handshakeBusy = false;
+            busy = false;
         }
     }
 
-    private static void handleComplete() throws Exception {
-        if (!entered || currentSn == null || currentSn.isEmpty()) {
-            lastComplete = false;
-            return;
-        }
-        if (uploadBusy) {
-            return;
-        }
-
+    /**
+     * 每秒读检测完成:上一秒=0 且本秒=1 → 上传。
+     * 不写检测完成;上传成功后复位允许进站=0。
+     */
+    private static void handleCompleteRisingEdge() throws Exception {
         boolean complete = s7Client.readBit(config.completeByte, config.completeBit);
-        // 保持完成位为 true 时持续尝试上传(失败可重试);首次从 false→true 或已完成待上传均可
-        if (!complete) {
-            lastComplete = false;
+        boolean rising = complete && !lastComplete;
+        lastComplete = complete;
+
+        if (busy || !armed || uploadDone || !rising) {
             return;
         }
-        lastComplete = true;
 
-        uploadBusy = true;
+        busy = true;
         try {
             String sn = s7Client.readFrameCode();
             if (sn == null || sn.isEmpty()) {
-                sn = currentSn;
-            }
-            if (sn == null || sn.isEmpty()) {
-                log.error("框架气密采集失败:无框架码,保持检测完成待重试");
-                return;
-            }
-
-            // 已上传成功但清完成位失败时,只重试清位,避免重复提交
-            if (sn.equals(lastUploadedSn)) {
-                s7Client.clearComplete();
-                SwingUtilities.invokeLater(() -> {
-                    MesClient.resetScanA();
-                    MesClient.setMenuStatus("测试结果上传成功,请扫下一件", 0);
-                });
-                resetCycle();
+                log.error("完成上升沿但框架码为空");
+                updateStatus("检测完成但框架码为空,无法上传", false);
                 return;
             }
 
@@ -213,35 +208,33 @@ public class QmPlcPoller {
             boolean judgePass = s7Client.readBit(config.judgeResultByte, config.judgeResultBit);
             String stationResult = judgePass ? "OK" : "NG";
 
-            log.info("框架气密采集 sn={} 充气时间={} 保压时间={} 测试时间={} 充气压力={} 稳定压力={} 泄漏量={} 判定={}",
-                    sn, inflationTime, holdTime, testTime, inflationPressure, stablePressure, leak, stationResult);
-
-            final String snF = sn;
-            final String resultF = stationResult;
-            final float stableF = stablePressure;
-            final float leakF = leak;
-            final float cqF = inflationTime;
-            final float byF = holdTime;
-            final float csF = testTime;
-            final float inflationPressureF = inflationPressure;
+            log.info("完成0→1上传 sn={} 判定={}", sn, stationResult);
+            updateStatus("正在上传 " + sn + " " + stationResult + "...", true);
 
-            TestParam testParam = buildTestParam(snF, resultF, stableF, leakF, cqF, byF, csF, inflationPressureF);
+            TestParam testParam = buildTestParam(sn, stationResult, stablePressure, leak,
+                    inflationTime, holdTime, testTime, inflationPressure);
             JSONObject resp = DataUtil.qmResultData(testParam);
-            boolean ok = resp != null && "true".equalsIgnoreCase(String.valueOf(resp.get("result")));
-            if (!ok) {
-                log.error("框架气密结果上传失败,保持检测完成待重试 sn={}", snF);
-                updateStatus("测试结果上传失败,请重试 [" + snF + "]", false);
+            boolean uploadOk = resp != null && "true".equalsIgnoreCase(String.valueOf(resp.get("result")));
+            if (!uploadOk) {
+                String msg = resp != null ? resp.getString("message") : "无响应";
+                log.error("上传失败 sn={} msg={}", sn, msg);
+                updateStatus("上传失败: " + msg + ",等完成位再次0→1", false);
                 return;
             }
 
-            lastUploadedSn = snF;
-            s7Client.clearComplete();
+            boolean localOk = false;
             try {
-                JdbcUtils.insertTestRecord(testParam);
+                localOk = JdbcUtils.insertTestRecord(testParam);
             } catch (Exception e) {
-                log.warn("本地测试记录保存失败: {}", e.getMessage());
+                log.error("本地记录保存异常: {}", e.getMessage());
             }
 
+            final String resultF = stationResult;
+            final float stableF = stablePressure;
+            final float leakF = leak;
+            final float byF = holdTime;
+            final float csF = testTime;
+            final boolean localSaved = localOk;
             SwingUtilities.invokeLater(() -> {
                 if (MesClient.param1 != null) {
                     MesClient.param1.setText(fmt(stableF));
@@ -259,13 +252,35 @@ public class QmPlcPoller {
                     MesClient.result.setText(resultF);
                     MesClient.result.setForeground("OK".equals(resultF) ? Color.GREEN : Color.RED);
                 }
-                MesClient.resetScanA();
-                MesClient.setMenuStatus("测试结果上传成功,请扫下一件", 0);
+                if (MesClient.product_sn != null) {
+                    MesClient.product_sn.setText(sn);
+                }
+                MesClient.work_status = 0;
+                MesClient.check_quality_result = false;
+                try {
+                    JdbcUtils.getTestData();
+                } catch (Exception e) {
+                    log.warn("刷新记录查询失败: {}", e.getMessage());
+                }
             });
-            resetCycle();
-            log.info("框架气密采集完成 sn={} result={}", snF, resultF);
+
+            uploadDone = true;
+            armed = false;
+            try {
+                s7Client.clearAllowEntry();
+                log.info("上传成功后已复位允许进站=0 sn={}", sn);
+            } catch (Exception e) {
+                log.error("复位允许进站失败 sn={}: {}", sn, e.getMessage());
+                updateStatus("上传成功但复位允许进站失败: " + e.getMessage(), false);
+            }
+            if (localSaved) {
+                updateStatus("上传成功(" + stationResult + "),已复位进站,等待PLC扫码反馈", true);
+            } else {
+                updateStatus("上传成功(" + stationResult + "),本地记录失败,等待PLC扫码反馈", false);
+            }
+            log.info("上传成功 sn={} result={} localOk={}", sn, stationResult, localSaved);
         } finally {
-            uploadBusy = false;
+            busy = false;
         }
     }
 

+ 8 - 1
src/com/mes/plc/QmS7Client.java

@@ -87,8 +87,15 @@ public class QmS7Client {
         writeBit(config.scanFeedbackByte, config.scanFeedbackBit, false);
     }
 
+    /** 上传成功后复位允许进站=0(不碰检测完成/扫码反馈) */
+    public void clearAllowEntry() throws Exception {
+        writeBit(config.allowEntryByte, config.allowEntryBit, false);
+    }
+
+    /** @deprecated 检测完成由 PLC 厂家清,MES 不应调用 */
+    @Deprecated
     public void clearComplete() throws Exception {
-        writeBit(config.completeByte, config.completeBit, false);
+        throw new UnsupportedOperationException("检测完成由 PLC 厂家清,MES 不写");
     }
 
     public String readFrameCode() throws Exception {

+ 11 - 6
src/com/mes/ui/MesClient.java

@@ -1146,8 +1146,8 @@ public class MesClient extends JFrame {
         finish_ng_bt.setEnabled(false);
 //        indexPanelA.add(finish_ng_bt);
 
-        tabbedPane.addTab("工作面板", new ImageIcon(MesClient.class.getResource("/bg/a_side.png")), indexScrollPaneA, null);
-        tabbedPane.setEnabledAt(0, true);
+        // 工作面板组件仍创建(PLC 轮询会写 product_sn/result 等),不加入 Tab
+        // tabbedPane.addTab("工作面板", new ImageIcon(MesClient.class.getResource("/bg/a_side.png")), indexScrollPaneA, null);
 
         indexPanelC = new JPanel();
         searchScrollPaneDj = new JScrollPane(indexPanelC);
@@ -1710,7 +1710,8 @@ public class MesClient extends JFrame {
         lineSn.setBounds(762, 195, 200, 30);
         indexPanelD.add(lineSn);
 
-        tabbedPane.addTab("软件设置", new ImageIcon(MesClient.class.getResource("/bg/menu_setting.png")), searchScrollPaneD, null);
+        // 软件设置组件仍创建,不加入 Tab
+        // tabbedPane.addTab("软件设置", new ImageIcon(MesClient.class.getResource("/bg/menu_setting.png")), searchScrollPaneD, null);
 
         // 原「通讯测试」页已隐藏;改为 PLC 调试页,读取 DB200 全部点位
         qmPlcMonitorPanel = new QmPlcMonitorPanel();
@@ -2048,14 +2049,18 @@ public class MesClient extends JFrame {
         indexPanelTask.add(barcodeLength);
 
 
-        tabbedPane.addTab("任务设置", new ImageIcon(MesClient.class.getResource("/bg/menu_data_preprocess.png")), searchScrollPaneTask, null);
-
+        // 任务设置组件仍创建,不加入 Tab
+        // tabbedPane.addTab("任务设置", new ImageIcon(MesClient.class.getResource("/bg/menu_data_preprocess.png")), searchScrollPaneTask, null);
 
+        // 仅保留:记录查询、PLC调试
         tabbedPane.addChangeListener(new ChangeListener() {
             @Override
             public void stateChanged(ChangeEvent e) {
                 JTabbedPane pane = (JTabbedPane) e.getSource();
                 int selectedIndex = pane.getSelectedIndex();
+                if (selectedIndex < 0) {
+                    return;
+                }
                 String title = pane.getTitleAt(selectedIndex);
                 if ("PLC调试".equals(title)) {
                     if (qmPlcMonitorPanel != null) {
@@ -2064,7 +2069,7 @@ public class MesClient extends JFrame {
                 } else if (qmPlcMonitorPanel != null) {
                     qmPlcMonitorPanel.stopMonitor();
                 }
-                if (selectedIndex == 1) {
+                if ("记录查询".equals(title)) {
                     JdbcUtils.getTestData();
                 }
             }

+ 1 - 1
src/resources/config/config.properties

@@ -8,7 +8,7 @@ portName1=COM9
 
 # 框架气密 PLC(DB200)
 mes.qm.plc.enabled=true
-mes.qm.plc.host=192.168.1.1
+mes.qm.plc.host=192.168.1.100
 mes.qm.plc.rack=0
 mes.qm.plc.slot=1
 mes.qm.plc.db=200