ModbusUtil.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. package com.mes.ui;
  2. import com.github.xingshuangs.iot.protocol.modbus.service.ModbusTcp;
  3. import com.mes.util.JdbcUtils;
  4. import javax.swing.*;
  5. import java.nio.charset.Charset;
  6. import java.util.List;
  7. public class ModbusUtil {
  8. // 刷新界面拉力、行程显示
  9. private static void updateForceStrokeDisplay(ModbusTcp plc, JTextField forceField, JTextField strokeField) {
  10. if (forceField == null || strokeField == null) {
  11. return;
  12. }
  13. try {
  14. forceField.setText(plc.readInt16(1064) + "");
  15. strokeField.setText((float) plc.readInt16(1065) / 1000 + "");
  16. } catch (Exception e) {
  17. e.printStackTrace();
  18. }
  19. }
  20. public static void getDataA(ModbusTcp plc){
  21. // 说明预设数量有变化不能修改
  22. // 打钉数应按实际监听数算
  23. // 41065=F-out 41066=S-out
  24. // 41069=F-min 41071=S-min 41070=F-max 41072=S-max
  25. // 预设数量=41129 完成数=41137
  26. Short cur = plc.readInt16(1136);
  27. updateForceStrokeDisplay(plc, MesClient.param5, MesClient.param6);
  28. // System.out.println("F-out:"+plc.readInt16(1064));
  29. // System.out.println("S-out:"+plc.readInt16(1065));
  30. // System.out.println("F-min:"+plc.readInt16(1068));
  31. // System.out.println("S-min:"+plc.readInt16(1070));
  32. // System.out.println("F-max:"+plc.readInt16(1069));
  33. // System.out.println("S-max:"+plc.readInt16(1071));
  34. // System.out.println("预设数量:"+plc.readInt16(1128));
  35. //System.out.println("当前数量:"+cur);
  36. if(MesClient.aMax <= 0){
  37. MesClient.aMax = plc.readInt16(1128); // 任务数量
  38. MesClient.param1.setText(String.valueOf(MesClient.aMax));
  39. }
  40. MesClient.param2.setText(cur + "");
  41. if(MesClient.sortA == cur - 1){
  42. MesClient.sortA = cur;
  43. MesClient.aFinish = plc.readInt16(1138);
  44. String fout = plc.readInt16(1064)+"";
  45. String sout = (float)plc.readInt16(1065)/1000+"";
  46. String fmin = plc.readInt16(1068)+"";
  47. String smin = (float)plc.readInt16(1070)/1000+"";
  48. String fmax = plc.readInt16(1069)+"";
  49. String smax = (float)plc.readInt16(1071)/1000+"";
  50. System.out.println("cur:"+cur);
  51. int nextRivet = cur + 1;
  52. if (nextRivet <= MesClient.aMax) {
  53. applyParamsForRivet(plc, MesClient.rivetParamRangesA, nextRivet);
  54. }
  55. if(!MesClient.product_sn.getText().isEmpty()){
  56. JdbcUtils.insertProdData(MesClient.mes_gw, MesClient.mes_line_sn, MesClient.product_sn.getText(),"A",fout,sout,fmin,smin,fmax,smax,"1",cur+"", MesClient.user_menu.getText());
  57. }
  58. }
  59. upResult();
  60. }
  61. public static void getDataB(ModbusTcp plc){
  62. // 41065=F-out 41066=S-out
  63. // 41069=F-min 41071=S-min 41070=F-max 41072=S-max
  64. // 预设数量=41129 完成数=41137
  65. Short cur = plc.readInt16(1136);
  66. updateForceStrokeDisplay(plc, MesClient.param7, MesClient.param8);
  67. // System.out.println("F-out:"+plc.readInt16(1064));
  68. // System.out.println("S-out:"+plc.readInt16(1065));
  69. // System.out.println("F-min:"+plc.readInt16(1068));
  70. // System.out.println("S-min:"+plc.readInt16(1070));
  71. // System.out.println("F-max:"+plc.readInt16(1069));
  72. // System.out.println("S-max:"+plc.readInt16(1071));
  73. // System.out.println("set:"+plc.readInt16(1128));
  74. // System.out.println("cur:"+cur);
  75. // System.out.println("cur2:"+MesClient.sortB);
  76. if(MesClient.bMax <= 0){
  77. MesClient.bMax = plc.readInt16(1128);
  78. MesClient.param3.setText(String.valueOf(MesClient.bMax));
  79. }
  80. MesClient.param4.setText(cur + "");
  81. if(MesClient.sortB == cur - 1){
  82. MesClient.sortB = cur;
  83. String fout = plc.readInt16(1064)+"";
  84. String sout = (float)plc.readInt16(1065)/1000+"";
  85. String fmin = plc.readInt16(1068)+"";
  86. String smin = (float)plc.readInt16(1070)/1000+"";
  87. String fmax = plc.readInt16(1069)+"";
  88. String smax = (float)plc.readInt16(1071)/1000+"";
  89. int nextRivet = cur + 1;
  90. if (nextRivet <= MesClient.bMax) {
  91. applyParamsForRivet(plc, MesClient.rivetParamRangesB, nextRivet);
  92. }
  93. System.out.println("cur:"+cur);
  94. if(!MesClient.product_sn.getText().isEmpty()){
  95. JdbcUtils.insertProdData(MesClient.mes_gw, MesClient.mes_line_sn, MesClient.product_sn.getText(),"B",fout,sout,fmin,smin,fmax,smax,"1",cur+"", MesClient.user_menu.getText());
  96. }
  97. }
  98. upResult();
  99. }
  100. // 上传总结果
  101. public static void upResult(){
  102. if(!MesClient.curSn.isEmpty() && MesClient.aMax > 0 && MesClient.aMax == MesClient.sortA && MesClient.bMax > 0 && MesClient.bMax == MesClient.sortB){
  103. MesClient.finish_ok_bt.setEnabled(true);
  104. MesClient.finish_ng_bt.setEnabled(true);
  105. if(MesClient.tjStatus == 0 && MesClient.check_quality_result){
  106. MesClient.tjStatus = 1;
  107. String retf = "OK";
  108. if(MesClient.aFinish != MesClient.aMax){
  109. retf = "NG";
  110. }
  111. MesClient.submitQualityResult(retf);
  112. }
  113. }
  114. }
  115. // 获取控制模式
  116. public static short getControlModel(ModbusTcp plc){
  117. short control = 0;
  118. try{
  119. control = plc.readInt16(1090);
  120. }catch (Exception e){
  121. e.printStackTrace();
  122. }
  123. return control;
  124. }
  125. // 获取二维码
  126. public static String getSn(ModbusTcp plc){
  127. String sn = "";
  128. try{
  129. sn = plc.readString(1216,40, Charset.forName("UTF8"));
  130. }catch (Exception e){
  131. e.printStackTrace();
  132. }
  133. return splitIntoChunks(sn,2);
  134. }
  135. // 每两个字符分割,并反转
  136. private static String splitIntoChunks(String str, int chunkSize) {
  137. if (str == null || str.isEmpty() || chunkSize <= 0) {
  138. return "";
  139. }
  140. int length = str.length();
  141. int arraySize = (length + chunkSize - 1) / chunkSize;
  142. String[] result = new String[arraySize];
  143. for (int i = 0, j = 0; i < length; i += chunkSize, j++) {
  144. int endIndex = Math.min(i + chunkSize, length);
  145. String sttr = str.substring(i, endIndex);
  146. StringBuilder sb = new StringBuilder(sttr);
  147. String reversedStr = sb.reverse().toString(); // 字符串反转
  148. result[j] = reversedStr;
  149. }
  150. return String.join("",result);
  151. }
  152. // 远程开机
  153. public static Boolean setPowerOn(ModbusTcp plc){
  154. Boolean ret = false;
  155. try{
  156. plc.writeCoil(3128,true);
  157. // plc.writeCoil(3079,false);
  158. // plc.writeCoil(3328,true); // 必须选关掉关机,开机才起左右
  159. ret = true;
  160. }catch (Exception e){
  161. e.printStackTrace();
  162. ret = false;
  163. }
  164. return ret;
  165. }
  166. // 远程关机
  167. public static Boolean setPowerOff(ModbusTcp plc){
  168. if (MesClient.mes_shield_flag) {
  169. System.out.println("MES屏蔽已开启,跳过关机指令");
  170. return true;
  171. }
  172. Boolean ret = false;
  173. try{
  174. plc.writeCoil(3128,false);
  175. // plc.writeCoil(3328,false);
  176. // plc.writeCoil(3079,true); // 关机
  177. // 必须选关掉关机,开机才起左右
  178. ret = true;
  179. }catch (Exception e){
  180. e.printStackTrace();
  181. ret = false;
  182. }
  183. return ret;
  184. }
  185. // 查找指定颗数对应的参数区间
  186. public static RivetParamRange findRivetParamRange(List<RivetParamRange> ranges, int rivetNo) {
  187. if (ranges == null) {
  188. return null;
  189. }
  190. for (RivetParamRange range : ranges) {
  191. if (range.contains(rivetNo)) {
  192. return range;
  193. }
  194. }
  195. return null;
  196. }
  197. // 获取指定枪的参数区间,必要时从数据库重新加载
  198. private static List<RivetParamRange> getRivetParamRanges(String gunType) {
  199. List<RivetParamRange> ranges = "A".equalsIgnoreCase(gunType)
  200. ? MesClient.rivetParamRangesA : MesClient.rivetParamRangesB;
  201. if (ranges == null || ranges.isEmpty()) {
  202. MesClient.loadRivetParamConfig();
  203. ranges = "A".equalsIgnoreCase(gunType)
  204. ? MesClient.rivetParamRangesA : MesClient.rivetParamRangesB;
  205. }
  206. return ranges;
  207. }
  208. // 扫码/开工:加载最新配置、远程开机并下发任务与第1颗拉力/行程参数
  209. public static void prepareAndStartWork() {
  210. MesClient.loadRivetParamConfig();
  211. setPowerOn(MesClient.plcA);
  212. setPowerOn(MesClient.plcB);
  213. setTask(MesClient.plcA, MesClient.aSetNum, "A");
  214. setTask(MesClient.plcB, MesClient.bSetNum, "B");
  215. System.out.println("开工下发完成:A枪" + MesClient.aSetNum + "颗, B枪" + MesClient.bSetNum + "颗");
  216. }
  217. // 保存配置后,按PLC当前进度将对应颗数的拉力/行程参数立即下发
  218. public static void syncRivetParamsToPlc(ModbusTcp plc, List<RivetParamRange> ranges) {
  219. if (plc == null || ranges == null || ranges.isEmpty()) {
  220. return;
  221. }
  222. try {
  223. int rivetNo;
  224. if (MesClient.work_status == 1) {
  225. short cur = plc.readInt16(1136);
  226. rivetNo = Math.max(cur + 1, 1);
  227. } else {
  228. // 非加工中按第1颗区间下发,避免沿用上次的完成颗数
  229. rivetNo = 1;
  230. }
  231. applyParamsForRivet(plc, ranges, rivetNo);
  232. } catch (Exception e) {
  233. e.printStackTrace();
  234. throw new RuntimeException(e);
  235. }
  236. }
  237. // 按颗数下发PLC拉力/行程参数
  238. public static void applyParamsForRivet(ModbusTcp plc, List<RivetParamRange> ranges, int rivetNo) {
  239. RivetParamRange range = findRivetParamRange(ranges, rivetNo);
  240. if (range == null) {
  241. System.out.println("未找到第" + rivetNo + "颗对应的参数配置");
  242. return;
  243. }
  244. try {
  245. plc.writeInt16(1068, (short) range.getFMin());
  246. plc.writeInt16(1069, (short) range.getFMax());
  247. plc.writeInt16(1070, (short) range.getSMin());
  248. plc.writeInt16(1071, (short) range.getSMax());
  249. System.out.println("下发铆接参数:第" + rivetNo + "颗, F=" + range.getFMin() + "-" + range.getFMax()
  250. + ", S=" + range.getSMin() + "-" + range.getSMax());
  251. } catch (Exception e) {
  252. e.printStackTrace();
  253. }
  254. }
  255. // 重置任务
  256. public static void setTask(ModbusTcp plc, Short setNum, String gunType) {
  257. try{
  258. // 设置模式 1=标记铆接模式
  259. plc.writeInt16(1092,(short) 1);
  260. // 设置任务
  261. plc.writeInt16(1128,setNum);
  262. plc.writeInt16(1136,(short) 0);
  263. plc.writeInt16(1138,(short) 0);
  264. List<RivetParamRange> ranges = getRivetParamRanges(gunType);
  265. applyParamsForRivet(plc, ranges, 1);
  266. }catch (Exception e){
  267. e.printStackTrace();
  268. }
  269. }
  270. // A枪说明 192.168.1.7
  271. // plc.writeCoil(3079,false);
  272. // plc.writeCoil(3328,true); // 必须选关掉关机,开机才起左右
  273. //// plc.writeCoil(3128,false);
  274. // System.out.println("控制模式:"+plc.readInt16(1090)); // 1091 控制模式
  275. // System.out.println("系统运行中:"+plc.readCoil(3128,1)); // 3129 系统运行中
  276. // System.out.println("结束暂停:"+plc.readCoil(3132,1)); // 3133 系统运行中
  277. // System.out.println("远程开机:"+plc.readCoil(3328,1)); // 3329 远程开机
  278. // System.out.println("远程关机:"+plc.readCoil(3079,1)); // 3080 远程关机
  279. // System.out.println("作业模式:"+plc.readInt16(1092)); // 1093 作业模式
  280. // System.out.println("最大拉力:"+plc.readInt16(1064)); // 1065 最大拉力
  281. // System.out.println("对应位移:"+plc.readInt16(1065)); // 1066 对应位移
  282. // System.out.println("任务数量:"+plc.readInt16(1128)); // 1129 任务数量
  283. // System.out.println("合格数量:"+plc.readInt16(1138)); // 1139 合格数量
  284. // System.out.println("质量状态:"+plc.readInt16(1072)); // 1073 质量状态
  285. // System.out.println("F-out:"+plc.readInt16(1064));
  286. // System.out.println("S-out:"+plc.readInt16(1065));
  287. // System.out.println("F-min:"+plc.readInt16(1068));
  288. // System.out.println("S-min:"+plc.readInt16(1070));
  289. // System.out.println("F-max:"+plc.readInt16(1069));
  290. // System.out.println("S-max:"+plc.readInt16(1071));
  291. }