package com.mes.component; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.github.s7connector.api.DaveArea; import com.github.s7connector.api.S7Connector; import com.github.s7connector.api.S7Serializer; import com.github.s7connector.api.factory.S7ConnectorFactory; import com.github.s7connector.api.factory.S7SerializerFactory; import com.github.xingshuangs.iot.protocol.common.buff.EByteBuffFormat; import com.github.xingshuangs.iot.protocol.modbus.service.ModbusTcp; 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.ui.OprnoUtil; import com.mes.util.DateLocalUtils; import com.mes.util.JdbcUtils; import com.mes.util.S7Util; //import com.mes.util.S7Utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.ArrayList; import java.util.List; import java.util.Timer; import java.util.TimerTask; public class WorkJPanelDevice extends JPanel { public final Logger log = LoggerFactory.getLogger(WorkJPanelDevice.class); public String oprno = "OP170"; public String pos = "A"; public String lastSn = ""; // 最近的码 public String lineSn = "XT"; public JLabel feedinglabel; public JLabel feedingmeslabel; public JLabel runlabel; //运行反馈, public JLabel blankinglabel; // 下料反馈 public JLabel blankingmeslabel; // 下料MES反馈 public JButton scanBtn; public JTextField productSn; public JTextField productSnFeeding; public JButton status_menu; public JButton resetBtn; public JButton checkBtn; public JButton historyBtn; public JButton toolBtn; public JButton resetFeedingBtn; public ImageIcon imageGreen; public ImageIcon imageGray; public String plcIp = "10.85.10.4"; public String deviceIp = "10.85.10.4"; public S7Connector s7Connector; public S7PLC s7PLC = null; public ModbusTcp modbusTcp; public S7PLC s7PLCFSW = null; public Integer workWidth = 470; public Integer workHeight = 300; public String plcDb = ""; public String preSn = ""; // 扫码内容 public Integer tjFeedingFlag = 0; // 上料状态标识 public Integer tjFlag = 0; // 1=可加工 2=设备运行中 3=加工结束 public Integer tjStatus = 0; // 提交标识 public Boolean plcHeart = false; public Integer isLocal = 0; // 0=正式 1=本地 public Integer isScan = 1; // 1=西侧 2=东测 public Boolean fswOnline = true; // public String finallySn = ""; public List hjparams = new ArrayList<>(); public Integer errflag = 0; // 1=报警 0=正常 public Integer errflag2 = 0; public String fswDeviceName = ""; public JLabel oprnoLabel2; public JLabel oprnoLabel; // OP110 // public int[] toolNums = { 1,2,3,4,5}; // public String[] toolTitle = { "高速端铣刀", "合金铣刀", "合金台阶钻", "合金台阶钻", "合金钻头" }; // public String[] toolLife = { "", "", "", "", "" }; // // OP170 // public int[] toolNums = { 1,2,3,4,5}; // public String[] toolTitle = { "合金铣刀", "插孔铣刀", "合金台阶钻", "铝用合金钻头", "切削丝锥" }; // public String[] toolLife = { "", "", "", "", "" }; // OP180 public int[] toolNums = new int[10]; public String[] toolTitle = new String[10]; public String[] toolLife = new String[10]; public int toolNm = 6; // 缓存上一次的信号值,用于检测变化(key=地址, value=上次值) private java.util.Map lastBooleanValues = new java.util.HashMap<>(); private java.util.Map lastWriteBooleanValues = new java.util.HashMap<>(); public WorkJPanelDevice(String position){ this.setLayout(null); this.setBackground(Color.WHITE); this.pos = position; this.oprno = DataUtil.formatOprno(MesClient.mes_gw); // 对于 OP140 和 OP150,增大窗口尺寸以占满主界面 int yScale = 1; log.info("deviceIp:"+deviceIp); fswDeviceName = OprnoUtil.getGwDes(lineSn, oprno); if(oprno.equals("OP110")){ // 框架反面CNC plcIp = "10.85.10.6"; if(position.equals("A")){ plcDb = "DB4003"; deviceIp = "10.85.10.80"; }else if(position.equals("B")){ plcDb = "DB4004"; deviceIp = "10.85.10.81"; } else if (position.equals("C")) { plcDb = "DB4005"; deviceIp = "10.85.10.82"; } }else if(oprno.equals("OP140")){ plcIp = "10.85.10.2"; if(position.equals("A")){ plcDb = "DB4008"; deviceIp = ""; } }else if(oprno.equals("OP150")){ plcIp = "10.85.10.2"; if(position.equals("A")){ plcDb = "DB4009"; deviceIp = "10.85.10.160"; }else if(position.equals("B")){ plcDb = "DB4010"; deviceIp = "10.85.10.161"; } }else if(oprno.equals("OP170")){ plcIp = "10.85.10.3"; if(position.equals("A")){ plcDb = "DB4012"; deviceIp = "10.85.10.83"; }else if(position.equals("B")){ plcDb = "DB4013"; deviceIp = "10.85.10.84"; }else if (position.equals("C")) { plcDb = "DB4014"; deviceIp = "10.85.10.85"; }else if (position.equals("D")) { plcDb = "DB4015"; deviceIp = "10.85.10.86"; } }else if(oprno.equals("OP180")){ plcIp = "10.85.10.4"; if(position.equals("A")){ plcDb = "DB4017"; deviceIp = "10.85.10.86"; }else if(position.equals("B")){ plcDb = "DB4018"; deviceIp = "10.85.10.87"; } else if (position.equals("C")) { plcDb = "DB4019"; deviceIp = "10.85.10.88"; } } s7PLC = new S7PLC(EPlcType.S1500, plcIp); s7PLC.setConnectTimeout(800); s7PLC.setReceiveTimeout(800); if(oprno.equals("OP110")||oprno.equals("OP170")||oprno.equals("OP180")){ modbusTcp = new ModbusTcp(1, deviceIp); modbusTcp.setConnectTimeout(500); modbusTcp.setReceiveTimeout(500); if(oprno.equals("OP170")){ toolNm = 9; }else if(oprno.equals("OP180")){ toolNm = 5; } for(int i=0; iPLC心跳 public void sendHeart(String db,S7PLC s7PLC){ try{ Boolean ret = s7PLC.readBoolean(db+".60.0"); s7PLC.writeBoolean(db+".60.0",!ret); }catch (Exception e){ e.printStackTrace(); } } private void ReplyPlc(String db,S7PLC s7PLC){ Boolean ret = s7PLC.readBoolean(db+".12.0"); if(ret){ // 允许MES读工件码 if(!db.equals("DB3010")){ String sn = s7PLC.readString(db+".24.0",33).trim(); if(!sn.isEmpty()){ // TODO::判断是否可上件 s7PLC.writeBoolean(db+".0.0",true); } }else{ s7PLC.writeBoolean(db+".0.0",true); } }else{ // 允许上料置位 s7PLC.writeBoolean(db+".0.0",false); } } public Timer cjTimerText3; public void monitorDeviceStatus() { if(cjTimerText3!=null) { cjTimerText3.cancel(); } cjTimerText3 = new Timer(); cjTimerText3.schedule(new TimerTask() { public void run() { if(MesClient.isLogin == 1 && isLocal == 0){ try{ initS7(); monitorDevice(); boolean ret = S7Util.getFswAlarm(s7Connector); if(ret){ errflag = 0; } if(!ret && errflag == 0 ){ errflag = 1; DataUtil.deviceAlarm(oprno+pos,productSn.getText(),oprno+pos+"随动夹具报警",MesClient.user_menu.getText()); } fswOnline = true; }catch (Exception e){ log.info(e.getMessage()); fswOnline = false; } if(fswOnline){ oprnoLabel.setForeground(Color.BLACK); oprnoLabel2.setForeground(Color.BLACK); }else{ oprnoLabel.setForeground(Color.RED); oprnoLabel2.setForeground(Color.RED); } try{ // int ret = getAlarm(); // if(ret == 0){ // errflag2 = 0; // } // if(ret != 0 && errflag2 == 0 ){ // String content = oprno+pos; // if(ret == 1){ // content += "安全门故障"; // }else if(ret == 2){ // content += "急停故障"; // }else if(ret == 3){ // content += "光栅故障"; // }else if(ret == 4){ // content += "夹紧故障"; // } // // errflag2 = 1; // DataUtil.deviceAlarm(oprno+pos,productSn.getText(),content,MesClient.user_menu.getText()); // } }catch (Exception e){ } } } }, 1000,1000); } public Timer oprnoTimer; public void startOprnoTimer() { //心跳显示图标 if(oprnoTimer!=null) { oprnoTimer.cancel(); } oprnoTimer = new Timer(); oprnoTimer.schedule(new TimerTask() { public void run() { try{ if(MesClient.isLogin == 1){ //请求扫码 Boolean retFeeding = readFeeding(); feedinglabel.setIcon(retFeeding?imageGreen:imageGray); // 读取MES允许上料信号 Boolean retFeedingAllow = readAllowFeeding(); feedingmeslabel.setIcon(retFeedingAllow?imageGreen:imageGray); if(!retFeeding && retFeedingAllow){ writeAllowFeeding(false); } // 读取下料信号 Boolean retBlanking = readBlanking(); blankinglabel.setIcon(retBlanking?imageGreen:imageGray); // 读取MES允许下料信号 Boolean retAllowBlanking = readAllowBlanking(); blankingmeslabel.setIcon(retAllowBlanking?imageGreen:imageGray); // 当检测到允许MES读码信号为 true,且当前MES下料反馈还为 true 时,将其复位为 false if (retFeeding && retAllowBlanking) { writeAllowBlanking(false); // 同步更新UI图标反馈为灰色 blankingmeslabel.setIcon(imageGray); } // 读取设备运行信号 Boolean retRunning = readRunning(); runlabel.setIcon(retRunning?imageGreen:imageGray); //上料 if(tjFeedingFlag == 0){ if(retRunning){ resetFeeding(); } if(retBlanking && !retAllowBlanking){ writeAllowBlanking(true); resetBlanking(); } if(retFeeding){ barCode(); } }else if(tjFeedingFlag == 1){ if(retRunning || retBlanking){ // 运行和下料双判断 tjFeedingFlag = 2; resetFeeding(); setMenuStatus("工件加工中", 0); getToolLife(); }else{ if(!retFeedingAllow){ writeAllowFeeding(true); } } }else if(tjFeedingFlag == 2){ if(retBlanking || retFeeding){ // 运行结束(下料或者再次上料) tjFeedingFlag = 0; setMenuStatus("工件加工结束,结果上传中", 0); writeAllowBlanking(true); if(tjStatus == 0){ tjStatus = 1; // String result = readResult(); String result = "OK"; result = result.equals("OK")?"OK":"NG"; // if(oprno.equals("OP110")||oprno.equals("OP170")||oprno.equals("OP180")){ // result = "OK"; // } JSONObject retObj = DataUtil.sendQuality(productSnFeeding.getText(),oprno+pos,result,MesClient.user_menu.getText()); if(retObj.get("result")!=null&&retObj.get("result").toString().equalsIgnoreCase("true")) { resetBlanking(); }else{ if(retObj.get("result")==null){ setMenuStatus("请求失败,请重试",-1); }else{ if(retObj.get("result").toString().equalsIgnoreCase("false")){ setMenuStatus(retObj.getString("message"),-1); } } } }else{ } } } } }catch (Exception e) { log.error(e.getMessage()); } } }, 100,1500); } public void barCode(){ //如果为空则不进行上料 if(!productSnFeeding.getText().isEmpty()){ return; } String sn = readQrcode(); if(sn.equals("")){ if(productSnFeeding.getText().isEmpty()){ productSnFeeding.setText(""); this.setMenuStatus("扫码结果为空", -1); } }else{ productSnFeeding.setText(sn); lastSn = sn; // 查询工件质量 JSONObject retObj = DataUtil.checkQuality(sn,oprno+pos,MesClient.user_menu.getText()); if(retObj.get("result")!=null&&retObj.get("result").toString().equalsIgnoreCase("true")) { tjFeedingFlag = 1;//可加工 setMenuStatus("工件可以加工", 0); writeAllowFeeding(true); //允许上料 }else{ writeAllowFeeding(false); resetFeedingBtn.setEnabled(true); if(retObj.get("result")==null){ setMenuStatus("请求失败,请重试",-1); }else{ if(retObj.get("result").toString().equalsIgnoreCase("false")){ setMenuStatus(retObj.getString("message"),-1); } } } } } public void resetBlanking() { tjFeedingFlag = 0; tjStatus = 0; productSnFeeding.setText(""); setMenuStatus("工件结果已提交,等待下一件",0); // resetBtn.setEnabled(true); } public void resetFeeding() { // productSnFeeding.setText(""); // tjFeedingFlag = 0; // setMenuStatus("等待请求扫码",0); resetFeedingBtn.setEnabled(true); writeAllowFeeding(false); } public void resetScanA() { tjFeedingFlag = 0; tjFlag = 0; tjStatus = 0; // productSn.setText(""); productSnFeeding.setText(""); setMenuStatus("等待请求扫码",0); // resetBtn.setEnabled(true); resetFeedingBtn.setEnabled(true); if(isLocal == 0){ writeAllowFeeding(false); writeAllowBlanking(false); } } // 与设备交互----------------------------------------------------------------------------------------- // 请求扫码 public boolean readFeeding(){ if(isLocal == 1){ return false; }else{ return readBoolean(plcDb+".12.0"); } } // 读取下料信号 public boolean readBlanking(){ if(isLocal == 1){ return false; }else{ return readBoolean(plcDb+".12.2"); } } // 读取设备运行信号 public boolean readRunning(){ if(isLocal == 1){ return true; }else{ return readBoolean(plcDb+".12.1"); } } // 读取设备通讯状态 public boolean readDeviceStatus(){ if(isLocal == 1){ return true; }else{ return readBoolean(plcDb+".12.5"); } } // 读取MES允许上料信号 public boolean readAllowFeeding(){ if(isLocal == 1){ return false; }else{ return readBoolean(plcDb+".0.0"); } } // 写入MES允许上料信号 public boolean writeAllowFeeding(Boolean b){ if(isLocal == 1){ return true; }else{ return writeBoolean(plcDb+".0.0",b); } } // 读取MES允许下料信号 public boolean readAllowBlanking(){ if(isLocal == 1){ return true; }else{ return readBoolean(plcDb+".0.1"); } } // 写入MES允许下料信号 public boolean writeAllowBlanking(Boolean b){ if(isLocal == 1){ return true; }else{ return writeBoolean(plcDb+".0.1",b); } } // 读取二维码 public String readQrcode(){ if(isLocal == 1){ return ""; }else{ String sn = s7PLC.readString(plcDb+".24.0", 33).trim(); return sn; } } public boolean readBoolean(String db){ boolean permit; try { permit = s7PLC.readBoolean(db); // 值变化时才打印日志(排除心跳地址.0.4和.0.6) Boolean lastValue = lastBooleanValues.get(db); if (lastValue == null || lastValue != permit) { if (!db.endsWith(".0.4") && !db.endsWith(".0.6")) { log.info("<"+this.oprno+this.pos+">读取"+db+"-->变化:{} -> {}", lastValue, permit); } lastBooleanValues.put(db, permit); } } catch (Exception e) { log.error("<"+this.oprno+this.pos+">读取"+db+"-->失败", e); return false; } return permit; } public boolean writeBoolean(String db, boolean permit){ try { // 值变化时才写入和打印日志(排除心跳地址.0.4和.0.6) Boolean lastValue = lastWriteBooleanValues.get(db); if (lastValue == null || lastValue != permit) { s7PLC.writeBoolean(db,permit); if (!db.endsWith(".0.4") && !db.endsWith(".0.6")) { log.info("<"+this.oprno+this.pos+">写入"+db+"-->变化:{} -> {}", lastValue, permit); } lastWriteBooleanValues.put(db, permit); } } catch (Exception e) { log.error("<"+this.oprno+this.pos+">写入"+db+"-->失败,写入内容:{}", permit ? "true" : "false"); log.error(e.getMessage(), e); return false; } return true; } public void getToolLife(){ try{ int i=0; List ps = new ArrayList<>(); for(Integer toolNum : toolNums){ if(i < toolNm){ String life = String.valueOf(getLife(modbusTcp,toolNum)); toolLife[i] = life; ps.add(toolNum+"_"+life); i++; } } if(!toolLife[i].isEmpty()){ DataUtil.saveLife(lineSn,oprno,productSnFeeding.getText(),MesClient.user_menu.getText(),String.join("\\|",ps)); } }catch (Exception e){ e.printStackTrace(); } } // public Integer getLife(ModbusTcp modbusTcp,Integer i){ try{ if(isLocal == 1){ return 0; }else{ // short max1 = modbusTcp.readInt16((2103+(i*10))*2+3); // short cur1 = modbusTcp.readInt16((2103+(i*10))*2+1); // return max1 - cur1; Integer st = 500; // 宏变量对应R变量 901 - 551 @551=>R151 @901=>R501 Integer max1 = modbusTcp.readInt32((st + i)*2, EByteBuffFormat.DC_BA); return max1; } }catch (Exception e){ e.printStackTrace(); return 0; } } public void initS7(){ try { if(s7Connector == null) { //PLC地址 String ipAddress = deviceIp; log.info("deviceIp2:"+deviceIp); //默认端口 int port = 102; int rack=0; int slot=3; int timeout=5000; s7Connector= S7ConnectorFactory .buildTCPConnector() .withHost(ipAddress) .withPort(port) //optional // .withRack(rack) //optional // .withSlot(slot) //optional .withTimeout(timeout) //连接超时时间 .build(); S7Serializer s7Serializer2L = S7SerializerFactory.buildSerializer(s7Connector); } } catch (Exception e) { // 如果连接失败保存失败再次尝试连接一次 s7Connector = null; e.printStackTrace(); } } public Timer cjTimerText33; public void monitorDevice(){ if(cjTimerText33!=null) { cjTimerText33.cancel(); } cjTimerText33 = new Timer(); cjTimerText33.schedule(new TimerTask() { public void run() { log.info("monitorDevice"); if(oprno.equals("OP150")){ if(tjFeedingFlag == 2 && !productSnFeeding.getText().isEmpty()){ try{ String zzzs = String.valueOf(s7PLCFSW.readSpindleRate()); String jgsd = String.valueOf(s7PLCFSW.readFeedRate()); String record_time = DateLocalUtils.getCurrentTime(); hjparams.add(zzzs+"|"+jgsd+"|"+record_time); if (hjparams.size() == 60 && productSn.getText() != null && !productSnFeeding.getText().trim().isEmpty() ) { JdbcUtils.insertParamData(oprno+pos,MesClient.mes_line_sn,productSn.getText(), JSON.toJSONString(hjparams)); hjparams = new ArrayList<>(); } }catch (Exception e){ e.printStackTrace(); } log.info("monitorDevice:"+JSON.toJSONString(hjparams)); }else{ if(hjparams.size() > 0){ JdbcUtils.insertParamData(oprno+pos,MesClient.mes_line_sn,lastSn, JSON.toJSONString(hjparams)); hjparams = new ArrayList<>(); } } } } }, 1000,1000); } public void monitorDeviceOld(){ log.info("monitorDevice"); if(tjFlag == 2){ try{ String zzzs = String.valueOf(s7PLCFSW.readSpindleRate()); String jgsd = String.valueOf(s7PLCFSW.readFeedRate()); // String zzzs = S7Util.formatS7Val(s7Connector.read(DaveArea.DB, 9051, 4, 0)); // String jgsd = S7Util.formatS7Val(s7Connector.read(DaveArea.DB, 9051, 4, 4)); String zzzb = S7Util.formatS7Val(s7Connector.read(DaveArea.DB, 9051, 4, 8)); String ylz = S7Util.formatS7Val(s7Connector.read(DaveArea.DB, 9051, 4, 12)); Integer hjjs = S7Util.formatS7Int(s7Connector.read(DaveArea.DB, 9051, 2, 26)); String hjcd = S7Util.formatS7Val(s7Connector.read(DaveArea.DB, 9051, 4, 28)); String hjms = S7Util.formatS7Val(s7Connector.read(DaveArea.DB, 9051, 4, 32)); String record_time = DateLocalUtils.getCurrentTime(); hjparams.add(zzzs+"|"+jgsd+"|"+zzzb+"|"+ylz+"|"+hjjs+"|"+hjcd+"|"+hjms+"|"+record_time); if (hjparams.size() == 60 && productSn.getText() != null && !productSn.getText().trim().isEmpty() ) { JdbcUtils.insertParamData(oprno+pos,MesClient.mes_line_sn,productSn.getText(), JSON.toJSONString(hjparams)); hjparams = new ArrayList<>(); } }catch (Exception e){ e.printStackTrace(); s7Connector = null; } log.info("monitorDevice:"+JSON.toJSONString(hjparams)); }else{ if(hjparams.size() > 0){ JdbcUtils.insertParamData(oprno,MesClient.mes_line_sn,lastSn, JSON.toJSONString(hjparams)); hjparams = new ArrayList<>(); } } } public String readResult(){ String result = "OK"; boolean resultOk = false; boolean resultNg = false; try { resultOk = s7PLC.readBoolean(plcDb+".12.3"); log.info("<4>读取信号-->读取工位加工结果是否OK成功,结果:{}", resultOk ? "true" : "false"); resultNg = s7PLC.readBoolean(plcDb+".12.4"); log.info("<4>读取信号-->读取工位加工结果是否NG成功,结果:{}", resultNg ? "true" : "false"); if(resultOk){ return "OK"; } if(resultNg){ return "NG"; } } catch (Exception e) { return result; } return result; } }