Procházet zdrojové kódy

中皖英太气密仪修复

张田野 před 2 týdny
rodič
revize
0cafc54cf1

+ 1 - 2
src/com/mes/netty/NettyClient.java

@@ -18,7 +18,7 @@ public class NettyClient {
     public SocketChannel socketChannel;
     public static ChannelFuture future;
 
-    public  void run(Object msg){
+    public void run(Object msg){
         //配置线程组
         EventLoopGroup group = new NioEventLoopGroup();
         //创建服务启动器
@@ -33,7 +33,6 @@ public class NettyClient {
                         socketChannel.pipeline()
                                 .addLast(new XDecoder())
                                 .addLast(new StringEncoder())
-//                                    .addLast(new StringDecoder())
                                 .addLast(new NettyClientHandler());
                     }
                 })

+ 1 - 1
src/com/mes/netty/NettyClientHandler.java

@@ -28,7 +28,7 @@ public class NettyClientHandler extends ChannelInboundHandlerAdapter {
     public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
         Channel channel = ctx.channel();
         log.error("close tcp, ip:" + channel.remoteAddress());
-        MesClient.tcp_connect_flag = false;
+        MesClient.qm_tcp_flag = false;
         MesClient.setTcpStatus();
         // 关闭通道
         channel.close();

+ 70 - 1
src/com/mes/ui/DataUtil.java

@@ -2,8 +2,10 @@ package com.mes.ui;
 
 import com.alibaba.fastjson2.JSONObject;
 import com.mes.netty.NettyClient;
+import com.mes.util.Base64Utils;
 import com.mes.util.DateLocalUtils;
 import com.mes.util.JdbcUtils;
+import com.mes.util.TestParam;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -11,6 +13,7 @@ import java.io.*;
 import java.net.HttpURLConnection;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.net.URLEncoder;
 import java.util.Properties;
 
 public class DataUtil {
@@ -237,6 +240,68 @@ public class DataUtil {
         }
     }
 
+    // 上传气密结果(HTTP直传后台,参照 OP-qm)
+    public static JSONObject qmResultData(TestParam testParam) {
+        try{
+            String enconding = "UTF-8";
+            InputStream is = ClassLoader.getSystemResourceAsStream("config/config.properties");
+            Properties pro = new Properties();
+            BufferedReader br = new BufferedReader(new InputStreamReader(is, enconding));
+            pro.load(br);
+            String mes_server_ip = pro.getProperty("mes.server_ip");
+            String url = "http://"+mes_server_ip+":8980/js/a/mes/mesProductRecord/qmresult";
+            String testPressureBase64 = Base64Utils.getBase64(testParam.getParam1() != null ? testParam.getParam1() : "");
+            String leakValBase64 = Base64Utils.getBase64(testParam.getParam3() != null ? testParam.getParam3() : "");
+            String testTimeBase64 = Base64Utils.getBase64(testParam.getCreateTime() != null ? testParam.getCreateTime() : "");
+            String titleBase64 = Base64Utils.getBase64(testParam.getOprnoTitle() != null ? testParam.getOprnoTitle() : "");
+
+            String params = "__ajax=json&oprno="+URLEncoder.encode(testParam.getOprno() != null ? testParam.getOprno() : "", "UTF-8")
+                    +"&lineSn="+URLEncoder.encode(testParam.getLineSn() != null ? testParam.getLineSn() : "", "UTF-8")
+                    +"&sn="+URLEncoder.encode(testParam.getSn() != null ? testParam.getSn() : "", "UTF-8")
+                    +"&workNum="+URLEncoder.encode(testParam.getUcode() != null ? testParam.getUcode() : "", "UTF-8")
+                    +"&cxm="+URLEncoder.encode(testParam.getParam5() != null ? testParam.getParam5() : "", "UTF-8")
+                    +"&result="+URLEncoder.encode(testParam.getResult() != null ? testParam.getResult() : "", "UTF-8")
+                    +"&testPressure="+URLEncoder.encode(testPressureBase64, "UTF-8")
+                    +"&testPressureUnit="+URLEncoder.encode(testParam.getParam2() != null ? testParam.getParam2() : "", "UTF-8")
+                    +"&leakVal="+URLEncoder.encode(leakValBase64, "UTF-8")
+                    +"&leakValUnit="+URLEncoder.encode(testParam.getParam4() != null ? testParam.getParam4() : "", "UTF-8")
+                    +"&testTime="+URLEncoder.encode(testTimeBase64, "UTF-8")
+                    +"&title="+URLEncoder.encode(titleBase64, "UTF-8")
+                    +"&remark="+URLEncoder.encode(testParam.getRemark() != null ? testParam.getRemark() : "", "UTF-8")
+                    +"&deviceType="+URLEncoder.encode(testParam.getDeviceType() != null ? testParam.getDeviceType() : "", "UTF-8")
+                    +"&cq="+URLEncoder.encode("", "UTF-8")
+                    +"&by="+URLEncoder.encode("", "UTF-8")
+                    +"&cs="+URLEncoder.encode("", "UTF-8")
+                    +"&leakRate="+URLEncoder.encode("", "UTF-8")
+                    +"&leakRateUnit="+URLEncoder.encode("", "UTF-8")
+                    +"&type="+URLEncoder.encode("", "UTF-8");
+
+            log.info("params="+params);
+            String result = doPost(url,params);
+            log.info("result="+result);
+
+            if(result == null || result.trim().isEmpty()) {
+                log.error("HTTP请求返回结果为空,请检查服务器连接和参数格式");
+                return null;
+            }
+
+            if(result.equalsIgnoreCase("false")) {
+                return null;
+            }else {
+                try {
+                    return JSONObject.parseObject(result);
+                } catch (Exception e) {
+                    log.error("解析JSON响应失败: {}, 原始响应: {}", e.getMessage(), result);
+                    return null;
+                }
+            }
+        }catch (Exception e){
+            log.error("qmResultData方法执行异常: {}", e.getMessage());
+            e.printStackTrace();
+            return null;
+        }
+    }
+
     public static String doPost(String httpUrl, String param) {
         HttpURLConnection connection = null;
         InputStream is = null;
@@ -255,7 +320,9 @@ public class DataUtil {
             connection.setRequestProperty("Authorization", "Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0");
             os = connection.getOutputStream();
             os.write(param.getBytes());
-            if (connection.getResponseCode() == 200) {
+            int responseCode = connection.getResponseCode();
+            log.info("HTTP响应码: " + responseCode);
+            if (responseCode == 200) {
                 is = connection.getInputStream();
                 br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                 StringBuffer sbf = new StringBuffer();
@@ -265,6 +332,8 @@ public class DataUtil {
                     sbf.append("\r\n");
                 }
                 result = sbf.toString();
+            } else {
+                log.error("HTTP请求失败,响应码: " + responseCode);
             }
         } catch (MalformedURLException e) {
             e.printStackTrace();

+ 205 - 15
src/com/mes/ui/MesClient.java

@@ -5,6 +5,10 @@ import com.mes.component.MesRadio;
 import com.mes.component.MesWebView;
 import com.mes.netty.NettyClient;
 import com.mes.util.*;
+import com.mes.util.ytnetty.YtNettyClient;
+import com.mes.util.ytnetty.YtUtil;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -35,7 +39,7 @@ public class MesClient extends JFrame {
     public static int mes_auth = 0; // 权限级别 0=无权限 1=操作工人 2=管理员
     public static String mes_gw = ""; // 工位号
     public static String mes_gw_des = ""; // 工位名称
-    public static String mes_server_ip = ""; // 服务器IP地址
+    public static String mes_server_ip = ""; // 服务器地址
     public static int mes_tcp_port = 3000; // TCP服务端口
     public static int mes_heart_beat_cycle = 10; // 心跳周期
     public static int mes_heart_icon_cycle = 1;
@@ -75,6 +79,8 @@ public class MesClient extends JFrame {
 
     public static String user20 = "";
 
+    public static boolean mes_enable = true; // true=MES开启
+
     public static JFrame welcomeWin;
 
     public static JPanel indexPanelB;
@@ -112,6 +118,7 @@ public class MesClient extends JFrame {
 
     public static String tjFlagTextErr = "结果上传MES失败,请重试";
 
+    public static CommonQmDevice commonQmDevice;
     public static SerialPortUtils serialPortUtils;
     public static JTextField printSn2;
     public static JTextField printTitle2;
@@ -121,6 +128,13 @@ public class MesClient extends JFrame {
     public static Integer isConfigEdit = 0;
     public static Integer mesStartFlag = 0;
     public static Integer mesTjFlag = 0;
+    public static boolean qm_tcp_flag = false;
+    /** 本轮实时压强/泄漏(与气密仪 RS 一致),提交时优先于 4353 旧协议解析值 */
+    public static String lastQmPressure = "";
+    public static String lastQmLeak = "";
+
+    //TCP连接
+    public static YtNettyClient ytClient;
 
     public static void main(String[] args) {
         EventQueue.invokeLater(new Runnable() {
@@ -142,14 +156,26 @@ public class MesClient extends JFrame {
                     formatConfigEdit(false);
                     formatConfigData();
 
-                    serialPortUtils=new SerialPortUtils(configParam.getSerialPort(),"","",configParam.getDevice());
-//                    getMaterailData();
+                    commonQmDevice = new CommonQmDevice(configParam);
+
+//                    serialPortUtils=new SerialPortUtils(configParam.getSerialPort(),"","",configParam.getDevice());
+
+//                    initYgslTcpConnection();
 //
-//                    startUpdateQualityTimer(); // 开启提交结果的定时任务
+
+//                    nettyClient.future.channel().writeAndFlush("5354"); // 启动
+
+                    // 初始化MES TCP连接与心跳(质量检查用)
+                    if(mes_enable){
+                        initTcpConnection();
+                        startHeartBeatTimer();
+                    }
+
                     startDateTimer();
 
                     textFocus();
 
+                    monitorDevice();
                     resetScanA();
                 }catch (Exception e){
                     log.error(e.getMessage());
@@ -173,6 +199,36 @@ public class MesClient extends JFrame {
         }, 1000,1000);
     }
 
+    public static Timer cjTimerText2;
+    public static void monitorDevice() {
+        if(cjTimerText2!=null) {
+            cjTimerText2.cancel();
+        }
+        // 空闲时不再主动读实时/结果,避免未扫码时把设备历史结果写入本地库
+        // 测试中的轮询由 CommonQmDevice.workTimerTask 在 work_status==1 时负责
+    }
+
+    // 初始化TCP
+    public static void initYgslTcpConnection() {
+        try {
+            if(ytClient==null) {
+                String ip = MesClient.configParam.getSerialPort();
+                String port = MesClient.configParam.getBaudRate();
+                //初始化TCP连接
+                ytClient = new YtNettyClient();
+                try{
+                    ytClient.run(ip,Integer.parseInt(port));
+//                    ytClient.run("192.168.0.253",3036);
+                }catch (Exception e){
+                    e.printStackTrace();
+                }
+            }
+        } catch (Exception e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+
     public static java.util.Timer dateBeatTimer;
     public static void startDateTimer() {
         if (dateBeatTimer != null) {
@@ -329,6 +385,21 @@ public class MesClient extends JFrame {
 //        MesClient.result.setForeground(Color.GRAY);
     }
 
+    /** 保留工件码并复位标志,便于同一工件连续多次测试 */
+    public static void resetForRetestKeepSn() {
+        work_status = 0;
+        check_quality_result = false;
+        MesClient.finish_ok_bt.setEnabled(false);
+        MesClient.finish_ng_bt.setEnabled(false);
+        product_sn.setEditable(true);
+        tjFlag = 0;
+        mesStartFlag = 0;
+        mesTjFlag = 0;
+        lastQmPressure = "";
+        lastQmLeak = "";
+        MesClient.setMenuStatus("已保存,同件回车可再测,或扫下一件",0);
+    }
+
     public static int userLoginHours;//用户登录所处小时
     public static JTextField param1;
     public static JTextField param2;
@@ -590,19 +661,113 @@ public class MesClient extends JFrame {
             return;
         }
 
+        // MES开启:先质量检查,通过后再进入测试(参照 OP-qm)
+        if(MesClient.mes_enable){
+            if(!tcp_connect_flag || nettyClient == null){
+                MesClient.setMenuStatus("未连接MES服务器,请检查网络后重试",-1);
+                return;
+            }
+            getUser();
+            MesClient.setMenuStatus("质量检查中...",0);
+            Boolean sendret = DataUtil.checkQuality(nettyClient, scanBarcode, user20);
+            if(!sendret){
+                MesClient.setMenuStatus("质量检查发送失败,请重试",-1);
+                return;
+            }
+            return;
+        }
+
+        // MES关闭:本地直接进入测试
+        beginTestAfterScan();
+    }
+
+    /** 扫码/质量检查通过后进入测试状态 */
+    public static void beginTestAfterScan() {
         work_status = 1;
-//            f_scan_data_bt_1.setEnabled(false);
         MesClient.tjFlag = 1;
-        MesClient.setMenuStatus("扫码成功,等待测试",0);
+        MesClient.mesStartFlag = 0;
+        MesClient.mesTjFlag = 0;
+        MesClient.lastQmPressure = "";
+        MesClient.lastQmLeak = "";
+        MesClient.check_quality_result = true;
+        MesClient.setMenuStatus("该工件可以测试,等待测试",0);
         product_sn.setEditable(false);
         if(MesClient.configParam.getStartMode().equals("自动启动")){
-            MesClient.serialPortUtils.start();
+            MesClient.commonQmDevice.start();
         }
         MesClient.result.setText("等待结果");
         MesClient.result.setForeground(Color.GRAY);
-//        f_scan_data_bt_1.setIcon(null);
-//        f_scan_data_bt_1.setText("启动");
+    }
 
+    /**
+     * 本地存库后提交MES(HTTP直传 qmresult,参照 OP-qm),成功则复位。
+     * @return true=可继续后续(含打印),false=MES上传失败已拦截
+     */
+    public static boolean afterTestSaveAndUpload(TestParam testParam) {
+        String testDate = testParam.getCreateTime();
+        if(testDate == null || testDate.isEmpty()){
+            testDate = DateLocalUtils.getCurrentTime();
+            testParam.setCreateTime(testDate);
+        }
+        // 本地库仍用合并后的压力/泄漏便于列表展示
+        TestParam localParam = new TestParam();
+        localParam.setSn(testParam.getSn());
+        localParam.setOprno(testParam.getOprno() != null ? testParam.getOprno() : "");
+        localParam.setParam1((testParam.getParam1() != null ? testParam.getParam1() : "")
+                + (testParam.getParam2() != null ? testParam.getParam2() : ""));
+        localParam.setParam2((testParam.getParam3() != null ? testParam.getParam3() : "")
+                + (testParam.getParam4() != null ? testParam.getParam4() : ""));
+        localParam.setParam3("");
+        localParam.setParam4("");
+        localParam.setResult(testParam.getResult());
+        JdbcUtils.insertTestRecord(localParam);
+
+        if(mes_enable){
+            JSONObject retObj = DataUtil.qmResultData(testParam);
+            if(retObj != null && retObj.get("result") != null && retObj.get("result").toString().equalsIgnoreCase("true")) {
+                if(MesClient.configParam.getPrintLabel().equals("是") && "OK".equals(testParam.getResult())){
+                    PrintUtil.printLabel(testParam.getSn(),
+                            (testParam.getParam1() != null ? testParam.getParam1() : "") + (testParam.getParam2() != null ? testParam.getParam2() : ""),
+                            (testParam.getParam3() != null ? testParam.getParam3() : "") + (testParam.getParam4() != null ? testParam.getParam4() : ""),
+                            testDate);
+                }
+                MesClient.resetForRetestKeepSn();
+                MesClient.setMenuStatus("测试结果上传成功,同件回车可再测,或扫下一件",0);
+                try { JdbcUtils.getTestData(); } catch (Exception ignore) {}
+                return true;
+            }else{
+                MesClient.mesStartFlag = 0;
+                MesClient.mesTjFlag = 0;
+                MesClient.setMenuStatus("测试结果上传失败,请重试(可直接再测本件)",-1);
+                return false;
+            }
+        }else{
+            if(MesClient.configParam.getPrintLabel().equals("是") && "OK".equals(testParam.getResult())){
+                PrintUtil.printLabel(testParam.getSn(),
+                        (testParam.getParam1() != null ? testParam.getParam1() : "") + (testParam.getParam2() != null ? testParam.getParam2() : ""),
+                        (testParam.getParam3() != null ? testParam.getParam3() : "") + (testParam.getParam4() != null ? testParam.getParam4() : ""),
+                        testDate);
+            }
+            MesClient.resetForRetestKeepSn();
+            try { JdbcUtils.getTestData(); } catch (Exception ignore) {}
+            return true;
+        }
+    }
+
+    /** 填充MES上传公共字段 */
+    public static void fillMesTestMeta(TestParam testParam) {
+        getUser();
+        testParam.setOprno(mes_gw);
+        testParam.setOprnoTitle(mes_gw_des);
+        testParam.setLineSn(mes_line_sn);
+        testParam.setUcode(user_menu != null ? user_menu.getText().trim() : "");
+        testParam.setParam5(programNo != null ? programNo.getText().trim() : "");
+        if(configParam != null){
+            testParam.setDeviceType(configParam.getDevice());
+        }
+        if(testParam.getRemark() == null){
+            testParam.setRemark("");
+        }
     }
 
     public static void scanBarcodeOld() {
@@ -849,7 +1014,16 @@ public class MesClient extends JFrame {
         f_scan_data_bt_1.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) {
                 scan_type = 1;
-                scanBarcode();
+                System.out.println("点击启动");
+                if(work_status != 1){
+                    MesClient.setMenuStatus("请先扫码并通过质量检查",-1);
+                    return;
+                }
+                if(commonQmDevice != null){
+                    commonQmDevice.start();
+                }else{
+                    MesClient.setMenuStatus("设备未初始化",-1);
+                }
             }
         });
 //        f_scan_data_bt_1.setIcon(new ImageIcon(MesClient.class.getResource("/bg/scan_barcode.png")));
@@ -1176,7 +1350,7 @@ public class MesClient extends JFrame {
         startMode.setBounds(140, 71, 200, 30);
         indexPanelD.add(startMode);
         
-        JLabel lblNewLabel_3_1_1 = new JLabel("串口号");
+        JLabel lblNewLabel_3_1_1 = new JLabel("串口号/IP");
         lblNewLabel_3_1_1.setHorizontalAlignment(SwingConstants.RIGHT);
         lblNewLabel_3_1_1.setFont(new Font("微软雅黑", Font.PLAIN, 16));
         lblNewLabel_3_1_1.setBounds(10, 123, 120, 30);
@@ -1188,7 +1362,7 @@ public class MesClient extends JFrame {
         serialPort.setBounds(140, 123, 200, 30);
         indexPanelD.add(serialPort);
         
-        JLabel lblNewLabel_3_1_1_1 = new JLabel("波特率");
+        JLabel lblNewLabel_3_1_1_1 = new JLabel("波特率/端口");
         lblNewLabel_3_1_1_1.setHorizontalAlignment(SwingConstants.RIGHT);
         lblNewLabel_3_1_1_1.setFont(new Font("微软雅黑", Font.PLAIN, 16));
         lblNewLabel_3_1_1_1.setBounds(10, 176, 120, 30);
@@ -1374,8 +1548,8 @@ public class MesClient extends JFrame {
                     isConfigEdit = 0;
 
                     formatConfigData();
-                    serialPortUtils.closePort();
-                    serialPortUtils = new SerialPortUtils(configParam.getSerialPort(),"","",configParam.getDevice());
+
+                    commonQmDevice.reconnect();
                 }
 
             }
@@ -1424,7 +1598,7 @@ public class MesClient extends JFrame {
         indexPanelD.add(lblNewLabel_3_1_1_1_1_1_1_1_1_1_1_1_1_1_1_2);
         
         device = new JComboBox();
-        device.setModel(new DefaultComboBoxModel(new String[] {"innomatec", "ateq"}));
+        device.setModel(new DefaultComboBoxModel(new String[] {"innomatec", "ateq", "中皖英泰"}));
         device.setFont(new Font("微软雅黑", Font.PLAIN, 16));
         device.setBounds(536, 445, 200, 30);
         indexPanelD.add(device);
@@ -1487,4 +1661,20 @@ public class MesClient extends JFrame {
         }
         MesClient.status_menu.setText(msg);
     }
+
+    /**
+     * 将字符串消息转为ByteBuf
+     * 16进制字符串转二进制
+     * @param hex 字符串消息
+     */
+    public static ByteBuf getSendByteBuf(String hex) {
+        byte[] bytes = new byte[hex.length() / 2];
+        for (int i = 0; i < hex.length(); i += 2) {
+            int value = Integer.parseInt(hex.substring(i, i + 2), 16);
+            bytes[i/2] = (byte)(value & 0xFF);
+        }
+        return Unpooled.wrappedBuffer(bytes);
+    }
+
+
 }

+ 5 - 61
src/com/mes/ui/MesRevice.java

@@ -1,49 +1,23 @@
 package com.mes.ui;
 
 import com.mes.netty.ProtocolParam;
-import com.mes.component.MyDialog;
 import com.mes.util.ErrorMsg;
 
-import javax.swing.*;
 import java.awt.*;
 
 public class MesRevice {
 
-    // 质量查询
+    // 质量查询(参照 OP-qm:UD 通过后进入测试)
     public static void checkQualityRevice(String processMsgRet,String mes_msg){
         try{
-//            String lmsg = "该工件本工位不可加工";
-//            MesClient.status_menu.setText(lmsg);
-//            new MyDialog(MesClient.mesClientFrame,"提示",lmsg);
             if(processMsgRet.equalsIgnoreCase("UD")) {
-                MesClient.status_menu.setForeground(Color.GREEN);
-                MesClient.check_quality_result = true;//质量合格,可以绑定加工
-                MesClient.status_menu.setText("该工件可以加工");
-                if(MesClient.work_status == 0 ){
-                    String barcode36 = MesClient.getBarcode(MesClient.product_sn.getText());//处理36为码
-                    MesClient.getUser();
-                    DataUtil.startWork(MesClient.nettyClient,barcode36,MesClient.user20);
-                }
+                MesClient.check_quality_result = true;
+                MesClient.beginTestAfterScan();
             }else {
                 MesClient.check_quality_result = false;
-
                 String lmsg = ErrorMsg.getErrorMsg(processMsgRet, ProtocolParam.getLx(mes_msg));
-
                 MesClient.setMenuStatus(lmsg,-1);
-//                MesClient.status_menu.setText(lmsg);
-//                new MyDialog(MesClient.mesClientFrame,"提示",lmsg);
-            }
-            if(MesClient.check_quality_result){
-                if(MesClient.work_status == 0){
-                    MesClient.finish_ok_bt.setEnabled(false);
-                    MesClient.finish_ng_bt.setEnabled(false);
-                }else{
-                    MesClient.finish_ok_bt.setEnabled(true);
-                    MesClient.finish_ng_bt.setEnabled(true);
-                }
-            }else{
-                MesClient.finish_ok_bt.setEnabled(false);
-                MesClient.finish_ng_bt.setEnabled(false);
+                MesClient.product_sn.setEditable(true);
             }
         }catch (Exception e){
             e.printStackTrace();
@@ -54,26 +28,7 @@ public class MesRevice {
     public static void startRevice(String processMsgRet,String mes_msg){
         try{
             if(processMsgRet.equalsIgnoreCase("OK")) {
-                MesClient.work_status = 1;
-
-                MesClient.f_scan_data_bt_1.setEnabled(false);
 
-//                String sn = MesClient.getBarcode(MesClient.product_sn.getText());
-//                MesClient.getUser();
-//                DataUtil.bindUser(MesClient.nettyClient,sn,MesClient.user20);
-
-                MesClient.finish_ok_bt.setEnabled(true);
-                MesClient.finish_ng_bt.setEnabled(true);
-
-                /*String qret = "OK";
-                Boolean sendret = DataUtil.sendQuality(MesClient.nettyClient,sn,qret,MesClient.user20);
-                if(!sendret){
-//                    MesClient.finish_ok_bt.setEnabled(true);
-//                    MesClient.finish_ng_bt.setEnabled(true);
-                    MesClient.status_menu.setText("结果提交失败,请重试");
-                    JOptionPane.showMessageDialog(MesClient.mesClientFrame,"结果提交失败,请重试","提示窗口", JOptionPane.INFORMATION_MESSAGE);
-                    return;
-                }*/
             }
         }catch (Exception e){
             e.printStackTrace();
@@ -106,22 +61,11 @@ public class MesRevice {
         }
     }
 
-    // 上传质量
+    // 上传质量(OP-qm 结果走 HTTP,此回调保留空实现)
     public static void updateResultRevice(String processMsgRet,String mes_msg){
         try{
             if(processMsgRet.equalsIgnoreCase("OK")) {
-
-                MesClient.resetScanA();
-//                MesClient.status_menu.setText("结果提交成功,请扫下一件");
-                MesClient.setMenuStatus("结果提交成功,请扫下一件",0);
-                MesClient.scan_type = 1;
-                MesClient.scanBarcode();
-
             }else{
-                MesClient.setMenuStatus("结果提交失败,请重试",-1);
-//                MesClient.status_menu.setText("结果提交失败,请重试");
-//                JOptionPane.showMessageDialog(MesClient.mesClientFrame,"结果提交失败,请重试","提示窗口", JOptionPane.INFORMATION_MESSAGE);
-//                return;
             }
         }catch (Exception e){
             e.printStackTrace();

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

@@ -6,18 +6,10 @@ 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"
+            "OP360"
     };
     public static String[] xtoprnodes = new String[]{
-            "镭雕二维码","小总成焊接(边梁、后梁)","框架焊接","人工补焊","框架矫形","焊道检验","CNC总成反面(1序)","总成反面清洁",
-            "框架找漏","冷板安装+拉铆","清理溢胶","水冷板FSW","CNC总成反面(2序)","CNC总成正面加工","总成正面清洁","框架终检",
-            "恒温静置","正面安装钢丝螺套","反面安装钢丝螺套","反面拉铆","半成品气密","涂液冷板加强件结构胶","涂密封胶 安装加强件","清胶",
-            "胶水固化","底护板预装+水嘴安装","底护板装配","成品气密","液冷板气密","反面贴EPDM保温棉","贴PI膜/限位条","正面涂胶+拉铆",
-            "安装复合横梁","正面贴EPDM保温棉","绝缘耐压测试","在线检测(错漏)","在线检测(尺寸)","终检","GP12","包装"
+            "总成气密"
     };
     public static String[] lboprnos = new String[]{
             "OP040","OP050","OP060","OP070","OP080","OP090","OP100","OP110",

+ 55 - 10
src/com/mes/ui/Test2.java

@@ -1,5 +1,11 @@
 package com.mes.ui;
 
+import com.mes.util.ytnetty.QmCurUtil;
+import com.mes.util.ytnetty.QmResultUtil;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufUtil;
+import io.netty.buffer.Unpooled;
+
 import javax.print.attribute.HashPrintRequestAttributeSet;
 import javax.print.attribute.PrintRequestAttributeSet;
 import javax.print.attribute.standard.PrintQuality;
@@ -10,6 +16,7 @@ import java.awt.Graphics2D;
 import java.awt.print.PageFormat;
 import java.awt.print.Printable;
 import java.awt.print.Book;
+import java.nio.charset.Charset;
 
 public class Test2 implements Printable {
     public int print(Graphics g, PageFormat pf, int page) throws PrinterException {
@@ -26,17 +33,55 @@ public class Test2 implements Printable {
     }
 
     public static void main(String[] args) {
-        PrinterJob job = PrinterJob.getPrinterJob();
-        job.setPrintable(new Test2());
-        boolean doPrint = job.printDialog();
-        if (doPrint) {
-            try {
-                PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet();
-                attributes.add(PrintQuality.DRAFT);
-                job.print(attributes);
-            } catch (PrinterException e) {
-                e.printStackTrace();
+        try{
+            String hexString = "435330303335363230323630373036313630313032303030202020202020202020202020202020202020202020202020202020202020303030312E35353331303030323031332E32383030";
+//            ByteBuf bccbf = Unpooled.wrappedBuffer(str.getBytes("UTF-8"));
+////            String ss = bccbf.toString(Charset.forName("UTF-8"));
+//            String ss = ByteBufUtil.hexDump(bccbf).toUpperCase();
+
+            hexString = "5253302C2D302E33332C302E302C302E302C302E3030";
+
+            QmCurUtil qmCurUtil = new QmCurUtil(hexString);
+            System.out.println("qmCurUtil:"+qmCurUtil.toString());
+
+            //5253 302C 2D30 2E33332C302E302C302E302C302E3030
+
+            hexString = "435330303336313230323630373135313130383439303030202020202020202020202020202020202020202020202020202020202020303939392E39393337303030303135312E39313030";
+
+            QmResultUtil qmResultUtil = new QmResultUtil(hexString);
+            System.out.println("qmResultUtil:"+qmResultUtil.toString());
+
+//            String hexString = "5253"; // 16进制表示的"Hello"
+            String asciiString = new String(hexStringToByteArray(hexString));
+            System.out.println(asciiString); // 输出: Hello
+
+
+            String input = "008";
+            StringBuilder hexValues = new StringBuilder();
+            for (char c : input.toCharArray()) {
+                int asciiValue = (int) c; // 获取ASCII值
+                String hexValue = Integer.toHexString(asciiValue); // 转换为16进制字符串
+                if (hexValues.length() > 0) { // 如果不是第一个字符,添加空格分隔
+                    hexValues.append("");
+                }
+                hexValues.append(hexValue); // 添加到StringBuilder中
             }
+            System.out.println("Hex values: " + hexValues.toString());
+
+//            System.out.println(ss);
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+
+    }
+
+    public static byte[] hexStringToByteArray(String s) {
+        int len = s.length();
+        byte[] data = new byte[len / 2];
+        for (int i = 0; i < len; i += 2) {
+            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+                    + Character.digit(s.charAt(i+1), 16));
         }
+        return data;
     }
 }

+ 30 - 14
src/com/mes/util/Base64Utils.java

@@ -1,19 +1,35 @@
 package com.mes.util;
 
-import com.mes.ui.MesClient;
-import org.apache.commons.codec.binary.Base64;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import java.util.Base64;
+import java.io.UnsupportedEncodingException;
 
 public class Base64Utils {
-    public static final Logger log =  LoggerFactory.getLogger(Base64Utils.class);
-	public static String getBase64(String str) {
-		// 待编码的二进制数据
-        byte[] binaryData = str.getBytes();
-        // 使用Base64.encodeBase64String进行编码
-        String encodedString = Base64.encodeBase64String(binaryData);
-        // 输出编码后的结果
-        log.info("Base64编码结果: " + encodedString);
-        return encodedString;
-	}
+
+    public static String getBase64(String str) {
+        if (str == null || str.isEmpty()) {
+            return "";
+        }
+
+        try {
+            byte[] bytes = str.getBytes("UTF-8");
+            return Base64.getEncoder().encodeToString(bytes);
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+            return "";
+        }
+    }
+
+    public static String decodeBase64(String base64Str) {
+        if (base64Str == null || base64Str.isEmpty()) {
+            return "";
+        }
+
+        try {
+            byte[] bytes = Base64.getDecoder().decode(base64Str);
+            return new String(bytes, "UTF-8");
+        } catch (Exception e) {
+            e.printStackTrace();
+            return "";
+        }
+    }
 }

+ 115 - 0
src/com/mes/util/CommonQmDevice.java

@@ -0,0 +1,115 @@
+package com.mes.util;
+
+import com.mes.ui.ConfigParam;
+import com.mes.ui.MesClient;
+import com.mes.util.ytnetty.YtNettyClient;
+import com.mes.util.ytnetty.YtUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.awt.*;
+import java.util.Arrays;
+import java.util.Timer;
+import java.util.TimerTask;
+
+public class CommonQmDevice {
+    public static final Logger log =  LoggerFactory.getLogger(SerialPortUtils.class);
+    public String device;
+    public SerialPortUtils serialPortUtils; // 串口
+    public YtNettyClient ytClient; // 网口 中皖英泰
+    public boolean isOnline; // 是否在线
+    ConfigParam configParam;
+
+    public CommonQmDevice(ConfigParam configParam) {
+        this.device = configParam.getDevice();
+        this.configParam = configParam;
+        if(configParam.getDevice().equals("中皖英泰")){
+            try {
+                if(ytClient==null) {
+                    String ip = configParam.getSerialPort();
+                    String port = configParam.getBaudRate();
+                    //初始化TCP连接
+                    ytClient = new YtNettyClient();
+                    try{
+                        ytClient.run(ip,Integer.parseInt(port));
+//                    ytClient.run("192.168.0.253",3036);
+                        workTimerTask();
+                    }catch (Exception e){
+                        e.printStackTrace();
+                    }
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }else{ // 串口
+            serialPortUtils = new SerialPortUtils(configParam.getSerialPort(),"","",configParam.getDevice());
+        }
+    }
+
+    public boolean isOnline() {
+        isOnline = false;
+        if(device.equals("中皖英泰")){
+            isOnline = ytClient.getTcpOnline() == 1;
+        }else{ // 串口
+            isOnline = serialPortUtils.isOpen;
+        }
+        return isOnline;
+    }
+
+    public void reconnect(){
+        if(device.equals("中皖英泰")){
+            try {
+                ytClient = null;
+                String ip = configParam.getSerialPort();
+                String port = configParam.getBaudRate();
+                //初始化TCP连接
+                ytClient = new YtNettyClient();
+                try{
+                    ytClient.run(ip,Integer.parseInt(port));
+//                    ytClient.run("192.168.0.253",3036);
+                    workTimerTask();
+                }catch (Exception e){
+                    e.printStackTrace();
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }else{ // 串口
+            serialPortUtils = new SerialPortUtils(configParam.getSerialPort(),"","",configParam.getDevice());
+        }
+    }
+
+    public Timer workTimer;
+    public void workTimerTask() {
+        if(workTimer!=null) {
+            workTimer.cancel();
+        }
+        workTimer = new Timer();
+        workTimer.schedule(new TimerTask() {
+            public void run() {
+                try{
+                    if (MesClient.work_status == 1) {
+                        // 循环查询实时结果
+                        ytClient.future.channel().writeAndFlush(YtUtil.getSendByteBuf(YtUtil.getCurDataCommon()));
+                    }
+                }catch (Exception e){
+                    e.printStackTrace();
+                }
+            }
+        }, 500, 500);
+    }
+
+    public boolean start() {
+        try{
+            if(device.equals("中皖英泰")){
+                ytClient.future.channel().writeAndFlush(YtUtil.getSendByteBuf(YtUtil.getStartCommon()));
+            }else{ // 串口
+                serialPortUtils.start();
+            }
+        }catch (Exception e){
+            e.printStackTrace();
+            return false;
+        }
+        return true;
+    }
+}

+ 26 - 17
src/com/mes/util/SerialPortUtils.java

@@ -23,7 +23,7 @@ public class SerialPortUtils {
     public boolean isStop;//是否结束
     public String oprno;
     public String oprnoName;
-    public StringBuilder dataBuilder ;
+    public StringBuilder dataBuilder;
     private static final byte[] buffer = new byte[1024* 5];
     private static int bufferEnd = 0;
     public String device;
@@ -77,7 +77,7 @@ public class SerialPortUtils {
                                     if (data != null && MesClient.work_status == 1) {
                                         if (true){
                                             if (MesClient.tjFlag == 1) {
-                                                if (data.trim().equals("RUN") || data.split("\t").length == 3) {
+                                                if (data.trim().equals("RUN") || data.trim().split("\t").length == 3) {
                                                     log.info("运行开始了");
                                                     MesClient.tjFlag = 2;
                                                     MesClient.setMenuStatus(MesClient.tjFlagText2,0);
@@ -87,8 +87,10 @@ public class SerialPortUtils {
                                                 }
                                             }
                                             if (MesClient.tjFlag == 2) {
-                                                if (data.split("\t").length == 3) {//例  data= 2.5	1.1	0.000   时间(s) 压力(hpa)  压降(pa)
-                                                    String[] lists = data.split("\\s+"); // 使用空格进行分割,\\s+ 表示匹配一个或多个空白字符
+                                                log.info("收到数据2:" + data.trim());
+                                                log.info("收到数据3:" + data.trim());
+                                                if (data.trim().split("\t").length == 3) {//例  data= 2.5	1.1	0.000   时间(s) 压力(hpa)  压降(pa)
+                                                    String[] lists = data.trim().split("\\s+"); // 使用空格进行分割,\\s+ 表示匹配一个或多个空白字符
                                                     if (lists.length == 3) {
                                                         double yali = Double.parseDouble(lists[1].trim());
                                                         double dividedValue = yali / 10;
@@ -99,7 +101,7 @@ public class SerialPortUtils {
                                                         MesClient.param2.setText(lists[2]);
 //
                                                     }
-                                                } else if (data.length() == 97) {//检测结束
+                                                } else if (data.length() == 97||data.length() == 98) {//检测结束
                                                     log.info("检测结束");
                                                     //结果
                                                     String result = null;
@@ -140,21 +142,28 @@ public class SerialPortUtils {
 
                                                         TestParam testParam = new TestParam();
                                                         testParam.setSn(MesClient.product_sn.getText().trim());
-                                                        testParam.setParam1(yaLi + yaLiUnit);
-                                                        testParam.setParam2(leakValue);
-                                                        testParam.setOprno("");
-                                                        testParam.setParam3("");
-                                                        testParam.setParam4("");
+                                                        testParam.setParam1(yaLi);
+                                                        testParam.setParam2(yaLiUnit);
+                                                        String leakValOnly;
+                                                        String leakUnitOnly;
+                                                        if(MesClient.configParam.getLeakage().equals("压降")){
+                                                            leakValOnly = yaJiang;
+                                                            leakUnitOnly = yaJiangUnit;
+                                                        }else{
+                                                            leakValOnly = leakRate;
+                                                            leakUnitOnly = leakRateUnit;
+                                                        }
+                                                        testParam.setParam3(leakValOnly);
+                                                        testParam.setParam4(leakUnitOnly);
                                                         testParam.setResult(lastRet);
-
-                                                        String testDate = DateLocalUtils.getCurrentTime();
-                                                        JdbcUtils.insertTestRecord(testParam);
-
-                                                        if(MesClient.configParam.getPrintLabel().equals("是") && lastRet.equals("OK")){
-                                                            PrintUtil.printLabel(testParam.getSn(),testParam.getParam1(),testParam.getParam2(),testDate);
+                                                        if(lastRet.equals("NG")){
+                                                            testParam.setRemark(result);
+                                                        }else{
+                                                            testParam.setRemark("");
                                                         }
+                                                        MesClient.fillMesTestMeta(testParam);
+                                                        MesClient.afterTestSaveAndUpload(testParam);
 
-                                                        MesClient.resetScanA();
                                                         MesClient.scan_type = 1;
                                                         MesClient.scanBarcode();
 

+ 75 - 0
src/com/mes/util/TestParam.java

@@ -4,13 +4,19 @@ public class TestParam {
 
     public Integer id;
     public String sn;
+    public String ucode;
+    public String lineSn;
     public String oprno;
+    public String oprnoTitle;
     public String createTime;
     public String param1;
     public String param2;
     public String param3;
     public String param4;
+    public String param5;
     public String result;
+    public String remark;
+    public String deviceType;
 
     public Integer getId() {
         return id;
@@ -83,4 +89,73 @@ public class TestParam {
     public void setResult(String result) {
         this.result = result;
     }
+
+    public String getOprnoTitle() {
+        return oprnoTitle;
+    }
+
+    public void setOprnoTitle(String oprnoTitle) {
+        this.oprnoTitle = oprnoTitle;
+    }
+
+    public String getParam5() {
+        return param5;
+    }
+
+    public void setParam5(String param5) {
+        this.param5 = param5;
+    }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark;
+    }
+
+    public String getUcode() {
+        return ucode;
+    }
+
+    public void setUcode(String ucode) {
+        this.ucode = ucode;
+    }
+
+    public String getDeviceType() {
+        return deviceType;
+    }
+
+    public void setDeviceType(String deviceType) {
+        this.deviceType = deviceType;
+    }
+
+    public String getLineSn() {
+        return lineSn;
+    }
+
+    public void setLineSn(String lineSn) {
+        this.lineSn = lineSn;
+    }
+
+    @Override
+    public String toString() {
+        return "TestParam{" +
+                "id=" + id +
+                ", sn='" + sn + '\'' +
+                ", ucode='" + ucode + '\'' +
+                ", lineSn='" + lineSn + '\'' +
+                ", oprno='" + oprno + '\'' +
+                ", oprnoTitle='" + oprnoTitle + '\'' +
+                ", createTime='" + createTime + '\'' +
+                ", param1='" + param1 + '\'' +
+                ", param2='" + param2 + '\'' +
+                ", param3='" + param3 + '\'' +
+                ", param4='" + param4 + '\'' +
+                ", param5='" + param5 + '\'' +
+                ", result='" + result + '\'' +
+                ", remark='" + remark + '\'' +
+                ", deviceType='" + deviceType + '\'' +
+                '}';
+    }
 }

+ 17 - 15
src/com/mes/util/WorkTimer.java

@@ -62,7 +62,11 @@ public class WorkTimer {
                             isEnd = true;
                         }
                     }else{
-                        MesClient.mesStartFlag = 1;
+                        // 新中间步骤:开启本轮;上一轮已入库则开新一轮
+                        if(MesClient.mesStartFlag == 0 || MesClient.mesTjFlag == 1){
+                            MesClient.mesStartFlag = 1;
+                            MesClient.mesTjFlag = 0;
+                        }
                         MesClient.setMenuStatus("当前步骤:"+realtimeResult.stepCode+":"+realtimeResult.step, 0); // 当前步骤
                     }
 
@@ -95,22 +99,20 @@ public class WorkTimer {
                         String sn = MesClient.product_sn.getText().trim();
 
                         TestParam testParam = new TestParam();
-                        testParam.setSn(MesClient.product_sn.getText().trim());
-                        testParam.setParam1(lastResult.pressureValue + lastResult.pressureUnit);
-                        testParam.setParam2(lastResult.leakValue + lastResult.leakUnit);
-                        testParam.setOprno("");
-                        testParam.setParam3("");
-                        testParam.setParam4("");
-                        testParam.setResult(lastRet);
-
-                        String testDate = DateLocalUtils.getCurrentTime();
-                        JdbcUtils.insertTestRecord(testParam);
-
-                        if(MesClient.configParam.getPrintLabel().equals("是") && lastRet.equals("OK")){
-                            PrintUtil.printLabel(testParam.getSn(),testParam.getParam1(),testParam.getParam2(),testDate);
+                        testParam.setSn(sn);
+                        testParam.setParam1(lastResult.pressureValue + "");
+                        testParam.setParam2(lastResult.pressureUnit);
+                        if(lastResult.leakValue == 0 && !lastResult.isPass){
+                            testParam.setParam3("9999");
+                        }else{
+                            testParam.setParam3(lastResult.leakValue + "");
                         }
+                        testParam.setParam4(lastResult.leakUnit);
+                        testParam.setResult(lastRet);
+                        testParam.setRemark("");
+                        MesClient.fillMesTestMeta(testParam);
+                        MesClient.afterTestSaveAndUpload(testParam);
 
-                        MesClient.resetScanA();
                         MesClient.scan_type = 1;
                         MesClient.scanBarcode();
                     }

+ 61 - 0
src/com/mes/util/ytnetty/QmCurUtil.java

@@ -0,0 +1,61 @@
+package com.mes.util.ytnetty;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class QmCurUtil {
+    public static final Logger log =  LoggerFactory.getLogger(QmCurUtil.class);
+
+    public final String step; // 0=待机 4=充气 1=排气 65535=结束
+    public final String temperature; // 温度等扩展字段
+    public final String pressureValue;                // 压力值
+    public final String leakValue;                    // 泄漏值
+
+    public QmCurUtil(String msg) {
+        // 新协议:RS,65535,0,0,4.7,0.0,0.0,0.0,0.0, (整包 hex 实为 ASCII CSV)
+        String ascii = new String(YtUtil.hexStringToByteArray(msg));
+        if (ascii.indexOf(',') >= 0) {
+            String[] parts = ascii.split(",", -1);
+            this.step = part(parts, 1);
+            this.pressureValue = part(parts, 4);
+            this.leakValue = part(parts, 5);
+            this.temperature = part(parts, 6);
+            return;
+        }
+        // 旧协议:定长二进制字段
+        this.step = new String(YtUtil.hexStringToByteArray(msg.substring(4, 6)));
+        this.temperature = new String(YtUtil.hexStringToByteArray(msg.substring(36, 42)));
+        this.leakValue = new String(YtUtil.hexStringToByteArray(msg.substring(28, 34)));
+        this.pressureValue = new String(YtUtil.hexStringToByteArray(msg.substring(20, 26)));
+    }
+
+    private static String part(String[] parts, int index) {
+        if (parts == null || index < 0 || index >= parts.length) {
+            return "";
+        }
+        return parts[index] == null ? "" : parts[index].trim();
+    }
+
+    /**
+     * 开启本轮:仅充气/保压/测试等中间步。
+     * 不含 0/1/9/65535,避免上一轮结束后设备停在结束态,扫新码被立刻当成新一轮并提交旧结果。
+     */
+    public boolean isRunningStep() {
+        return step != null && !step.isEmpty() && !isEndStep();
+    }
+
+    /** 读最终结果的结束步(含新协议 65535) */
+    public boolean isEndStep() {
+        return "65535".equals(step) || "1".equals(step) || "9".equals(step) || "0".equals(step);
+    }
+
+    @Override
+    public String toString() {
+        return "QmCurUtil{" +
+                "step='" + step + '\'' +
+                ", temperature='" + temperature + '\'' +
+                ", pressureValue='" + pressureValue + '\'' +
+                ", leakValue='" + leakValue + '\'' +
+                '}';
+    }
+}

+ 97 - 0
src/com/mes/util/ytnetty/QmResultUtil.java

@@ -0,0 +1,97 @@
+package com.mes.util.ytnetty;
+
+import com.mes.util.DataUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Arrays;
+
+public class QmResultUtil {
+    public static final Logger log =  LoggerFactory.getLogger(QmResultUtil.class);
+
+    public final String num; // 记录编号
+    public final String testDate; // 记录编号
+    public final String sn; // 工件号
+    public final String resultType; // 结果符号
+    public final String result; // 结果
+    public final String programNumber;               // 程序号
+    public final String pressureValue;                // 压力值
+    public final String leakValue;                    // 泄漏值
+    public final String pressureUnit;                 // 压力单位
+    public final String leakUnit;                     // 泄漏单位
+
+    public QmResultUtil(String msg) {
+        this.num = new String(YtUtil.hexStringToByteArray(msg.substring(4,14)));
+        this.testDate = new String(YtUtil.hexStringToByteArray(msg.substring(14,42)));
+        this.sn = new String(YtUtil.hexStringToByteArray(msg.substring(48,108)));
+        this.resultType = new String(YtUtil.hexStringToByteArray(msg.substring(108,110)));
+        String leak = Double.valueOf(new String(YtUtil.hexStringToByteArray(msg.substring(110,122))))+"";
+        this.leakUnit = formatLeakUnit(new String(YtUtil.hexStringToByteArray(msg.substring(122,124))));
+        this.result = formatResult(new String(YtUtil.hexStringToByteArray(msg.substring(124,126))));
+        this.programNumber = new String(YtUtil.hexStringToByteArray(msg.substring(126,130)));
+        this.pressureValue = Double.valueOf(new String(YtUtil.hexStringToByteArray(msg.substring(130,146))))+"";
+        this.pressureUnit = "kpa";
+        if(this.resultType.equals("1")){
+             leak = "-"+leak;
+        }
+        this.leakValue = leak;
+    }
+
+    @Override
+    public String toString() {
+        return "QmResultUtil{" +
+                "num='" + num + '\'' +
+                ", testDate='" + testDate + '\'' +
+                ", sn='" + sn + '\'' +
+                ", resultType='" + resultType + '\'' +
+                ", result='" + result + '\'' +
+                ", programNumber='" + programNumber + '\'' +
+                ", pressureValue='" + pressureValue + '\'' +
+                ", leakValue='" + leakValue + '\'' +
+                ", pressureUnit='" + pressureUnit + '\'' +
+                ", leakUnit='" + leakUnit + '\'' +
+                '}';
+    }
+
+    public String formatLeakUnit(String leakUnit) {
+        String unit = "";
+        switch (leakUnit) {
+            case "0":
+                unit = "P";
+                break;
+            case "1":
+                unit = "Pa/s";
+                break;
+            case "2":
+                unit = "mL/s";
+                break;
+            case "3":
+                unit = "mL/min";
+                break;
+            case "4":
+                unit = "cc/min";
+                break;
+        }
+        return unit;
+    }
+
+    public String formatResult(String result) {
+        if (result == null || result.trim().isEmpty()) {
+            return "NG";
+        }
+        switch (result.trim()) {
+            case "1":
+                return "OK";
+            case "2": // +NG
+            case "3": // 大漏
+            case "4": // 正向超量程
+            case "5": // -NG
+            case "6": // 负向超量程
+            case "7": // 压力不足
+            case "9": // 压力超限
+                return "NG";
+            default:
+                return "NG";
+        }
+    }
+}

+ 111 - 0
src/com/mes/util/ytnetty/YtDecoderServer.java

@@ -0,0 +1,111 @@
+package com.mes.util.ytnetty;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufUtil;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.ByteToMessageDecoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+
+public class YtDecoderServer extends ByteToMessageDecoder {
+
+    private static final byte START_CHAR = (byte) 0x02; // 假设的起始字符
+    private static final byte END_CHAR = (byte) 0x03; // 假设的结束字符
+    private final ByteBuf msgin = Unpooled.buffer();
+    private final Charset charset = Charset.forName("UTF-8");
+
+    private static final Logger logger = LoggerFactory.getLogger(YtDecoderServer.class);
+
+
+    @Override
+    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
+        logger.info(Thread.currentThread() + "收到了一次数据包,长度是:" + in.readableBytes());
+        String content = ByteBufUtil.hexDump(in).toUpperCase();
+        logger.info("接收包内容:" + in.toString(charset));
+        logger.info("接收包内容2:" +   content);
+
+        String content2 = hexStringToAscii(ByteBufUtil.hexDump(in)).toLowerCase();
+
+        while (in.isReadable()) {
+            byte b = in.readByte();
+            if (b == START_CHAR) {
+                // 当遇到起始字符时,重置消息StringBuilder
+                msgin.clear();
+            } else if (b == END_CHAR) {
+                // 当遇到结束字符时,将消息加入到解码列表中
+                String content3 = ByteBufUtil.hexDump(msgin).toUpperCase();
+                logger.info("接收信息:" + msgin.toString(charset));
+                logger.info("接收信息2:" + content3);
+//                out.add(content3);
+                out.add(content3);
+            } else {
+                // 正常的消息字符,追加到StringBuilder
+                msgin.writeByte(b);
+            }
+        }
+    }
+
+    /**
+     * 计算16进制字符串的BCC校验码
+     * @param hexData 16进制字符串
+     * @return BCC校验码
+     */
+    public static byte calculateBCC(String hexData) {
+        byte bcc = 0; // 初始化BCC校验码为0
+        for (int i = 0; i < hexData.length(); i += 2) { // 每次处理两个字符(1个字节)
+            String byteStr = hexData.substring(i, i + 2); // 获取当前16进制字节
+            int byteValue = Integer.parseInt(byteStr, 16); // 将16进制字符串转换为整数
+            bcc ^= byteValue; // 执行异或操作
+        }
+        return bcc; // 返回计算后的BCC校验码
+    }
+
+    // 16字符串转Ascii
+    private String hexStringToAscii(String hexString) {
+        StringBuilder sbuilder = new StringBuilder();
+        for (int i = 0; i < hexString.length(); i += 2) {
+            String hexByte = hexString.substring(i, i + 2);
+            int byteValue = Integer.parseInt(hexByte, 16);
+            char c = (char) byteValue;
+            sbuilder.append(c);
+        }
+        return sbuilder.toString();
+    }
+
+    public static String hexStringToString(String str) {
+        StringBuilder name = new StringBuilder();
+        String[] split = str.split("\\\\x");
+        name.append(split[0]);
+        for (int i = 1; i < split.length; i++) {
+            if (!split[i].isEmpty() && split.length > i + 2 && split[i].length() == 2 && split[i + 1].length() == 2 && split[i+2].length() >= 2) {
+                String name16 = split[i] + split[i + 1] + split[i + 2].substring(0, 2);
+                // name16 = name16.replace(" ", "");
+                byte[] baKeyword = new byte[name16.length() / 2];
+                for (int j = 0; j < baKeyword.length; j++) {
+                    try {
+                        baKeyword[j] = (byte) (0xff & Integer.parseInt(name16.substring(j * 2, j * 2 + 2), 16));
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                }
+                try {
+                    name16 = new String(baKeyword, StandardCharsets.UTF_8);
+                } catch (Exception e1) {
+                    e1.printStackTrace();
+                }
+                name.append(name16);
+                name.append(split[i + 2].substring(2));
+                i = i + 2;
+            }else {
+                name.append("\\\\x" + split[i]);
+            }
+        }
+        return name.toString();
+    }
+
+}

+ 60 - 0
src/com/mes/util/ytnetty/YtEncoderServer.java

@@ -0,0 +1,60 @@
+package com.mes.util.ytnetty;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufUtil;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.MessageToByteEncoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class YtEncoderServer extends MessageToByteEncoder<String> {
+
+    private static final String START_CHAR = "02"; // 假设的起始字符
+    private static final String END_CHAR = "03"; // 假设的结束字符
+    private static final Logger logger = LoggerFactory.getLogger(YtEncoderServer.class);
+
+    @Override
+    protected void encode(ChannelHandlerContext channelHandlerContext, String message, ByteBuf out) throws Exception {
+        //String message 16禁止字符串
+        String contstr = START_CHAR + message + END_CHAR;
+        System.out.println("contstr:"+contstr);
+        String bcc = String.format("%02x",calculateBCC(contstr));
+
+        String allstr = contstr+bcc;
+        System.out.println("allstr:"+allstr);
+
+        ByteBuf bccbf = Unpooled.wrappedBuffer(allstr.getBytes("UTF-8"));
+        out.writeBytes(bccbf);
+
+//        String content2 = hexStringToAscii(ByteBufUtil.hexDump(buf));
+        bccbf.release(); // 释放ByteBuf资源
+    }
+
+    // 16字符串转Ascii
+    private String hexStringToAscii(String hexString) {
+        StringBuilder sbuilder = new StringBuilder();
+        for (int i = 0; i < hexString.length(); i += 2) {
+            String hexByte = hexString.substring(i, i + 2);
+            int byteValue = Integer.parseInt(hexByte, 16);
+            char c = (char) byteValue;
+            sbuilder.append(c);
+        }
+        return sbuilder.toString();
+    }
+
+    /**
+     * 计算16进制字符串的BCC校验码
+     * @param hexData 16进制字符串
+     * @return BCC校验码
+     */
+    public static byte calculateBCC(String hexData) {
+        byte bcc = 0; // 初始化BCC校验码为0
+        for (int i = 0; i < hexData.length(); i += 2) { // 每次处理两个字符(1个字节)
+            String byteStr = hexData.substring(i, i + 2); // 获取当前16进制字节
+            int byteValue = Integer.parseInt(byteStr, 16); // 将16进制字符串转换为整数
+            bcc ^= byteValue; // 执行异或操作
+        }
+        return bcc; // 返回计算后的BCC校验码
+    }
+}

+ 76 - 0
src/com/mes/util/ytnetty/YtNettyClient.java

@@ -0,0 +1,76 @@
+package com.mes.util.ytnetty;
+
+import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.*;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import io.netty.handler.timeout.IdleStateHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.TimeUnit;
+
+public class YtNettyClient {
+
+    public static final Logger log =  LoggerFactory.getLogger(YtNettyClientHandler.class);
+    public static SocketChannel socketChannel;
+    public static ChannelFuture future;
+    //配置线程组
+    public static EventLoopGroup group = new NioEventLoopGroup();
+    //创建服务启动器
+    public static Bootstrap bootstrap = new Bootstrap();
+
+    public static String ip;
+    public static int port;
+    public static int tcpOnline = 0; // 0不在线 1=在线
+
+    public static void run(String inip, int inport) {
+        try{
+            ip = inip;
+            port = inport;
+            //配置参数
+            bootstrap.group(group)
+                    .channel(NioSocketChannel.class)
+                    .option(ChannelOption.TCP_NODELAY,true)
+                    .handler(new ChannelInitializer<SocketChannel>() {
+                        protected void initChannel(SocketChannel socketChannel) throws Exception {
+                            socketChannel.pipeline()
+                                    .addLast("decoder", new YtDecoderServer())
+                                    .addLast("encoder",new YtEncoderServer())
+                                    .addLast(new IdleStateHandler(60, 90, 120, TimeUnit.SECONDS))
+                                    .addLast(new YtNettyClientHandler());
+                        }
+                    })
+                    .remoteAddress(ip,port);
+            doConnect();
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+
+    }
+
+    public static void doConnect() throws InterruptedException {
+        tcpOnline = 0;
+        //连接
+        future = bootstrap.connect();
+        log.info("客户端正在连接服务端...");
+        //客户端断线重连逻辑
+        future.addListener((ChannelFutureListener) future1 -> {
+            if (future1.isSuccess()) {
+                log.info("客户端连接服务端成功...");
+                tcpOnline = 1;
+            } else {
+                future1.channel().eventLoop().schedule(() -> run(ip,port), 10, TimeUnit.SECONDS);
+            }
+        });
+        socketChannel = (SocketChannel) future.channel();
+    }
+
+    public static int getTcpOnline(){
+        return tcpOnline;
+    }
+}
+
+
+

+ 205 - 0
src/com/mes/util/ytnetty/YtNettyClientHandler.java

@@ -0,0 +1,205 @@
+package com.mes.util.ytnetty;
+
+import com.mes.ui.MesClient;
+import com.mes.util.TestParam;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.handler.timeout.IdleState;
+import io.netty.handler.timeout.IdleStateEvent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.awt.*;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class YtNettyClientHandler extends ChannelInboundHandlerAdapter {
+
+    public static final Logger log =  LoggerFactory.getLogger(YtNettyClientHandler.class);
+
+    private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+    public static byte[] responseByte;
+
+    //当前超时次数
+    private int timeoutNum = 0;
+
+    //运行最大超时次数
+    private int timeoutNumMax = 3;
+
+    @Override
+    public void channelActive(ChannelHandlerContext ctx) throws Exception {
+        log.info("mes connecting:" + sdf.format(new Date()));
+//        YtNettyClient.tcpOnline = 1;
+    }
+
+    @Override
+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+        Channel channel = ctx.channel();
+        log.error("close tcp, ip:" + channel.remoteAddress());
+        YtNettyClient.tcpOnline = 0;
+
+        System.out.println("3s 之后尝试重新连接服务器...");
+        Thread.sleep(3 * 1000);
+        YtNettyClient.doConnect();
+    }
+
+    //读写超时发送心跳
+    @Override
+    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
+        IdleState state = ((IdleStateEvent) evt).state();
+        if (state.equals(IdleState.READER_IDLE)) {
+            System.out.println("客户端read超时" + (timeoutNum++) + "次");
+
+            if (timeoutNum > timeoutNumMax) {
+                System.out.println("超时次数上限,关闭这个不活跃的连接");
+                ctx.channel().close();
+            }
+        }
+        if(state.equals(IdleState.ALL_IDLE)){
+            //给服务端端发送心跳请求
+            sendHeartbeatPacket(ctx);
+        }
+    }
+
+    @Override
+    public void channelRead(ChannelHandlerContext ctx, Object message) throws Exception {
+        timeoutNum = 0;
+        log.info("message:"+message);
+        String msg = message+"";
+        String code = YtUtil.getCode(msg);
+        log.info("code:"+code);
+        log.info("msg:"+msg);
+        try{
+            switch (code){
+                case "4353": // 测试结果
+                    // 未扫码、未进入本轮测试、工件码为空、或本轮已入库时,忽略旧结果/重复结果
+                    if(MesClient.work_status != 1){
+                        log.info("忽略测试结果:未扫码,work_status={}", MesClient.work_status);
+                        break;
+                    }
+                    if(MesClient.mesStartFlag != 1){
+                        log.info("忽略测试结果:本轮测试尚未开始(未检测到充气等中间步骤),可能是上一件旧结果");
+                        break;
+                    }
+                    if(MesClient.mesTjFlag != 0){
+                        log.info("忽略测试结果:本轮结果已处理,mesTjFlag={}", MesClient.mesTjFlag);
+                        break;
+                    }
+                    String sn = MesClient.product_sn.getText().trim();
+                    if(sn.isEmpty()){
+                        log.info("忽略测试结果:工件码为空");
+                        break;
+                    }
+                    // 先占位,防止同一轮重复入库
+                    MesClient.mesTjFlag = 1;
+
+                    QmResultUtil qmResultUtil = new QmResultUtil(msg);
+                    log.info("qmResultUtil:"+qmResultUtil.toString());
+                    // 压强/泄漏数值优先用本轮 RS(与气密仪一致);单位仍取 4353(RS 无单位字段)
+                    boolean useCur = MesClient.lastQmPressure != null && !MesClient.lastQmPressure.trim().isEmpty();
+                    String pressureValue = useCur ? MesClient.lastQmPressure.trim() : qmResultUtil.pressureValue;
+                    String leakValue = useCur && MesClient.lastQmLeak != null
+                            ? MesClient.lastQmLeak.trim() : qmResultUtil.leakValue;
+                    String pressureUnit = qmResultUtil.pressureUnit != null && !qmResultUtil.pressureUnit.trim().isEmpty()
+                            ? qmResultUtil.pressureUnit.trim() : "kPa";
+                    String leakUnit = qmResultUtil.leakUnit != null ? qmResultUtil.leakUnit.trim() : "";
+                    if(useCur){
+                        log.info("提交采用实时RS值 pressure={}{}, leak={}{}", pressureValue, pressureUnit, leakValue, leakUnit);
+                    }
+                    MesClient.param1.setText(pressureValue + pressureUnit);
+                    MesClient.param2.setText(leakValue + leakUnit);
+                    String lastRet = "OK".equals(qmResultUtil.result) ? "OK" : "NG";
+                    if(lastRet.equals("OK")){
+                        MesClient.result.setText("OK");
+                        MesClient.result.setForeground(Color.GREEN);
+                    }else{
+                        MesClient.result.setText("NG");
+                        MesClient.result.setForeground(Color.RED);
+                    }
+                    TestParam testParam = new TestParam();
+                    testParam.setSn(sn);
+                    testParam.setParam1(pressureValue);
+                    testParam.setParam2(pressureUnit);
+                    testParam.setParam3(leakValue);
+                    testParam.setParam4(leakUnit);
+                    testParam.setResult(lastRet);
+                    if(lastRet.equals("NG")){
+                        testParam.setRemark(qmResultUtil.result);
+                    }else{
+                        testParam.setRemark("");
+                    }
+                    MesClient.fillMesTestMeta(testParam);
+                    MesClient.afterTestSaveAndUpload(testParam);
+
+                    break;
+                case "5253": // 实时结果
+                    // 未扫码时不处理实时流程,避免设备自行测试触发读结果并入库
+                    if(MesClient.work_status != 1){
+                        break;
+                    }
+                    QmCurUtil qmCurUtil = new QmCurUtil(msg);
+                    log.info("qmCurUtil:"+qmCurUtil.toString());
+                    // 仅中间步骤开启本轮;65535 等结束态不能开轮,否则扫新码会立刻读旧结果并提交
+                    if(qmCurUtil.isRunningStep()){
+                        if(MesClient.mesStartFlag == 0 || MesClient.mesTjFlag == 1){
+                            MesClient.mesStartFlag = 1;
+                            MesClient.mesTjFlag = 0;
+                            log.info("本轮测试已开始,step={}", qmCurUtil.step);
+                        }
+                    }
+                    MesClient.setMenuStatus("当前步骤:"+qmCurUtil.step, 0); // 当前步骤
+                    // 实时更新显示的压力值和泄漏值(与气密仪一致)
+                    MesClient.param1.setText(qmCurUtil.pressureValue);
+                    MesClient.param2.setText(qmCurUtil.leakValue);
+                    if(qmCurUtil.pressureValue != null && !qmCurUtil.pressureValue.trim().isEmpty()){
+                        MesClient.lastQmPressure = qmCurUtil.pressureValue.trim();
+                    }
+                    if(qmCurUtil.leakValue != null && !qmCurUtil.leakValue.trim().isEmpty()){
+                        MesClient.lastQmLeak = qmCurUtil.leakValue.trim();
+                    }
+
+                    // 读最终结果:必须本轮已由中间步开启(mesStartFlag=1)后,再遇到结束步才请求 4353
+                    if(MesClient.mesStartFlag == 1 && MesClient.mesTjFlag == 0){
+                        if(qmCurUtil.isEndStep()){
+                            log.info("读取测试结果,当前step={}, pressure={}, leak={}",
+                                    qmCurUtil.step, MesClient.lastQmPressure, MesClient.lastQmLeak);
+                            ctx.writeAndFlush(YtUtil.getSendByteBuf(YtUtil.getResultCommon()));
+                        }
+                    }
+
+                    break;
+                case "5453": // 设备状态
+
+                    break;
+                case "4F4B": // 指令执行成功
+
+                    break;
+                case "4552": // 非法操作或校验位错误
+
+                    break;
+            }
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+
+
+    }
+
+    @Override
+    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+        System.out.println("exceptionCaught");
+//        ctx.close();
+    }
+
+    /**
+     * 发送心跳包
+     *
+     * @param ctx
+     */
+    private void sendHeartbeatPacket(ChannelHandlerContext ctx) {
+        // 查询状态当做心跳
+        ctx.writeAndFlush(YtUtil.getSendByteBuf(YtUtil.getStateCommon()));
+    }
+
+}

+ 122 - 0
src/com/mes/util/ytnetty/YtUtil.java

@@ -0,0 +1,122 @@
+package com.mes.util.ytnetty;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class YtUtil {
+    public static final Logger log =  LoggerFactory.getLogger(YtUtil.class);
+
+    // 获取功能码
+    public static String getCode(String msg){
+        return msg.substring(0,4);
+    }
+
+    /**
+     * 计算16进制字符串的BCC校验码
+     * @param hexData 16进制字符串
+     * @return BCC校验码
+     */
+    public static byte calculateBCC(String hexData) {
+        byte bcc = 0; // 初始化BCC校验码为0
+        for (int i = 0; i < hexData.length(); i += 2) { // 每次处理两个字符(1个字节)
+            String byteStr = hexData.substring(i, i + 2); // 获取当前16进制字节
+            int byteValue = Integer.parseInt(byteStr, 16); // 将16进制字符串转换为整数
+            bcc ^= byteValue; // 执行异或操作
+        }
+        return bcc; // 返回计算后的BCC校验码
+    }
+
+    public static String formatCommon(String msg){
+        String start = "02";
+        String end = "03";
+        String content = start+msg+end;
+        String bcc = String.format("%02x",calculateBCC(content));
+        return content + bcc;
+    }
+
+    // 启动指令
+    public static String getStartCommon(){
+        return formatCommon("5354");
+    }
+
+    // 停止/复位指令
+    public static String getStopCommon(){
+        return formatCommon("5254");
+    }
+
+    // 锁机指令
+    public static String getLockCommon(){
+        return formatCommon("4C4D31");
+    }
+
+    // 解锁指令
+    public static String getUnLockCommon(){
+        return formatCommon("4C4D30");
+    }
+
+    // 选频指令
+    public static String getSelectProgramCommon(String programNo){
+        String no = String.format("%03d", Integer.parseInt(programNo));
+        return formatCommon("4348"+asciiToHex(no));
+    }
+
+    // 读取当前通道
+    public static String getCurProgramCommon(){
+        return formatCommon("5250");
+    }
+
+    // 读取实时
+    public static String getCurDataCommon(){
+        return formatCommon("5253");
+    }
+
+    // 设备状态
+    public static String getStateCommon(){
+        return formatCommon("5453");
+    }
+
+
+    // 传输结果
+    public static String getResultCommon(){
+        return formatCommon("4353");
+    }
+
+    public static String asciiToHex(String input){
+        StringBuilder hexValues = new StringBuilder();
+        for (char c : input.toCharArray()) {
+            int asciiValue = (int) c; // 获取ASCII值
+            String hexValue = Integer.toHexString(asciiValue); // 转换为16进制字符串
+            if (hexValues.length() > 0) { // 如果不是第一个字符,添加空格分隔
+                hexValues.append("");
+            }
+            hexValues.append(hexValue); // 添加到StringBuilder中
+        }
+        return hexValues.toString();
+    }
+
+    public static byte[] hexStringToByteArray(String s) {
+        int len = s.length();
+        byte[] data = new byte[len / 2];
+        for (int i = 0; i < len; i += 2) {
+            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+                    + Character.digit(s.charAt(i+1), 16));
+        }
+        return data;
+    }
+
+    /**
+     * 将字符串消息转为ByteBuf
+     * 16进制字符串转二进制
+     * @param hex 字符串消息
+     */
+    public static ByteBuf getSendByteBuf(String hex) {
+        byte[] bytes = new byte[hex.length() / 2];
+        for (int i = 0; i < hex.length(); i += 2) {
+            int value = Integer.parseInt(hex.substring(i, i + 2), 16);
+            bytes[i/2] = (byte)(value & 0xFF);
+        }
+        return Unpooled.wrappedBuffer(bytes);
+    }
+}

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

@@ -1,6 +1,6 @@
-mes.gw=OP260B
-mes.server_ip=127.0.0.1
-#mes.server_ip=192.168.17.99
+mes.gw=OP360B
+#mes.server_ip=127.0.0.1
+mes.server_ip=192.168.24.99
 mes.tcp_port=3000
 mes.heart_beat_cycle=60
 mes.line_sn=XT

+ 12 - 0
绀轰緥

@@ -0,0 +1,12 @@
+02435330303335363230323630373036313630313032303030202020202020202020202020202020202020202020202020202020202020303030312E35353331303030323031332E32383030032B
+2026-07-14 17:28:34 INFO   com.mes.util.ytnetty.YtDecoderServer - 接收信息:CS0035620260706160102000                              0001.55310002013.2800
+2026-07-14 17:28:34 INFO   com.mes.util.ytnetty.YtDecoderServer - 接收信息2:435330303335363230323630373036313630313032303030202020202020202020202020202020202020202020202020202020202020303030312E35353331303030323031332E32383030
+2026-07-14 17:28:34 INFO   c.m.u.ytnetty.YtNettyClientHandler - msg:435330303335363230323630373036313630313032303030202020202020202020202020202020202020202020202020202020202020303030312E35353331303030323031332E32383030
+
+
+qmCurUtil:QmCurUtil{step='0,', temperature='0,0.', pressureValue='-0.5', leakValue='8,0.'}
+2026-07-15 11:24:41 INFO   c.m.u.ytnetty.YtNettyClientHandler - message:435330303336313230323630373135313130383439303030202020202020202020202020202020202020202020202020202020202020303939392E39393337303030303135312E39313030
+2026-07-15 11:24:41 INFO   c.m.u.ytnetty.YtNettyClientHandler - code:4353
+2026-07-15 11:24:41 INFO   c.m.u.ytnetty.YtNettyClientHandler - msg:435330303336313230323630373135313130383439303030202020202020202020202020202020202020202020202020202020202020303939392E39393337303030303135312E39313030
+2026-07-15 11:24:41 INFO   c.m.u.ytnetty.YtNettyClientHandler - qmResultUtil:QmResultUtil{num='00361', testDate='20260715110849', sn='               ', resultType=' ', result=' ', programNumber='  ', pressureValue='    0999', leakValue='      ', pressureUnit='kpa', leakUnit=' '}
+CS0036120260715110849000                              0999.99370000151.9100