package com.mes.ui; import com.github.xingshuangs.iot.protocol.modbus.service.ModbusTcp; import com.mes.util.JdbcUtils; import java.nio.charset.Charset; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; public class ModbusUtil { public static final int PLC_TIMEOUT_MS = 5000; private static final Map failUntil = new ConcurrentHashMap(); public static void applyTimeout(ModbusTcp plc) { if (plc == null) { return; } plc.setConnectTimeout(PLC_TIMEOUT_MS); plc.setReceiveTimeout(PLC_TIMEOUT_MS); } private static boolean isUnavailable(ModbusTcp plc) { if (plc == null) { return true; } Long until = failUntil.get(plc); return until != null && System.currentTimeMillis() < until; } private static void markOk(ModbusTcp plc) { failUntil.remove(plc); } private static void markFail(ModbusTcp plc) { failUntil.put(plc, System.currentTimeMillis() + PLC_TIMEOUT_MS); try { plc.close(); } catch (Exception ignore) { } } public static void getDataA(ModbusTcp plc){ if (isUnavailable(plc)) { return; } try { // 说明预设数量有变化不能修改 // 打钉数应按实际监听数算 // 41065=F-out 41066=S-out // 41069=F-min 41071=S-min 41070=F-max 41072=S-max // 预设数量=41129 完成数=41137 Short cur = plc.readInt16(1136); if(MesClient.aMax <= 0){ MesClient.aMax = plc.readInt16(1128); // 任务数量 MesClient.param1.setText(String.valueOf(MesClient.aMax)); } if(MesClient.sortA == cur - 1){ MesClient.sortA = cur; MesClient.aFinish = plc.readInt16(1138); String fout = plc.readInt16(1064)+""; String sout = (float)plc.readInt16(1065)/1000+""; String fmin = plc.readInt16(1068)+""; String smin = (float)plc.readInt16(1070)/1000+""; String fmax = plc.readInt16(1069)+""; String smax = (float)plc.readInt16(1071)/1000+""; MesClient.param2.setText(cur+""); System.out.println("cur:"+cur); if(MesClient.aSwitchEnable && MesClient.sortA == MesClient.aSwitchFrom - 1){ writeRecipe(plc, MesClient.aSwitchSMin, MesClient.aSwitchSMax, MesClient.aSwitchFMin, MesClient.aSwitchFMax); } if(!MesClient.product_sn.getText().isEmpty()){ String qty = "1"; if(Integer.valueOf(fout) < Integer.valueOf(fmin) || Integer.valueOf(fout) > Integer.valueOf(fmax)){ qty = "0"; } if(Float.valueOf(sout) < Float.valueOf(smin) || Float.valueOf(sout) > Float.valueOf(smax)){ qty = "0"; } // NG处理 if(qty.equals("0")){ MesClient.zdStatusA = 1; MesClient.foutA = fout; MesClient.soutA = sout; MesClient.fmaxA = fmax; MesClient.fminA = fmin; MesClient.smaxA = smax; MesClient.sminA = smin; MesClient.curA = cur+""; MesClient.resetResultA.setEnabled(true); MesClient.okResultA.setEnabled(true); MesClient.ngResultA.setEnabled(true); setPowerOff(plc); DataUtil.addNgData(MesClient.product_sn.getText(),"A"); } if(qty.equals("1")){ JdbcUtils.insertProdData(MesClient.mes_gw, MesClient.mes_line_sn, MesClient.product_sn.getText(),"A",fout,sout,fmin,smin,fmax,smax,qty,cur+"", MesClient.user_menu.getText()); } } } if(MesClient.zdStatusA == 0 && MesClient.zdStatusB == 0){ upResult(); } markOk(plc); } catch (Exception e) { markFail(plc); e.printStackTrace(); } } public static void getDataB(ModbusTcp plc){ if (isUnavailable(plc)) { return; } try { // 41065=F-out 41066=S-out // 41069=F-min 41071=S-min 41070=F-max 41072=S-max // 预设数量=41129 完成数=41137 Short cur = plc.readInt16(1136); if(MesClient.bMax <= 0){ MesClient.bMax = plc.readInt16(1128); MesClient.param3.setText(String.valueOf(MesClient.bMax)); } if(MesClient.sortB == cur - 1){ MesClient.sortB = cur; MesClient.bFinish = plc.readInt16(1138); String fout = plc.readInt16(1064)+""; String sout = (float)plc.readInt16(1065)/1000+""; String fmin = plc.readInt16(1068)+""; String smin = (float)plc.readInt16(1070)/1000+""; String fmax = plc.readInt16(1069)+""; String smax = (float)plc.readInt16(1071)/1000+""; if(MesClient.bSwitchEnable && MesClient.sortB == MesClient.bSwitchFrom - 1){ writeRecipe(plc, MesClient.bSwitchSMin, MesClient.bSwitchSMax, MesClient.bSwitchFMin, MesClient.bSwitchFMax); } MesClient.param4.setText(cur+""); System.out.println("cur:"+cur); if(!MesClient.product_sn.getText().isEmpty()){ String qty = "1"; if(Integer.valueOf(fout) < Integer.valueOf(fmin) || Integer.valueOf(fout) > Integer.valueOf(fmax)){ qty = "0"; } if(Float.valueOf(sout) < Float.valueOf(smin) || Float.valueOf(sout) > Float.valueOf(smax)){ qty = "0"; } // NG处理 if(qty.equals("0")){ MesClient.zdStatusB = 1; MesClient.foutB = fout; MesClient.soutB = sout; MesClient.fmaxB = fmax; MesClient.fminB = fmin; MesClient.smaxB = smax; MesClient.sminB = smin; MesClient.curB = cur+""; MesClient.resetResultB.setEnabled(true); MesClient.okResultB.setEnabled(true); MesClient.ngResultB.setEnabled(true); setPowerOff(plc); DataUtil.addNgData(MesClient.product_sn.getText(),"B"); } if(qty.equals("1")){ JdbcUtils.insertProdData(MesClient.mes_gw, MesClient.mes_line_sn, MesClient.product_sn.getText(),"B",fout,sout,fmin,smin,fmax,smax,qty,cur+"", MesClient.user_menu.getText()); } } } if(MesClient.zdStatusA == 0 && MesClient.zdStatusB == 0){ upResult(); } markOk(plc); } catch (Exception e) { markFail(plc); e.printStackTrace(); } } // 上传总结果 public static void upResult(){ if (MesClient.zdStatusA != 0 || MesClient.zdStatusB != 0) { return; } if(!MesClient.curSn.isEmpty() && MesClient.aMax > 0 && MesClient.aMax == MesClient.sortA && MesClient.bMax > 0 && MesClient.bMax == MesClient.sortB){ MesClient.finish_ok_bt.setEnabled(true); MesClient.finish_ng_bt.setEnabled(true); if(MesClient.tjStatus == 0 && MesClient.check_quality_result){ MesClient.tjStatus = 1; MesClient.getUser(); String retf = "OK"; if(MesClient.aFinish != MesClient.aMax){ retf = "NG"; } if(MesClient.bFinish != MesClient.bMax){ retf = "NG"; } Boolean ret = DataUtil.sendQuality(MesClient.nettyClient, MesClient.product_sn.getText(),retf, MesClient.user20); if(!ret){ MesClient.setMenuStatus(MesClient.tjFlagTextErr,-1); } } } } // 获取控制模式 public static short getControlModel(ModbusTcp plc){ short control = 0; if (isUnavailable(plc)) { return control; } try{ control = plc.readInt16(1090); markOk(plc); }catch (Exception e){ markFail(plc); e.printStackTrace(); } return control; } // 获取二维码 public static String getSn(ModbusTcp plc){ String sn = ""; if (isUnavailable(plc)) { return sn; } try{ sn = plc.readString(1216,40, Charset.forName("UTF8")); markOk(plc); }catch (Exception e){ markFail(plc); e.printStackTrace(); } return splitIntoChunks(sn,2); } // 每两个字符分割,并反转 private static String splitIntoChunks(String str, int chunkSize) { if (str == null || str.isEmpty() || chunkSize <= 0) { return ""; } int length = str.length(); int arraySize = (length + chunkSize - 1) / chunkSize; String[] result = new String[arraySize]; for (int i = 0, j = 0; i < length; i += chunkSize, j++) { int endIndex = Math.min(i + chunkSize, length); String sttr = str.substring(i, endIndex); StringBuilder sb = new StringBuilder(sttr); String reversedStr = sb.reverse().toString(); // 字符串反转 result[j] = reversedStr; } return String.join("",result); } // 远程开机 public static Boolean setPowerOn(ModbusTcp plc){ Boolean ret = false; if (isUnavailable(plc)) { return ret; } try{ plc.writeCoil(3128,true); markOk(plc); ret = true; }catch (Exception e){ markFail(plc); e.printStackTrace(); ret = false; } return ret; } // 远程关机 public static Boolean setPowerOff(ModbusTcp plc){ Boolean ret = false; if (isUnavailable(plc)) { return ret; } try{ plc.writeCoil(3128,false); markOk(plc); ret = true; }catch (Exception e){ markFail(plc); e.printStackTrace(); ret = false; } return ret; } // 重置任务,写入颗数和初始行程/拉力 public static void setTask(ModbusTcp plc, Short setNum, short sMin, short sMax, short fMin, short fMax){ if (isUnavailable(plc)) { return; } try{ // 设置模式 1=标记铆接模式 plc.writeInt16(1092,(short) 1); // 设置任务 plc.writeInt16(1128,setNum); plc.writeInt16(1136,(short) 0); plc.writeInt16(1138,(short) 0); writeRecipe(plc, sMin, sMax, fMin, fMax); markOk(plc); }catch (Exception e){ markFail(plc); e.printStackTrace(); } } private static void writeRecipe(ModbusTcp plc, short sMin, short sMax, short fMin, short fMax){ plc.writeInt16(1070, sMin); plc.writeInt16(1071, sMax); plc.writeInt16(1068, fMin); plc.writeInt16(1069, fMax); } }