chefz 5 days ago
parent
commit
5000ef3e6b

+ 7 - 1
.classpath

@@ -10,7 +10,13 @@
 	<classpathentry kind="src" path="src/resources"/>
 	<classpathentry kind="output" path="bin"/>
 	<classpathentry kind="lib" path="lib/s7connector-2.1.jar"/>
-	<classpathentry kind="lib" path="lib/slf4j-api-2.0.6.jar"/>
+	<classpathentry kind="lib" path="lib/slf4j-api-1.7.36.jar"/>
+	<classpathentry kind="lib" path="lib/logback-classic-1.2.13.jar"/>
+	<classpathentry kind="lib" path="lib/logback-core-1.2.13.jar"/>
+	<classpathentry kind="lib" path="lib/jSerialComm-2.6.2.jar"/>
+	<classpathentry kind="lib" path="lib/iot-communication-1.4.4.jar"/>
+	<classpathentry kind="lib" path="lib/core-3.5.1.jar"/>
+	<classpathentry kind="lib" path="lib/javase-3.5.1.jar"/>
 	<classpathentry kind="lib" path="lib/okhttp-4.10.0.jar"/>
 	<classpathentry kind="lib" path="lib/kotlin-stdlib-1.8.10.jar"/>
 	<classpathentry kind="lib" path="lib/okio-jvm-3.3.0.jar"/>

+ 1 - 1
src/com/mes/ui/LoginFrame.java

@@ -171,7 +171,7 @@ public class LoginFrame extends JFrame {
                     MesClient.indexPanelB.add(jfxPanel);
 
 
-                    String url2 = "http://" + Config.server_ip + ":8980/js/a/mes/mesProcessCheckRecord/ulist?ucode=" + user_id + "&oprno=OP380" + "&lineSn=" + Config.line_sn;
+                    String url2 = "http://" + Config.server_ip + ":8980/js/a/mes/mesProcessCheckRecord/ulist?ucode=" + user_id + "&oprno=OP450" + "&lineSn=" + Config.line_sn;
                     MesWebView jfxPanel2 = new MesWebView(url2);
                     jfxPanel2.setSize(990, 550);
                     MesClient.indexPanelC.add(jfxPanel2);

+ 22 - 12
src/com/mes/ui/MesClient.java

@@ -185,6 +185,15 @@ public class MesClient extends JFrame {
         MesClient.finish_ok_bt_1.setEnabled(false);
         MesClient.finish_ng_bt_1.setEnabled(false);
         MesClient.f_scan_data_bt_1.setEnabled(true);
+        if (product_sn_1 != null) {
+            product_sn_1.setText("");
+        }
+        if (pressureText_1 != null) {
+            pressureText_1.setText("");
+        }
+        if (leakText_1 != null) {
+            leakText_1.setText("");
+        }
 //        setMenuState_1("请扫码", 0);
         work_status1 = 0;
         check_quality_result1 = false;
@@ -325,7 +334,7 @@ public class MesClient extends JFrame {
 
     public MesClient() {
         setIconImage(Toolkit.getDefaultToolkit().getImage(MesClient.class.getResource("/bg/logo.png")));
-        setTitle("MES系统客户端:OP380- 绝缘检测");
+        setTitle("MES系统客户端:OP450- 绝缘检测");
         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         setBounds(0, 0, 1024, 768);
 
@@ -409,11 +418,9 @@ public class MesClient extends JFrame {
             public void mousePressed(MouseEvent e) {
                 log.info("<工人操作>:点击 <打开远程> 按钮");
                 super.mouseClicked(e);
-                String read = WorkTimer.serialUtil.read("TESTok:RETURN?\r");
-                if(read != null && read.trim().equals("OFF")) {
-                    WorkTimer.serialUtil.read("TEST:RETURN ON\r");
-                }
-                WorkTimer.serialUtil.read("*RMTOFF\r");
+                // 正确指令:TEST:RETURN? → TEST:RETURN ON → *RMTOFF(旧代码误写 TESTok:RETURN?)
+                TesterRemoteUtil.openRemote(WorkTimer.serialUtil);
+                setMenuState_1("已发送打开远程指令", 0);
             }
         });
         menu1.add(menuItem1_1);
@@ -426,7 +433,7 @@ public class MesClient extends JFrame {
             public void mousePressed(MouseEvent e) {
                 log.info("<工人操作>:点击 <清除RMT> 按钮");
                 super.mouseClicked(e);
-                WorkTimer.serialUtil.read("*RMTOFF\r");
+                TesterRemoteUtil.clearRmt(WorkTimer.serialUtil);
             }
         });
         menu1.add(menuItem1_2);
@@ -500,7 +507,7 @@ public class MesClient extends JFrame {
         indexScrollPaneA = new JScrollPane(indexPanelA);
         indexPanelA.setLayout(null);
 
-        // OP310A
+        // OP450A
         product_sn_1 = new JTextField();
         product_sn_1.setHorizontalAlignment(SwingConstants.CENTER);
         product_sn_1.setEditable(false);
@@ -555,6 +562,7 @@ public class MesClient extends JFrame {
                     InsulationParamsDao.insert(Config.gw_1, sn, p1.description, p1.result, p1.state, p1.voltage, p1.testParam, p1.testTime);
                     InsulationParamsDao.insert(Config.gw_1, sn, p2.description, p2.result, p2.state, p2.voltage, p2.testParam, p2.testTime);
 
+                    TesterRemoteUtil.stopAndPrepareNext(WorkTimer.serialUtil);
                     S7Utils.writeFinish(true);
 
                     MesClient.setMenuState_1("结果提交成功,请扫下一件", 0);
@@ -601,8 +609,9 @@ public class MesClient extends JFrame {
                     log.info("读取参数: {}", p2);
 
                     InsulationParamsDao.insert(Config.gw_1, sn, p1.description, p1.result, p1.state, p1.voltage, p1.testParam, p1.testTime);
-                    InsulationParamsDao.insert(Config.gw_1, sn, p2.description, p1.result, p2.state, p2.voltage, p2.testParam, p2.testTime);
+                    InsulationParamsDao.insert(Config.gw_1, sn, p2.description, p2.result, p2.state, p2.voltage, p2.testParam, p2.testTime);
 
+                    TesterRemoteUtil.stopAndPrepareNext(WorkTimer.serialUtil);
                     S7Utils.writeFinish(true);
 
                     MesClient.setMenuState_1("结果提交成功,请扫下一件", 0);
@@ -678,13 +687,14 @@ public class MesClient extends JFrame {
                     int option = JOptionPane.showConfirmDialog(mesClientFrame, "确定切换串口至" + selectedItem + "?", "切换串口", JOptionPane.OK_CANCEL_OPTION);
                     if (option == JOptionPane.OK_OPTION) {
                         // 用户确认切换
-                        log.info("用户切换OP310A串口至 {}", selectedItem);
+                        log.info("用户切换OP450A串口至 {}", selectedItem);
                         currentSerialPort = selectedItem;
                         WorkTimer.serialUtil.serialPort.closePort();
                         WorkTimer.serialUtil = new SerialUtil(selectedItem);
+                        TesterRemoteUtil.openRemote(WorkTimer.serialUtil);
                         resetScanA();
-                        setMenuState_1("切换OP310A串口至" + selectedItem + ",请扫码", 0);
-                        log.info("切换OP310A串口成功");
+                        setMenuState_1("切换OP450A串口至" + selectedItem + ",请扫码", 0);
+                        log.info("切换OP450A串口成功");
                     } else {
                         // 用户取消切换,恢复之前的选项
                         comboBox1.setSelectedItem(currentSerialPort);

+ 14 - 10
src/com/mes/ui/OprnoUtil.java

@@ -6,18 +6,22 @@ import java.util.Map;
 
 public class OprnoUtil {
     public static String[] xtoprnos = new String[]{
-            "OP040","OP050","OP060","OP070","OP080","OP090","OP100","OP110",
-            "OP120","OP130","OP140","OP150","OP160","OP170","OP180","OP190",
-            "OP200","OP210","OP220","OP230","OP240","OP250","OP260","OP270",
-            "OP280","OP290","OP300","OP310","OP320","OP330","OP340","OP350",
-            "OP360","OP370","OP380","OP390","OP400","OP410","OP420","OP430"
+            "OP010", "OP020", "OP030", "OP040", "OP051", "OP052", "OP060", "OP070",
+            "OP080", "OP090", "OP100", "OP110", "OP120", "OP130", "OP140", "OP150",
+            "OP160", "OP170", "OP180", "OP190", "OP200", "OP210", "OP220", "OP230",
+            "OP240", "OP250", "OP260", "OP270", "OP281", "OP282", "OP283", "OP284",
+            "OP290", "OP300", "OP310", "OP320", "OP330", "OP340", "OP350", "OP360",
+            "OP370", "OP380", "OP390", "OP400", "OP410", "OP420", "OP430", "OP440",
+            "OP450", "OP460", "OP470", "OP480", "OP490"
     };
     public static String[] xtoprnodes = new String[]{
-            "镭雕二维码","小总成焊接(边梁、后梁)","框架焊接","人工补焊","框架矫形","焊道检验","CNC总成反面(1序)","总成反面清洁",
-            "框架找漏","冷板安装+拉铆","清理溢胶","水冷板FSW","CNC总成反面(2序)","CNC总成正面加工","总成正面清洁","框架终检",
-            "恒温静置","正面安装钢丝螺套","反面安装钢丝螺套","反面拉铆","半成品气密","涂液冷板加强件结构胶","涂密封胶 安装加强件","清胶",
-            "胶水固化","底护板预装+水嘴安装","底护板装配","成品气密,液冷板气密","人工清洁","贴PI膜/限位条","正面涂胶+拉铆",
-            "安装复合横梁","贴EPDM保温棉","绝缘耐压测试","在线检测(错漏)","在线检测(尺寸)","终检","GP12","包装"
+            "进料检", "入库", "领料", "镭雕二维码", "前后梁压铆", "前后梁压铆螺母柱-涂胶", "左/右前边框与封堵片焊接", "Flyback固定支架安装钢丝牙套",
+            "小总成焊接", "框架CMT焊接", "人工正面补焊", "人工反面补焊", "焊缝铣削打磨", "焊道检验", "框架CNC反面加工", "框架反面清洁去毛刺",
+            "框架找漏", "框架清洁", "框架终检", "液冷板安装", "冷板激光焊", "液冷板FSW", "水嘴、匙孔焊接", "CNC加工箱体正面",
+            "箱体正反面清洁", "封堵片焊接", "总成反面装螺套", "总成反面拉铆", "总成正面装配", "总成正面装配", "总成正面装配", "总成正面拉铆",
+            "安装中吊点", "型腔封堵", "箱体静置", "箱体气密", "液冷板气密检测", "粘贴MPP泡棉", "底护板气密", "底护板安装",
+            "底护板螺栓复拧", "反面终检", "粘贴陶瓷胶带", "总成清洁", "蓝光检测", "总成检具检验", "正面终检", "CCD错漏检",
+            "绝缘耐压检测", "接地点检测", "GP12", "下线拍照", "称重+包装"
     };
     public static String[] lboprnos = new String[]{
             "OP040","OP050","OP060","OP070","OP080","OP090","OP100","OP110",

+ 35 - 7
src/com/mes/util/SerialUtil.java

@@ -22,7 +22,10 @@ public class SerialUtil {
         log.info("{} 串口初始化{}", this.serialPort.getSystemPortName(), read ? "成功" : "失败");
         this.serialPort.setComPortParameters(9600, 8, SerialPort.ONE_STOP_BIT, SerialPort.NO_PARITY);
         this.serialPort.setComPortTimeouts(SerialPort.TIMEOUT_SCANNER, 0, 0);
+        addDataListener();
+    }
 
+    private void addDataListener() {
         this.serialPort.addDataListener(new SerialPortDataListener() {
             @Override
             public int getListeningEvents() {
@@ -37,39 +40,64 @@ public class SerialUtil {
 
                 byte[] buffer = new byte[1024];
                 int numBytesRead = SerialUtil.this.serialPort.readBytes(buffer, buffer.length);
+                if (numBytesRead <= 0) {
+                    return;
+                }
 
                 for (int i = 0; i < numBytesRead; i++) {
+                    if (SerialUtil.this.bufferEnd >= SerialUtil.this.buffer.length) {
+                        SerialUtil.this.bufferEnd = 0;
+                    }
                     SerialUtil.this.buffer[SerialUtil.this.bufferEnd++] = buffer[i];
                 }
             }
         });
     }
 
+    public boolean isPortOpen() {
+        return serialPort != null && serialPort.isOpen();
+    }
 
     public synchronized String read(String sendData) {
-        if (!sendData.isEmpty()) {
-            log.info("向串口写入: {}", sendData);
+        if (serialPort == null || !serialPort.isOpen()) {
+            log.warn("绝缘测试仪串口未打开,跳过指令: {}", sendData);
+            return "";
+        }
+        if (sendData != null && !sendData.isEmpty()) {
+            log.info("向串口写入: {}", sendData.replace("\r", "\\r"));
             byte[] bytes = sendData.getBytes();
             this.serialPort.writeBytes(bytes, bytes.length);
             try {
-                Thread.sleep(250);
+                // RETURN/MEAS 等指令需要稍长等待,避免读空
+                Thread.sleep(sendData.contains("?") || sendData.contains("RETURN") || sendData.contains("STOP")
+                        ? 400 : 250);
             } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
                 log.error("串口读取时,延时报错");
             }
         }
         byte[] copy = Arrays.copyOf(this.buffer, this.bufferEnd);
         this.bufferEnd = 0;
         String result = new String(copy);
-        log.info("从串口读取: {}", result);
+        log.info("从串口读取: {}", result.replace("\r", "\\r").replace("\n", "\\n"));
         return result;
     }
 
-    public void reconnect() {
+    public synchronized void reconnect() {
         log.info("{}断线重连", this.serialPort.getSystemPortName());
+        try {
+            this.serialPort.removeDataListener();
+        } catch (Exception ignored) {
+            // ignore
+        }
         this.serialPort.closePort();
+        this.bufferEnd = 0;
         boolean opened = this.serialPort.openPort();
+        if (opened) {
+            this.serialPort.setComPortParameters(9600, 8, SerialPort.ONE_STOP_BIT, SerialPort.NO_PARITY);
+            this.serialPort.setComPortTimeouts(SerialPort.TIMEOUT_SCANNER, 0, 0);
+            addDataListener();
+        }
         log.info("断线重连{}", opened ? "成功" : "失败");
     }
-
-
 }

+ 102 - 0
src/com/mes/util/TesterRemoteUtil.java

@@ -0,0 +1,102 @@
+package com.mes.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 绝缘测试仪远程控制(SCPI)。
+ * 现场验证:先开 RETURN,再 *RMTOFF,仪器才会主动回传 OK。
+ */
+public final class TesterRemoteUtil {
+
+    private static final Logger log = LoggerFactory.getLogger(TesterRemoteUtil.class);
+
+    private TesterRemoteUtil() {
+    }
+
+    /**
+     * 打开远程回报:TEST:RETURN ON + 清除 RMT。
+     */
+    public static void openRemote(SerialUtil serialUtil) {
+        if (serialUtil == null || !serialUtil.isPortOpen()) {
+            log.warn("打开远程失败:串口未打开");
+            return;
+        }
+        try {
+            // 清空残留,避免误判
+            serialUtil.read("");
+            String status = serialUtil.read("TEST:RETURN?\r");
+            String normalized = status == null ? "" : status.trim().toUpperCase();
+            log.info("TEST:RETURN? 当前状态: [{}]", normalized);
+            if (!normalized.contains("ON")) {
+                serialUtil.read("TEST:RETURN ON\r");
+                log.info("已发送 TEST:RETURN ON");
+            }
+            serialUtil.read("*RMTOFF\r");
+            log.info("打开远程完成(RETURN ON + *RMTOFF)");
+        } catch (Exception e) {
+            log.error("打开远程异常", e);
+        }
+    }
+
+    public static void clearRmt(SerialUtil serialUtil) {
+        if (serialUtil == null || !serialUtil.isPortOpen()) {
+            log.warn("清除RMT失败:串口未打开");
+            return;
+        }
+        serialUtil.read("*RMTOFF\r");
+    }
+
+    /**
+     * 产品到位后自动启动测试(等价于面板 START)。
+     */
+    public static void startTest(SerialUtil serialUtil) {
+        if (serialUtil == null || !serialUtil.isPortOpen()) {
+            log.warn("启动测试失败:串口未打开");
+            return;
+        }
+        try {
+            // 清缓冲,避免上一件残留 OK 误触发
+            serialUtil.read("");
+            serialUtil.read("*RMTOFF\r");
+            // 面板 START 对应远程指令;兼容常见写法
+            serialUtil.read("START\r");
+            serialUtil.read("SAFE:START\r");
+            log.info("已发送测试仪启动指令(START)");
+        } catch (Exception e) {
+            log.error("启动测试异常", e);
+        }
+    }
+
+    /**
+     * 测完复位:等价于面板 STOP,否则仪器卡在结束态,无法再按 START。
+     * 随后重新确保 RETURN ON,供下一件自动回传 OK。
+     */
+    public static void stopAndPrepareNext(SerialUtil serialUtil) {
+        if (serialUtil == null || !serialUtil.isPortOpen()) {
+            log.warn("测试仪复位失败:串口未打开");
+            return;
+        }
+        try {
+            // 面板 STOP 对应远程指令;兼容常见写法
+            serialUtil.read("STOP\r");
+            serialUtil.read("SAFE:STOP\r");
+            serialUtil.read("*RMTOFF\r");
+            serialUtil.read("TEST:RETURN ON\r");
+            serialUtil.read("*RMTOFF\r");
+            log.info("测试仪已 STOP 并重新打开 RETURN,可进行下一件");
+        } catch (Exception e) {
+            log.error("测试仪复位异常", e);
+        }
+    }
+
+    /** 判断缓冲中是否包含测试完成标志 OK */
+    public static boolean containsOk(String read) {
+        if (read == null) {
+            return false;
+        }
+        String s = read.trim().toUpperCase();
+        // 整行或夹杂回车时仍能识别
+        return "OK".equals(s) || s.contains("OK");
+    }
+}

+ 19 - 11
src/com/mes/util/WorkTimer.java

@@ -5,7 +5,8 @@ import com.mes.ui.MesClient;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.*;
+import java.util.Timer;
+import java.util.TimerTask;
 
 public class WorkTimer {
     private static final Logger log = LoggerFactory.getLogger(WorkTimer.class);
@@ -17,8 +18,9 @@ public class WorkTimer {
     }
 
     public static void start() {
-
         if (workTimer1 == null) {
+            // 登录后自动打开远程回报,避免收不到测试仪主动回传的 OK
+            TesterRemoteUtil.openRemote(serialUtil);
             workTimer1 = new Timer();
             workTimer1.schedule(new WorkTimerTask1(), 1000, 3000);
         }
@@ -31,9 +33,7 @@ public class WorkTimer {
         }
     }
 
-
-
-    // OP310A工作流程定时任务
+    // OP450 工作流程定时任务
     private static class WorkTimerTask1 extends TimerTask {
         @Override
         public void run() {
@@ -43,16 +43,22 @@ public class WorkTimer {
                         case 1:
                             Boolean spotDetection = S7Utils.readSpot();
                             if (spotDetection) {
+                                // PLC 产品到位后,自动启动测试仪(无需再按面板 START)
+                                MesClient.setMenuState_1("产品到位,正在启动测试仪...", 0);
+                                TesterRemoteUtil.startTest(serialUtil);
                                 MesClient.setMenuState_1("工件正在加工", 0);
                                 flag = 2;
                             }
                             break;
                         case 2:
                             String read = serialUtil.read("");
-                            if ("OK".equals(read.trim())) {
+                            if (TesterRemoteUtil.containsOk(read)) {
                                 MesClient.setMenuState_1("工件加工完成", 0);
                                 read = serialUtil.read("MEAS1?\r");
-                                if(read.isEmpty()) serialUtil.reconnect();
+                                if (read == null || read.trim().isEmpty()) {
+                                    serialUtil.reconnect();
+                                    read = serialUtil.read("MEAS1?\r");
+                                }
                                 InsulationParam p1 = new InsulationParam(read);
                                 log.info("读取参数: {}", p1);
 
@@ -60,7 +66,6 @@ public class WorkTimer {
                                 InsulationParam p2 = new InsulationParam(read);
                                 log.info("读取参数: {}", p2);
 
-
                                 String result = "NG";
                                 if ("PASS".equals(p1.state) && "PASS".equals(p2.state)) {
                                     result = "OK";
@@ -70,16 +75,21 @@ public class WorkTimer {
                                 InsulationParamsDao.insert(Config.gw_1, sn, p1.description, p1.result, p1.state, p1.voltage, p1.testParam, p1.testTime);
                                 InsulationParamsDao.insert(Config.gw_1, sn, p2.description, p2.result, p2.state, p2.voltage, p2.testParam, p2.testTime);
                                 MesClient.setMenuState_1("测试完成, 结果:" + result, 0);
+                                // 测完复位测试仪,否则需人工按 STOP 才能再 START
+                                TesterRemoteUtil.stopAndPrepareNext(serialUtil);
                                 S7Utils.writeFinish(true);
                                 flag = 3;
                             }
                             break;
                         case 3:
-                            if(S7Utils.readFeedback()) {
+                            if (S7Utils.readFeedback()) {
                                 MesClient.resetScanA();
                                 MesClient.scanBarcode1();
                                 flag = 0;
                             }
+                            break;
+                        default:
+                            break;
                     }
                 }
             } catch (Exception e) {
@@ -88,5 +98,3 @@ public class WorkTimer {
         }
     }
 }
-
-

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

@@ -1,6 +1,6 @@
-mes.gw_1=OP380
+mes.gw_1=OP450
 #mes.server_ip=127.0.0.1
-mes.server_ip=192.168.17.99
+mes.server_ip=192.168.15.99
 mes.tcp_port=3000
 
 mes.heart_beat_cycle=60

+ 1 - 1
src/resources/logback.xml

@@ -4,7 +4,7 @@
 
     <!-- 定义日志文件的存储位置及文件名 -->
     <property name="LOG_HOME" value="D:/Logs"/>
-    <property name="PROJECT_NAME" value="OP380"/>
+    <property name="PROJECT_NAME" value="OP450"/>
 
     <!-- 控制台输出 -->
     <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">