sunxianglong 5 napja
szülő
commit
fb8965bdc5

+ 32 - 0
src/com/mes/ui/DataUtil.java

@@ -1,10 +1,13 @@
 package com.mes.ui;
 
+import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONObject;
 import com.mes.netty.NettyClient;
 import com.mes.util.Config;
 import com.mes.util.DateLocalUtils;
+import com.mes.util.HttpUtils;
 import com.mes.util.JdbcUtils;
+import com.mes.util.MesProductVoltage;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -145,6 +148,35 @@ public class DataUtil {
         }
     }
 
+    /**
+     * 提交绝缘电压检测数据到 MES(MesProductVoltage)
+     */
+    public static boolean submitVoltageData(MesProductVoltage data) {
+        try {
+            String url = String.format("http://%s:8980/js/a/mes/mesProductVoltage/add", Config.server_ip);
+            String json = JSON.toJSONString(data);
+            log.info("提交绝缘电压数据: url={}, body={}", url, json);
+            String response = HttpUtils.sendJsonPost(url, json);
+            if (response == null || response.isEmpty()) {
+                log.error("提交绝缘电压数据失败: 无响应");
+                return false;
+            }
+            JSONObject obj = JSONObject.parseObject(response);
+            Object resultVal = obj.get("result");
+            boolean ok = Boolean.TRUE.equals(resultVal)
+                    || "true".equalsIgnoreCase(String.valueOf(resultVal));
+            if (ok) {
+                log.info("提交绝缘电压数据成功");
+                return true;
+            }
+            log.error("提交绝缘电压数据失败: {}", response);
+            return false;
+        } catch (Exception e) {
+            log.error("提交绝缘电压数据异常", e);
+            return false;
+        }
+    }
+
     public static Boolean sendQuality(String sn,String result,String user,String s1,String s2,String s3,String s4,String s5,String s6,String s7,String s8,String s9,String s10){
         try{
             String msgType = "MQDW";

+ 56 - 27
src/com/mes/ui/MesClient.java

@@ -58,6 +58,14 @@ public class MesClient extends JFrame {
     public static JTextField pressureText_2;                // 压力值显示文本框
     public static JTextField leakText_2;                   // 压力值显示文本框
 
+    // S7 信号显示
+    public static JTextField plc_heartbeat_tf;
+    public static JTextField plc_req_check_tf;
+    public static JTextField plc_req_entry_tf;
+    public static JTextField plc_mes_check_ok_tf;
+    public static JTextField plc_mes_check_ng_tf;
+    public static JTextField plc_mes_entry_ok_tf;
+
 
     public static JPanel contentPane;
     public static MesClient mesClientFrame;
@@ -506,6 +514,7 @@ public class MesClient extends JFrame {
         finish_ok_bt_1.setFont(new Font("微软雅黑", Font.PLAIN, 32));
         finish_ok_bt_1.setBounds(185, 291, 240, 80);
         finish_ok_bt_1.setEnabled(false);
+        finish_ok_bt_1.setVisible(false);
         indexPanelA.add(finish_ok_bt_1);
 
         finish_ng_bt_1 = new JButton("NG");
@@ -528,35 +537,16 @@ public class MesClient extends JFrame {
         finish_ng_bt_1.setFont(new Font("微软雅黑", Font.PLAIN, 32));
         finish_ng_bt_1.setBounds(508, 291, 240, 80);
         finish_ng_bt_1.setEnabled(false);
+        finish_ng_bt_1.setVisible(false);
         indexPanelA.add(finish_ng_bt_1);
 
-
-//        JLabel lblNewLabel = new JLabel("压力");
-//        lblNewLabel.setHorizontalAlignment(SwingConstants.RIGHT);
-//        lblNewLabel.setFont(new Font("微软雅黑", Font.PLAIN, 25));
-//        lblNewLabel.setBounds(129, 195, 96, 53);
-//        indexPanelA.add(lblNewLabel);
-//
-//        pressureText_1 = new JTextField();
-//        pressureText_1.setFont(new Font("微软雅黑", Font.PLAIN, 25));
-//        pressureText_1.setEnabled(false);
-//        pressureText_1.setForeground(Color.BLACK);
-//        pressureText_1.setBounds(245, 190, 191, 56);
-//        indexPanelA.add(pressureText_1);
-//        pressureText_1.setColumns(10);
-//
-//        JLabel lblNewLabel_1 = new JLabel("泄漏");
-//        lblNewLabel_1.setHorizontalAlignment(SwingConstants.RIGHT);
-//        lblNewLabel_1.setFont(new Font("微软雅黑", Font.PLAIN, 25));
-//        lblNewLabel_1.setBounds(475, 195, 96, 53);
-//        indexPanelA.add(lblNewLabel_1);
-//
-//        leakText_1 = new JTextField();
-//        leakText_1.setFont(new Font("微软雅黑", Font.PLAIN, 25));
-//        leakText_1.setEnabled(false);
-//        leakText_1.setColumns(10);
-//        leakText_1.setBounds(591, 190, 191, 56);
-//        indexPanelA.add(leakText_1);
+        // S7 信号显示区
+        addSignalRow(indexPanelA, "心跳", 81, 180, plc_heartbeat_tf = createSignalField());
+        addSignalRow(indexPanelA, "请求效验", 480, 180, plc_req_check_tf = createSignalField());
+        addSignalRow(indexPanelA, "请求MES录入", 81, 260, plc_req_entry_tf = createSignalField());
+        addSignalRow(indexPanelA, "Mes效验OK", 480, 260, plc_mes_check_ok_tf = createSignalField());
+        addSignalRow(indexPanelA, "Mes效验NG", 81, 340, plc_mes_check_ng_tf = createSignalField());
+        addSignalRow(indexPanelA, "Mes录入成功", 480, 340, plc_mes_entry_ok_tf = createSignalField());
 
 
         tabbedPane.addTab("工作面板", new ImageIcon(MesClient.class.getResource("/bg/a_side.png")), indexScrollPaneA, null);
@@ -600,6 +590,45 @@ public class MesClient extends JFrame {
         MesClient.status_menu_1.setText(msg);
     }
 
+    private static JTextField createSignalField() {
+        JTextField tf = new JTextField("OFF");
+        tf.setHorizontalAlignment(SwingConstants.CENTER);
+        tf.setFont(new Font("微软雅黑", Font.BOLD, 22));
+        tf.setEditable(false);
+        tf.setFocusable(false);
+        tf.setForeground(Color.GRAY);
+        return tf;
+    }
+
+    private static void addSignalRow(JPanel panel, String title, int x, int y, JTextField field) {
+        JLabel label = new JLabel(title);
+        label.setHorizontalAlignment(SwingConstants.RIGHT);
+        label.setFont(new Font("微软雅黑", Font.PLAIN, 22));
+        label.setBounds(x, y, 150, 50);
+        panel.add(label);
+
+        field.setBounds(x + 160, y, 140, 50);
+        panel.add(field);
+    }
+
+    public static void updatePlcSignal(JTextField field, boolean on) {
+        if (field == null) {
+            return;
+        }
+        field.setText(on ? "ON" : "OFF");
+        field.setForeground(on ? Color.GREEN : Color.GRAY);
+    }
+
+    public static void refreshPlcSignals(boolean heartbeat, boolean reqCheck, boolean reqEntry,
+                                         boolean mesCheckOk, boolean mesCheckNg, boolean mesEntryOk) {
+        updatePlcSignal(plc_heartbeat_tf, heartbeat);
+        updatePlcSignal(plc_req_check_tf, reqCheck);
+        updatePlcSignal(plc_req_entry_tf, reqEntry);
+        updatePlcSignal(plc_mes_check_ok_tf, mesCheckOk);
+        updatePlcSignal(plc_mes_check_ng_tf, mesCheckNg);
+        updatePlcSignal(plc_mes_entry_ok_tf, mesEntryOk);
+    }
+
 
     public static void getMaterailData() {
         JSONObject retObj = DataUtil.getBindMaterail();

+ 8 - 3
src/com/mes/ui/MesRevice.java

@@ -15,12 +15,17 @@ public class MesRevice {
             if (Config.gw_1.equalsIgnoreCase(oprno)) {
                 if(processMsgRet.equalsIgnoreCase("UD")) {
                     MesClient.check_quality_result1 = true;  //质量合格,可以绑定加工
+                    S7Utils.writeMesCheckOk(true);
+                    S7Utils.writeMesCheckNg(false);
+                    MesClient.setMenuState_1("质量校验OK", 0);
                     if(MesClient.work_status1 == 0 ){
                         String barcode = MesClient.getBarcode(MesClient.product_sn_1.getText());//处理36为码
                         DataUtil.startWork(MesClient.nettyClient, barcode,MesClient.user20, Config.gw_1);
                     }
                 }else {
                     MesClient.check_quality_result1 = false;
+                    S7Utils.writeMesCheckOk(false);
+                    S7Utils.writeMesCheckNg(true);
                     String lmsg = ErrorMsg.getErrorMsg(processMsgRet, ProtocolParam.getLx(mes_msg));
                     MesClient.setMenuState_1(lmsg,1);
                 }
@@ -36,7 +41,7 @@ public class MesRevice {
             String oprno = ProtocolParam.getOprno(mes_msg).trim();
             if (Config.gw_1.equalsIgnoreCase(oprno)) {
                 if(processMsgRet.equalsIgnoreCase("OK")) {
-                    MesClient.setMenuState_1("该工件可以加工,请选择结果", 0);
+                    MesClient.setMenuState_1("该工件可以加工", 0);
                     MesClient.f_scan_data_bt_1.setEnabled(false);
                     MesClient.finish_ok_bt_1.setEnabled(true);
                     MesClient.finish_ng_bt_1.setEnabled(true);
@@ -83,9 +88,9 @@ public class MesRevice {
             if(processMsgRet.equalsIgnoreCase("OK")) {
 
                 WorkTimer.flag = 0;
+                S7Utils.writeMesEntryOk(true);
                 MesClient.resetScanA();
-                MesClient.setMenuState_1("结果提交成功,请扫下一件",0);
-                MesClient.scanBarcode1();
+                MesClient.setMenuState_1("MES录入成功,等待下一件",0);
 
             }else{
                 MesClient.setMenuState_1("结果提交失败,请重试",-1);

+ 4 - 0
src/com/mes/util/Config.java

@@ -23,6 +23,8 @@ public class Config {
     public static final Integer tcp_port;
     public static final Integer heart_beat_cycle;
     public static final Integer heart_icon_cycle = 1;
+    public static final String plc_ip;
+    public static final Integer plc_heart_beat_cycle;
 
     private Config() {}
     static {
@@ -40,6 +42,8 @@ public class Config {
         server_ip = prop.getProperty("mes.server_ip");
         tcp_port = Integer.parseInt(prop.getProperty("mes.tcp_port"));
         heart_beat_cycle = Integer.parseInt(prop.getProperty("mes.heart_beat_cycle"));
+        plc_ip = prop.getProperty("plc.ip", "192.168.20.20");
+        plc_heart_beat_cycle = Integer.parseInt(prop.getProperty("plc.heart_beat_cycle", "1"));
 
     }
 

+ 93 - 0
src/com/mes/util/MesProductVoltage.java

@@ -0,0 +1,93 @@
+package com.mes.util;
+
+/**
+ * 绝缘电压数据(对应服务端 MesProductVoltage)
+ */
+public class MesProductVoltage {
+    private String sn;            // 工件码
+    private String current;       // 检测电流
+    private String currentPs;     // 爬升电流
+    private String oneVoltage;    // 电压1
+    private String twoVoltage;    // 电压2
+    private String resistance;    // 电阻
+    private String result;        // 检测结果
+    private String time;          // 检测次数
+
+    public String getSn() {
+        return sn;
+    }
+
+    public void setSn(String sn) {
+        this.sn = sn;
+    }
+
+    public String getCurrent() {
+        return current;
+    }
+
+    public void setCurrent(String current) {
+        this.current = current;
+    }
+
+    public String getCurrentPs() {
+        return currentPs;
+    }
+
+    public void setCurrentPs(String currentPs) {
+        this.currentPs = currentPs;
+    }
+
+    public String getOneVoltage() {
+        return oneVoltage;
+    }
+
+    public void setOneVoltage(String oneVoltage) {
+        this.oneVoltage = oneVoltage;
+    }
+
+    public String getTwoVoltage() {
+        return twoVoltage;
+    }
+
+    public void setTwoVoltage(String twoVoltage) {
+        this.twoVoltage = twoVoltage;
+    }
+
+    public String getResistance() {
+        return resistance;
+    }
+
+    public void setResistance(String resistance) {
+        this.resistance = resistance;
+    }
+
+    public String getResult() {
+        return result;
+    }
+
+    public void setResult(String result) {
+        this.result = result;
+    }
+
+    public String getTime() {
+        return time;
+    }
+
+    public void setTime(String time) {
+        this.time = time;
+    }
+
+    @Override
+    public String toString() {
+        return "MesProductVoltage{" +
+                "sn='" + sn + '\'' +
+                ", current='" + current + '\'' +
+                ", currentPs='" + currentPs + '\'' +
+                ", oneVoltage='" + oneVoltage + '\'' +
+                ", twoVoltage='" + twoVoltage + '\'' +
+                ", resistance='" + resistance + '\'' +
+                ", result='" + result + '\'' +
+                ", time='" + time + '\'' +
+                '}';
+    }
+}

+ 210 - 31
src/com/mes/util/S7Utils.java

@@ -7,67 +7,246 @@ import org.slf4j.LoggerFactory;
 
 public class S7Utils {
     public static final Logger log = LoggerFactory.getLogger(S7Utils.class);
-    public static S7PLC s7PLC = new S7PLC(EPlcType.S200_SMART, "192.168.20.20");
 
-    //发送允许启动信号
-    public static void writeStart(boolean b) {
+    /** 心跳 DB1000.DBX0.0 */
+    public static final String ADDR_HEARTBEAT = "DB1000.0.0";
+    /** 请求效验 DB1000.DBX2.1 */
+    public static final String ADDR_REQ_CHECK = "DB1000.2.1";
+    /** 请求MES录入 DB1000.DBX2.2 */
+    public static final String ADDR_REQ_ENTRY = "DB1000.2.2";
+    /** Mes效验OK DB1000.DBX0.1 */
+    public static final String ADDR_MES_CHECK_OK = "DB1000.0.1";
+    /** Mes效验NG DB1000.DBX0.2 */
+    public static final String ADDR_MES_CHECK_NG = "DB1000.0.2";
+    /** Mes录入成功 DB1000.DBX0.3 */
+    public static final String ADDR_MES_ENTRY_OK = "DB1000.0.3";
+    /** 工件码 DB1000.DBB6 ~ DB1000.DBB65,共60字节 Char */
+    public static final String ADDR_PRODUCT_SN = "DB1000.6.0";
+    public static final int PRODUCT_SN_LEN = 60;
+    /** 最终测量结果 DB1000.DBW4 Word */
+    public static final String ADDR_FINAL_RESULT = "DB1000.4.0";
+
+    /** 第1次测量:结果/爬升电流/电压1/电阻/电压2/电流 */
+    public static final String ADDR_MEASURE_RESULT_1 = "DB1000.66.0";
+    public static final String ADDR_CURRENT_PS_1 = "DB1000.68.0";
+    public static final String ADDR_ONE_VOLTAGE_1 = "DB1000.72.0";
+    public static final String ADDR_RESISTANCE_1 = "DB1000.84.0";
+    public static final String ADDR_TWO_VOLTAGE_1 = "DB1000.80.0";
+    public static final String ADDR_CURRENT_1 = "DB1000.76.0";
+
+    /** 第2次测量:结果/爬升电流/电压1/电阻/电压2/电流 */
+    public static final String ADDR_MEASURE_RESULT_2 = "DB1000.112.0";
+    public static final String ADDR_CURRENT_PS_2 = "DB1000.114.0";
+    public static final String ADDR_ONE_VOLTAGE_2 = "DB1000.118.0";
+    public static final String ADDR_RESISTANCE_2 = "DB1000.130.0";
+    public static final String ADDR_TWO_VOLTAGE_2 = "DB1000.126.0";
+    public static final String ADDR_CURRENT_2 = "DB1000.122.0";
+
+    /** 第3次测量:结果/爬升电流/电压1/电阻/电压2/电流 */
+    public static final String ADDR_MEASURE_RESULT_3 = "DB1000.158.0";
+    public static final String ADDR_CURRENT_PS_3 = "DB1000.160.0";
+    public static final String ADDR_ONE_VOLTAGE_3 = "DB1000.164.0";
+    public static final String ADDR_RESISTANCE_3 = "DB1000.176.0";
+    public static final String ADDR_TWO_VOLTAGE_3 = "DB1000.172.0";
+    public static final String ADDR_CURRENT_3 = "DB1000.168.0";
+
+    /** 第4次测量:结果/爬升电流/电压1/电阻/电压2/电流 */
+    public static final String ADDR_MEASURE_RESULT_4 = "DB1000.204.0";
+    public static final String ADDR_CURRENT_PS_4 = "DB1000.206.0";
+    public static final String ADDR_ONE_VOLTAGE_4 = "DB1000.210.0";
+    public static final String ADDR_RESISTANCE_4 = "DB1000.222.0";
+    public static final String ADDR_TWO_VOLTAGE_4 = "DB1000.218.0";
+    public static final String ADDR_CURRENT_4 = "DB1000.214.0";
+
+    public static S7PLC s7PLC = new S7PLC(EPlcType.S200_SMART, Config.plc_ip);
+
+    private S7Utils() {
+    }
+
+    public static boolean readBoolean(String address) {
         try {
-            s7PLC.writeBoolean("DB100.0.2", b);
-            log.info("设置<MES允许启动> : {}", b);
+            return s7PLC.readBoolean(address);
         } catch (Exception e) {
-            log.error("设置<MES允许启动> 失败: {}", e.getMessage());
+            log.error("读取S7地址 {} 失败: {}", address, e.getMessage());
+            return false;
         }
     }
 
-    public static void writeFinish(boolean b) {
+    public static void writeBoolean(String address, boolean value) {
         try {
-            s7PLC.writeBoolean("DB100.0.3", b);
-            log.info("设置<检测完成> : {}", b);
+            s7PLC.writeBoolean(address, value);
         } catch (Exception e) {
-            log.error("设置<检测完成> 失败");
+            log.error("写入S7地址 {} 失败: {}", address, e.getMessage());
         }
     }
 
-    public static Boolean readSpot() {
+    /**
+     * 读取工件码:DB1000.DBB6 ~ DB1000.DBB65(Char数组,非STRING)
+     * 注意:不能用 readString,否则会把首字节当成长度头导致丢第一位
+     */
+    public static String readProductSn() {
         try {
-            boolean result = s7PLC.readBoolean("DB100.0.4");
-            log.info("读取<产品到位检测> : {}", result);
-            return result;
+            byte[] bytes = s7PLC.readByte(ADDR_PRODUCT_SN, PRODUCT_SN_LEN);
+            if (bytes == null || bytes.length == 0) {
+                return "";
+            }
+            String sn = new String(bytes, java.nio.charset.StandardCharsets.ISO_8859_1);
+            int end = sn.indexOf('\0');
+            if (end >= 0) {
+                sn = sn.substring(0, end);
+            }
+            sn = sn.trim();
+            log.info("读取工件码: {}", sn);
+            return sn;
         } catch (Exception e) {
-            log.error("读取<产品到位检测> 失败");
-            return false;
+            log.error("读取工件码失败: {}", e.getMessage());
+            return "";
         }
     }
 
-
-    public static void writeSpot(boolean b) {
+    public static int readWord(String address) {
         try {
-            s7PLC.writeBoolean("DB100.0.4", b);
-            log.info("设置<产品到位检测> : {}", b);
+            return Short.toUnsignedInt(s7PLC.readInt16(address));
         } catch (Exception e) {
-            log.error("设置<产品到位检测> 失败");
+            log.error("读取Word {} 失败: {}", address, e.getMessage());
+            return 0;
         }
     }
 
-    public static Boolean readFeedback() {
+    public static float readFloat(String address) {
         try {
-            boolean result = s7PLC.readBoolean("DB100.0.5");
-            log.info("读取<反馈给MES完成> : {}", result);
-            return result;
+            return s7PLC.readFloat32(address);
         } catch (Exception e) {
-            log.error("读取<反馈给MES完成> 失败");
-            return false;
+            log.error("读取Real {} 失败: {}", address, e.getMessage());
+            return 0f;
         }
+    }
+
+    private static String formatFloat(float value) {
+        return String.format(java.util.Locale.US, "%.4f", value);
+    }
+
+    /**
+     * 读取指定次数的测量数据并封装为 MesProductVoltage
+     */
+    public static MesProductVoltage readVoltageData(String sn, String time,
+                                                    String addrResult, String addrCurrentPs,
+                                                    String addrOneVoltage, String addrResistance,
+                                                    String addrTwoVoltage, String addrCurrent) {
+        int measureResult = readWord(addrResult);
+        float currentPs = readFloat(addrCurrentPs);
+        float oneVoltage = readFloat(addrOneVoltage);
+        float resistance = readFloat(addrResistance);
+        float twoVoltage = readFloat(addrTwoVoltage);
+        float current = readFloat(addrCurrent);
+
+        // Word 测量结果:1=OK,其它=NG
+        String result = (measureResult == 1) ? "OK" : "NG";
+
+        MesProductVoltage data = new MesProductVoltage();
+        data.setSn(sn);
+        data.setCurrent(formatFloat(current));
+        data.setCurrentPs(formatFloat(currentPs));
+        data.setOneVoltage(formatFloat(oneVoltage));
+        data.setTwoVoltage(formatFloat(twoVoltage));
+        data.setResistance(formatFloat(resistance));
+        data.setResult(result);
+        data.setTime(time);
+
+        log.info("读取测量数据 time={}: word={}, {}", time, measureResult, data);
+        return data;
+    }
+
+    /** 第1次测量 time=1 */
+    public static MesProductVoltage readVoltageData1(String sn) {
+        return readVoltageData(sn, "1",
+                ADDR_MEASURE_RESULT_1, ADDR_CURRENT_PS_1, ADDR_ONE_VOLTAGE_1,
+                ADDR_RESISTANCE_1, ADDR_TWO_VOLTAGE_1, ADDR_CURRENT_1);
+    }
+
+    /** 第2次测量 time=2 */
+    public static MesProductVoltage readVoltageData2(String sn) {
+        return readVoltageData(sn, "2",
+                ADDR_MEASURE_RESULT_2, ADDR_CURRENT_PS_2, ADDR_ONE_VOLTAGE_2,
+                ADDR_RESISTANCE_2, ADDR_TWO_VOLTAGE_2, ADDR_CURRENT_2);
+    }
+
+    /** 第3次测量 time=3 */
+    public static MesProductVoltage readVoltageData3(String sn) {
+        return readVoltageData(sn, "3",
+                ADDR_MEASURE_RESULT_3, ADDR_CURRENT_PS_3, ADDR_ONE_VOLTAGE_3,
+                ADDR_RESISTANCE_3, ADDR_TWO_VOLTAGE_3, ADDR_CURRENT_3);
+    }
 
+    /** 第4次测量 time=4 */
+    public static MesProductVoltage readVoltageData4(String sn) {
+        return readVoltageData(sn, "4",
+                ADDR_MEASURE_RESULT_4, ADDR_CURRENT_PS_4, ADDR_ONE_VOLTAGE_4,
+                ADDR_RESISTANCE_4, ADDR_TWO_VOLTAGE_4, ADDR_CURRENT_4);
     }
 
-    public static void writeFeedback(boolean b) {
+    /**
+     * 读取最终测量结果:DB1000.DBW4,1=OK,其它=NG
+     */
+    public static String readFinalResult() {
+        int word = readWord(ADDR_FINAL_RESULT);
+        String result = (word == 1) ? "OK" : "NG";
+        log.info("读取最终测量结果: word={}, result={}", word, result);
+        return result;
+    }
+
+    /**
+     * MES->PLC 心跳交互:读取后取反写回,每秒调用一次
+     */
+    public static boolean heartBeat() {
         try {
-            s7PLC.writeBoolean("DB100.0.5", b);
-            log.info("设置<反馈给MES完成> : {}", b);
+            boolean current = s7PLC.readBoolean(ADDR_HEARTBEAT);
+            boolean next = !current;
+            s7PLC.writeBoolean(ADDR_HEARTBEAT, next);
+            return next;
         } catch (Exception e) {
-            log.error("设置<反馈给MES完成> 失败");
+            log.error("S7心跳交互失败: {}", e.getMessage());
+            return false;
         }
     }
 
+    public static boolean readReqCheck() {
+        return readBoolean(ADDR_REQ_CHECK);
+    }
+
+    public static boolean readReqEntry() {
+        return readBoolean(ADDR_REQ_ENTRY);
+    }
+
+    public static boolean readMesCheckOk() {
+        return readBoolean(ADDR_MES_CHECK_OK);
+    }
+
+    public static boolean readMesCheckNg() {
+        return readBoolean(ADDR_MES_CHECK_NG);
+    }
+
+    public static boolean readMesEntryOk() {
+        return readBoolean(ADDR_MES_ENTRY_OK);
+    }
+
+    public static void writeMesCheckOk(boolean b) {
+        writeBoolean(ADDR_MES_CHECK_OK, b);
+        log.info("设置<Mes效验OK>: {}", b);
+    }
+
+    public static void writeMesCheckNg(boolean b) {
+        writeBoolean(ADDR_MES_CHECK_NG, b);
+        log.info("设置<Mes效验NG>: {}", b);
+    }
+
+    public static void writeMesEntryOk(boolean b) {
+        writeBoolean(ADDR_MES_ENTRY_OK, b);
+        log.info("设置<Mes录入成功>: {}", b);
+    }
+
+    public static void clearMesCheckResult() {
+        writeMesCheckOk(false);
+        writeMesCheckNg(false);
+    }
 }

+ 148 - 12
src/com/mes/util/WorkTimer.java

@@ -1,24 +1,32 @@
 package com.mes.util;
 
+import com.mes.ui.DataUtil;
 import com.mes.ui.MesClient;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.*;
+import javax.swing.*;
+import java.util.Timer;
+import java.util.TimerTask;
 
 public class WorkTimer {
     private static final Logger log = LoggerFactory.getLogger(WorkTimer.class);
     private static Timer workTimer1 = null;
     public static int flag = 0;
 
+    /** 本次请求效验是否已处理(防止重复发质量校验) */
+    private static volatile boolean reqCheckHandled = false;
+    /** 本次请求MES录入是否已处理 */
+    private static volatile boolean reqEntryHandled = false;
+
     private WorkTimer() {
     }
 
     public static void start() {
-
         if (workTimer1 == null) {
-            workTimer1 = new Timer();
-            workTimer1.schedule(new WorkTimerTask1(), 1000, 3000);
+            workTimer1 = new Timer("S7-Plc-Timer");
+            long cycleMs = Config.plc_heart_beat_cycle * 1000L;
+            workTimer1.schedule(new WorkTimerTask1(), 1000, cycleMs);
         }
     }
 
@@ -27,21 +35,149 @@ public class WorkTimer {
             workTimer1.cancel();
             workTimer1 = null;
         }
+        reqCheckHandled = false;
+        reqEntryHandled = false;
     }
 
-
-
-    // 工作状态定时任务(已去除串口交互,结果由界面 OK/NG 手动提交)
+    /**
+     * S7 定时任务:每秒心跳交互,刷新信号,处理请求效验/录入
+     */
     private static class WorkTimerTask1 extends TimerTask {
         @Override
-        public void  run() {
+        public void run() {
             try {
-                log.info("flag:"+flag);
-                log.info("work_status1:"+MesClient.work_status1);
-                log.info("check_quality_result1:"+MesClient.check_quality_result1);
+                boolean heartbeat = S7Utils.heartBeat();
+                boolean reqCheck = S7Utils.readReqCheck();
+                boolean reqEntry = S7Utils.readReqEntry();
+                boolean mesCheckOk = S7Utils.readMesCheckOk();
+                boolean mesCheckNg = S7Utils.readMesCheckNg();
+                boolean mesEntryOk = S7Utils.readMesEntryOk();
+
+                SwingUtilities.invokeLater(() -> MesClient.refreshPlcSignals(
+                        heartbeat, reqCheck, reqEntry, mesCheckOk, mesCheckNg, mesEntryOk));
+
+                handleReqCheck(reqCheck);
+                handleReqEntry(reqEntry);
             } catch (Exception e) {
-                log.error("工作定时任务报错", e);
+                log.error("S7定时任务报错", e);
+            }
+        }
+    }
+
+    /**
+     * 请求效验=true 时读取工件码并做质量校验
+     */
+    private static void handleReqCheck(boolean reqCheck) {
+        if (!reqCheck) {
+            if (reqCheckHandled) {
+                reqCheckHandled = false;
+                log.info("请求效验已复位");
+            }
+            return;
+        }
+
+        if (reqCheckHandled) {
+            return;
+        }
+
+        String sn = S7Utils.readProductSn();
+        if (sn.isEmpty()) {
+            log.warn("请求效验为true,但工件码为空,等待PLC写入");
+            SwingUtilities.invokeLater(() -> MesClient.setMenuState_1("等待PLC工件码", 1));
+            return;
+        }
+
+        if (!MesClient.tcp_connect_flag || MesClient.nettyClient == null) {
+            log.error("MES未连接,无法质量校验");
+            S7Utils.writeMesCheckOk(false);
+            S7Utils.writeMesCheckNg(true);
+            reqCheckHandled = true;
+            SwingUtilities.invokeLater(() -> MesClient.setMenuState_1("MES未连接", 1));
+            return;
+        }
+
+        reqCheckHandled = true;
+
+        SwingUtilities.invokeLater(() -> {
+            MesClient.product_sn_1.setText(sn);
+            MesClient.setMenuState_1("正在质量校验...", 0);
+            MesClient.mesClientFrame.repaint();
+        });
+
+        log.info("请求效验触发,开始质量校验, sn={}", sn);
+        Boolean sendOk = DataUtil.checkQuality(MesClient.nettyClient, sn, MesClient.user20, Config.gw_1);
+        if (!Boolean.TRUE.equals(sendOk)) {
+            log.error("质量校验报文发送失败");
+            S7Utils.writeMesCheckOk(false);
+            S7Utils.writeMesCheckNg(true);
+            SwingUtilities.invokeLater(() -> MesClient.setMenuState_1("质量校验发送失败", 1));
+        }
+    }
+
+    /**
+     * 请求MES录入=true 时读取工件码与测量数据,提交电压记录并回写结果
+     */
+    private static void handleReqEntry(boolean reqEntry) {
+        if (!reqEntry) {
+            if (reqEntryHandled) {
+                reqEntryHandled = false;
+                log.info("请求MES录入已复位");
             }
+            return;
         }
+
+        if (reqEntryHandled) {
+            return;
+        }
+
+        String sn = S7Utils.readProductSn();
+        if (sn.isEmpty()) {
+            log.warn("请求MES录入为true,但工件码为空,等待PLC写入");
+            SwingUtilities.invokeLater(() -> MesClient.setMenuState_1("等待PLC工件码(录入)", 1));
+            return;
+        }
+
+        reqEntryHandled = true;
+
+        MesProductVoltage voltage1 = S7Utils.readVoltageData1(sn);
+        MesProductVoltage voltage2 = S7Utils.readVoltageData2(sn);
+        MesProductVoltage voltage3 = S7Utils.readVoltageData3(sn);
+        MesProductVoltage voltage4 = S7Utils.readVoltageData4(sn);
+        SwingUtilities.invokeLater(() -> {
+            MesClient.product_sn_1.setText(sn);
+            MesClient.setMenuState_1("正在MES录入...", 0);
+            MesClient.mesClientFrame.repaint();
+        });
+
+        boolean httpOk1 = DataUtil.submitVoltageData(voltage1);
+        boolean httpOk2 = DataUtil.submitVoltageData(voltage2);
+        boolean httpOk3 = DataUtil.submitVoltageData(voltage3);
+        boolean httpOk4 = DataUtil.submitVoltageData(voltage4);
+        if (!httpOk1 || !httpOk2 || !httpOk3 || !httpOk4) {
+            log.error("绝缘电压数据提交失败, sn={}, time1={}, time2={}, time3={}, time4={}",
+                    sn, httpOk1, httpOk2, httpOk3, httpOk4);
+            SwingUtilities.invokeLater(() -> MesClient.setMenuState_1("MES录入失败", 1));
+            return;
+        }
+
+        // 最终结果取自 DB1000.DBW4
+        String finalResult = S7Utils.readFinalResult();
+
+        if (!MesClient.tcp_connect_flag || MesClient.nettyClient == null) {
+            log.error("MES TCP未连接,质量结果无法提交");
+            SwingUtilities.invokeLater(() -> MesClient.setMenuState_1("MES未连接(质量提交)", 1));
+            return;
+        }
+
+        Boolean qualityOk = DataUtil.sendQuality(sn, finalResult, MesClient.user20, Config.gw_1);
+        if (!Boolean.TRUE.equals(qualityOk)) {
+            log.error("质量结果提交失败, sn={}, result={}", sn, finalResult);
+            SwingUtilities.invokeLater(() -> MesClient.setMenuState_1("质量提交失败", 1));
+            return;
+        }
+
+        // Mes录入成功 在 MQDW 回调 updateResultRevice 中置位
+        SwingUtilities.invokeLater(() -> MesClient.setMenuState_1("等待质量提交确认...", 0));
+        log.info("MES录入已发送, sn={}, final(DBW4)={}", sn, finalResult);
     }
 }

+ 7 - 3
src/resources/config/config.properties

@@ -1,9 +1,13 @@
-mes.gw_1=OP370A
-#mes.server_ip=127.0.0.1
-mes.server_ip=10.0.20.10
+mes.gw_1=OP380
+mes.server_ip=127.0.0.1
+#mes.server_ip=10.0.20.10
 mes.tcp_port=3000
 
 mes.heart_beat_cycle=60
 
 mes.line_sn=XT
 
+# S7 PLC
+plc.ip=192.168.1.10
+plc.heart_beat_cycle=1
+