package com.mes.component; import com.alibaba.fastjson2.JSONObject; import com.github.xingshuangs.iot.protocol.s7.enums.EPlcType; import com.github.xingshuangs.iot.protocol.s7.service.S7PLC; import com.mes.ui.DataUtil; import com.mes.ui.MesClient; import com.mes.util.TCPClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.Timer; import java.util.TimerTask; public class WorkJPanelOP65 extends JPanel { public static final Logger log = LoggerFactory.getLogger(WorkJPanelOP65.class); public String oprno = "OP075"; // 原OP065打磨,产线改造后工位号OP075 public String pos = "A"; public String lastSn = ""; // 最近的码 public String lineSn = "XT"; public JLabel sllabel1; public JLabel sllabel2; public JButton scanBtn; public JTextField productSn; public JButton status_menu; public JButton resetBtn; public JButton finish_ok_bt; public JButton finish_ng_bt; public Integer workWidth = 940; public Integer workHeight = 400; public Boolean check_quality_result = false; public Integer work_status = 0; public String plcDb2 = "DB7010"; public JLabel turnmeslabel; public JLabel aFaceLabel; public JLabel bFaceLabel; public ImageIcon imageGreen; public ImageIcon imageGray; public boolean boolFlag; public Integer isLocal = 0; // 0=正式 1=本地 public int lastFaceState = -1; // PLC 地址配置 public S7PLC s7PLC = null; public String plcIp1 = "192.168.90.85"; // plc5 西侧 public String plcIp2 = "192.168.90.86"; // plc6 东侧 public String addrFaceA = plcDb2 + ".6.0"; // B 面到位信号 public String addrFaceB = plcDb2 + ".6.1"; // A 面到位信号 public String addrFeedback = plcDb2 + ".6.2"; // 转动反馈信号 //55扫码完成反馈 public String addrScanFinish = plcDb2 + ".7.0"; //55定位台状态 public String addrPush = plcDb2 + ".7.1"; private JLabel scanFinish55Label; // 55扫码信号显示与操作 private JLabel push55Label; // 55到位信号显示 private String orientation = "1"; // 逻辑记录变量 private int lastPush55State = -1; // 记录上一次55到位状态 public JButton signalBtn; // 信号监控按钮 public PlcSignalMonitor03 signalMonitor; // 信号监控组件 public WorkJPanelOP65(String position){ this.setLayout(null); this.setBackground(Color.WHITE); this.pos = position; if(MesClient.mes_line_pos.equals("east")){ // 东侧 s7PLC = new S7PLC(EPlcType.S1500, plcIp2); orientation = "1"; //东 }else{ s7PLC = new S7PLC(EPlcType.S1500, plcIp1); orientation = "2"; //西 } JLabel oprnoLabel = new JLabel(oprno+pos); oprnoLabel.setHorizontalAlignment(SwingConstants.CENTER); oprnoLabel.setForeground(Color.BLACK); oprnoLabel.setFont(new Font("微软雅黑", Font.PLAIN, 30)); oprnoLabel.setBounds(0, 0, workWidth, 60); this.add(oprnoLabel); imageGreen = new ImageIcon(MesClient.class.getResource("/bg/green_dot.png")); imageGreen.setImage(imageGreen.getImage().getScaledInstance(20, 20, Image.SCALE_SMOOTH)); imageGray = new ImageIcon(MesClient.class.getResource("/bg/grey_dot.png")); imageGray.setImage(imageGray.getImage().getScaledInstance(20, 20, Image.SCALE_SMOOTH)); turnmeslabel = new JLabel("MES转动反馈"); turnmeslabel.setHorizontalAlignment(SwingConstants.LEFT); turnmeslabel.setIcon(imageGreen); turnmeslabel.setForeground(Color.BLACK); turnmeslabel.setBounds(270, 200, workWidth/3, 30); turnmeslabel.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { boolean ret = readBoolean(addrFeedback); int choice = JOptionPane.showConfirmDialog(null, "确定修改MES完成反馈结果为"+(ret?"false":"true")+"吗?", "操作确认", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); if (choice == JOptionPane.YES_OPTION) { writeBoolean(addrFeedback,!ret); log.info("修改MES扫码反馈结果为"+(ret?"false":"true")); } } }); this.add(turnmeslabel); aFaceLabel = new JLabel("当前A面"); aFaceLabel.setHorizontalAlignment(SwingConstants.LEFT); aFaceLabel.setIcon(imageGreen); aFaceLabel.setForeground(Color.BLACK); aFaceLabel.setBounds(400, 200, workWidth/3, 30); this.add(aFaceLabel); bFaceLabel = new JLabel("当前B面"); bFaceLabel.setHorizontalAlignment(SwingConstants.LEFT); bFaceLabel.setIcon(imageGreen); bFaceLabel.setForeground(Color.BLACK); bFaceLabel.setBounds(500, 200, workWidth/3, 30); this.add(bFaceLabel); push55Label = new JLabel("55定位台状态"); push55Label.setHorizontalAlignment(SwingConstants.LEFT); push55Label.setIcon(imageGray); // 初始为灰色 push55Label.setForeground(Color.BLACK); push55Label.setBounds(270, 240, workWidth/3, 30); // 放在转动反馈下方一行 this.add(push55Label); scanFinish55Label = new JLabel("55扫码反馈"); scanFinish55Label.setHorizontalAlignment(SwingConstants.LEFT); scanFinish55Label.setIcon(imageGray); scanFinish55Label.setForeground(Color.BLACK); scanFinish55Label.setBounds(400, 240, workWidth/3, 30); scanFinish55Label.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { // 读取当前55扫码状态 boolean ret = readBoolean(addrScanFinish); int choice = JOptionPane.showConfirmDialog(null, "确定修改55扫码完成反馈结果为 " + (ret ? "false" : "true") + " 吗?", "操作确认", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); if (choice == JOptionPane.YES_OPTION) { writeBoolean(addrScanFinish, !ret); log.info("手动修改55扫码反馈结果为: " + !ret); } } }); this.add(scanFinish55Label); status_menu = new JButton("请扫工件码"); status_menu.setBounds(0, 60, workWidth, 60); status_menu.setForeground(Color.GREEN); status_menu.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { } }); status_menu.setForeground(Color.GREEN); status_menu.setFont(new Font("微软雅黑", Font.PLAIN, 20)); status_menu.setBackground(Color.BLACK); this.add(status_menu); productSn = new JTextField(""); productSn.setHorizontalAlignment(SwingConstants.CENTER); productSn.setForeground(Color.BLACK); productSn.setFont(new Font("微软雅黑", Font.PLAIN, 20)); productSn.setEditable(true); productSn.setBounds(0, 130, this.workWidth-200, 60); productSn.addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ENTER) { // 处理Enter键被按下的逻辑 String sn = productSn.getText().trim(); if(!sn.isEmpty()){ // MesClient.createQRCode(productSn.getText(),oprno); productSn.setEnabled(false); // 查询工件质量 JSONObject retObj = DataUtil.checkQuality(sn,oprno+pos,MesClient.user_menu.getText()); if(retObj.get("result")!=null&&retObj.get("result").toString().equalsIgnoreCase("true")) { check_quality_result = true;//质量合格,可以绑定加工 work_status = 1; setMenuStatus("工件可以加工", 0); finish_ok_bt.setEnabled(true); finish_ng_bt.setEnabled(true); }else{ check_quality_result = false; work_status = 0; if(retObj.get("result")==null){ setMenuStatus("请求失败,请重试",-1); }else{ if(retObj.get("result").toString().equalsIgnoreCase("false")){ setMenuStatus(retObj.getString("message"),-1); } } } } } } }); // productSn.addMouseListener(new MouseAdapter() { // public void mouseClicked(MouseEvent e) { // // } // }); this.add(productSn); finish_ok_bt = new JButton("OK"); finish_ok_bt.setEnabled(false); finish_ok_bt.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String sn = productSn.getText().trim(); if(sn.isEmpty()){ return; } JSONObject retObj = DataUtil.sendQuality(sn,oprno+pos,"OK",MesClient.user_menu.getText()); if(retObj.get("result")!=null&&retObj.get("result").toString().equalsIgnoreCase("true")) { resetScanA(); setMenuStatus("结果提交成功,请扫下一件",0); writeBoolean(addrFeedback,true); //完成反馈 }else{ if(retObj.get("result")==null){ setMenuStatus("请求失败,请重试",-1); }else{ if(retObj.get("result").toString().equalsIgnoreCase("false")){ setMenuStatus(retObj.getString("message"),-1); } } } } }); finish_ok_bt.setIcon(new ImageIcon(MesClient.class.getResource("/bg/ok_bg.png"))); finish_ok_bt.setFont(new Font("微软雅黑", Font.PLAIN, 32)); finish_ok_bt.setBounds(185, 291, 240, 80); finish_ok_bt.setEnabled(false); this.add(finish_ok_bt); finish_ng_bt = new JButton("NG"); finish_ng_bt.setEnabled(false); finish_ng_bt.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String sn = productSn.getText().trim(); if(sn.isEmpty()){ return; } JSONObject retObj = DataUtil.sendQuality(sn,oprno+pos,"NG",MesClient.user_menu.getText()); if(retObj.get("result")!=null&&retObj.get("result").toString().equalsIgnoreCase("true")) { resetScanA(); setMenuStatus("结果提交成功,请扫下一件",0); writeBoolean(addrFeedback,true); //完成反馈 }else{ if(retObj.get("result")==null){ setMenuStatus("请求失败,请重试",-1); }else{ if(retObj.get("result").toString().equalsIgnoreCase("false")){ setMenuStatus(retObj.getString("message"),-1); } } } } }); finish_ng_bt.setIcon(new ImageIcon(MesClient.class.getResource("/bg/ng_bg.png"))); finish_ng_bt.setFont(new Font("微软雅黑", Font.PLAIN, 32)); finish_ng_bt.setBounds(508, 291, 240, 80); finish_ng_bt.setEnabled(false); this.add(finish_ng_bt); resetBtn = new JButton("刷新"); resetBtn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { resetScanA(); } }); resetBtn.setIcon(new ImageIcon(MesClient.class.getResource("/bg/reset_logo.png"))); resetBtn.setFont(new Font("微软雅黑", Font.PLAIN, 32)); resetBtn.setBounds(this.workWidth-190, 130, 190, 60); this.add(resetBtn); textFocus(); if (isLocal == 0) { writeBoolean(addrFeedback, false); writeBoolean(addrScanFinish, false); log.info("程序启动:55扫码信号已初始化为 false"); log.info("程序启动:65扫码完成信号已初始化为 false"); } startTurntableMonitor(); start55MonitorTimer(); // 信号监控按钮 signalMonitor = new PlcSignalMonitor03(s7PLC, plcDb2, oprno + pos, MesClient.mesClientFrame); signalBtn = signalMonitor.createSignalButton(); signalBtn.setBounds(workWidth*2/3 + 63, 230, 90, 26); this.add(signalBtn); } public void setMenuStatus(String msg,int error){ if(error == 0){ this.status_menu.setForeground(Color.GREEN); }else{ this.status_menu.setForeground(Color.RED); } this.status_menu.setText(msg); } public Timer cjTimerText; public void textFocus() { if(cjTimerText!=null) { cjTimerText.cancel(); } cjTimerText = new Timer(); cjTimerText.schedule(new TimerTask() { public void run() { productSn.requestFocusInWindow(); } }, 1000,1000); } public void resetScanA() { check_quality_result = false; work_status = 0; productSn.setText(""); productSn.setEnabled(true); setMenuStatus("请扫工件码",0); finish_ok_bt.setEnabled(true); finish_ng_bt.setEnabled(true); } private Timer turntableTimer; public void startTurntableMonitor() { if (turntableTimer != null) { turntableTimer.cancel(); } turntableTimer = new Timer(); turntableTimer.schedule(new TimerTask() { @Override public void run() { try { if (MesClient.isLogin == 1) { // 1. 读取 A、B 面信号 boolean isA = readBoolean(addrFaceA); boolean isB = readBoolean(addrFaceB); boolean isBack = readBoolean(addrFeedback); //改变状态灯 aFaceLabel.setIcon(!isA ? imageGreen : imageGray); bFaceLabel.setIcon(!isB ? imageGreen : imageGray); turnmeslabel.setIcon(isBack ? imageGreen : imageGray); int currentFace = -1; if (isA && !isB) { currentFace = 0; // 当前在 A 面 } else if (isB && !isA) { currentFace = 1; // 当前在 B 面 }else { //既不在A,也不在B面 currentFace = 2; } // 2. 捕捉切换瞬间 // 如果当前面有效,且与上次记录不同,且不是刚启动后的第一次识别 if (currentFace != -1 && lastFaceState != -1 && currentFace != lastFaceState) { log.info("检测到面切换,自动重置反馈信号"); writeBoolean(addrFeedback, false); // 切换时重置 } // 3. 更新记录状态 if (currentFace != -1) { lastFaceState = currentFace; } } } catch (Exception e) { log.error("监控异常: " + e.getMessage()); } } }, 1000, 1500); // 1秒后启动,每1.5秒扫描一次 } private Timer monitor55Timer; public void start55MonitorTimer() { if (monitor55Timer != null) { monitor55Timer.cancel(); } monitor55Timer = new Timer(); monitor55Timer.schedule(new TimerTask() { @Override public void run() { try { if (MesClient.isLogin == 1) { JSONObject signalMessage = DataUtil.getSignal(orientation); //如果已扫码,就将扫码信号写为true String data = signalMessage.getString("data"); //为1则已扫码 if(data.equals("1")){ writeBoolean(addrScanFinish, true); } // 1. 读取 55 工位相关信号 boolean isPush = readBoolean(addrPush); boolean isScanFinish = readBoolean(addrScanFinish); // 2. 更新 UI 状态灯图标 push55Label.setIcon(isPush ? imageGreen : imageGray); scanFinish55Label.setIcon(isScanFinish ? imageGreen : imageGray); // 3. 核心联动逻辑:55定位台信号发生改变时重置扫码信号 int currentPush = isPush ? 1 : 0; if (lastPush55State != -1 && currentPush != lastPush55State) { log.info("检测到55到位信号切换 ({} -> {}),执行55扫码信号自动重置", lastPush55State, currentPush); // 执行重置 writeBoolean(addrScanFinish, false); DataUtil.sendChangeByorientation(orientation); } // 4. 更新上次状态记录 lastPush55State = currentPush; } } catch (Exception e) { log.error("55工位信号监控异常: " + e.getMessage()); } } }, 1000, 1500); // 2秒后启动,每1.5秒执行一次 } //旋转反馈 public boolean writeBoolean(String db, boolean permit){ try { s7PLC.writeBoolean(db,permit); // log.info("<"+this.oprno+this.pos+">写入"+db+"-->成功,写入内容:{}", permit ? "true" : "false"); } catch (Exception e) { log.error("<"+this.oprno+this.pos+">写入"+db+"-->失败,写入内容:{}", permit ? "true" : "false"); log.error(e.getMessage(), e); return false; } return true; } public boolean readBoolean(String db){ boolean permit; try { permit = s7PLC.readBoolean(db); // log.info("<"+this.oprno+this.pos+">读取"+db+"-->成功,结果:{}", permit ? "true" : "false"); } catch (Exception e) { log.error("<"+this.oprno+this.pos+">读取"+db+"-->失败", e); return false; } return permit; } }