ModbusUtil.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. package com.mes.ui;
  2. import com.github.xingshuangs.iot.protocol.modbus.service.ModbusTcp;
  3. import com.mes.util.JdbcUtils;
  4. import java.nio.charset.Charset;
  5. import java.util.Map;
  6. import java.util.concurrent.ConcurrentHashMap;
  7. public class ModbusUtil {
  8. public static final int PLC_TIMEOUT_MS = 5000;
  9. private static final Map<ModbusTcp, Long> failUntil = new ConcurrentHashMap<ModbusTcp, Long>();
  10. public static void applyTimeout(ModbusTcp plc) {
  11. if (plc == null) {
  12. return;
  13. }
  14. plc.setConnectTimeout(PLC_TIMEOUT_MS);
  15. plc.setReceiveTimeout(PLC_TIMEOUT_MS);
  16. }
  17. private static boolean isUnavailable(ModbusTcp plc) {
  18. if (plc == null) {
  19. return true;
  20. }
  21. Long until = failUntil.get(plc);
  22. return until != null && System.currentTimeMillis() < until;
  23. }
  24. private static void markOk(ModbusTcp plc) {
  25. failUntil.remove(plc);
  26. }
  27. private static void markFail(ModbusTcp plc) {
  28. failUntil.put(plc, System.currentTimeMillis() + PLC_TIMEOUT_MS);
  29. try {
  30. plc.close();
  31. } catch (Exception ignore) {
  32. }
  33. }
  34. public static void getDataA(ModbusTcp plc){
  35. if (isUnavailable(plc)) {
  36. return;
  37. }
  38. try {
  39. // 说明预设数量有变化不能修改
  40. // 打钉数应按实际监听数算
  41. // 41065=F-out 41066=S-out
  42. // 41069=F-min 41071=S-min 41070=F-max 41072=S-max
  43. // 预设数量=41129 完成数=41137
  44. Short cur = plc.readInt16(1136);
  45. if(MesClient.aMax <= 0){
  46. MesClient.aMax = plc.readInt16(1128); // 任务数量
  47. MesClient.param1.setText(String.valueOf(MesClient.aMax));
  48. }
  49. if(MesClient.sortA == cur - 1){
  50. MesClient.sortA = cur;
  51. MesClient.aFinish = plc.readInt16(1138);
  52. String fout = plc.readInt16(1064)+"";
  53. String sout = (float)plc.readInt16(1065)/1000+"";
  54. String fmin = plc.readInt16(1068)+"";
  55. String smin = (float)plc.readInt16(1070)/1000+"";
  56. String fmax = plc.readInt16(1069)+"";
  57. String smax = (float)plc.readInt16(1071)/1000+"";
  58. MesClient.param2.setText(cur+"");
  59. System.out.println("cur:"+cur);
  60. if(MesClient.aSwitchEnable && MesClient.sortA == MesClient.aSwitchFrom - 1){
  61. writeRecipe(plc, MesClient.aSwitchSMin, MesClient.aSwitchSMax, MesClient.aSwitchFMin, MesClient.aSwitchFMax);
  62. }
  63. if(!MesClient.product_sn.getText().isEmpty()){
  64. String qty = "1";
  65. if(Integer.valueOf(fout) < Integer.valueOf(fmin) || Integer.valueOf(fout) > Integer.valueOf(fmax)){
  66. qty = "0";
  67. }
  68. if(Float.valueOf(sout) < Float.valueOf(smin) || Float.valueOf(sout) > Float.valueOf(smax)){
  69. qty = "0";
  70. }
  71. // NG处理
  72. if(qty.equals("0")){
  73. MesClient.zdStatusA = 1;
  74. MesClient.foutA = fout;
  75. MesClient.soutA = sout;
  76. MesClient.fmaxA = fmax;
  77. MesClient.fminA = fmin;
  78. MesClient.smaxA = smax;
  79. MesClient.sminA = smin;
  80. MesClient.curA = cur+"";
  81. MesClient.resetResultA.setEnabled(true);
  82. MesClient.okResultA.setEnabled(true);
  83. MesClient.ngResultA.setEnabled(true);
  84. setPowerOff(plc);
  85. DataUtil.addNgData(MesClient.product_sn.getText(),"A");
  86. }
  87. if(qty.equals("1")){
  88. 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());
  89. }
  90. }
  91. }
  92. if(MesClient.zdStatusA == 0 && MesClient.zdStatusB == 0){
  93. upResult();
  94. }
  95. markOk(plc);
  96. } catch (Exception e) {
  97. markFail(plc);
  98. e.printStackTrace();
  99. }
  100. }
  101. public static void getDataB(ModbusTcp plc){
  102. if (isUnavailable(plc)) {
  103. return;
  104. }
  105. try {
  106. // 41065=F-out 41066=S-out
  107. // 41069=F-min 41071=S-min 41070=F-max 41072=S-max
  108. // 预设数量=41129 完成数=41137
  109. Short cur = plc.readInt16(1136);
  110. if(MesClient.bMax <= 0){
  111. MesClient.bMax = plc.readInt16(1128);
  112. MesClient.param3.setText(String.valueOf(MesClient.bMax));
  113. }
  114. if(MesClient.sortB == cur - 1){
  115. MesClient.sortB = cur;
  116. MesClient.bFinish = plc.readInt16(1138);
  117. String fout = plc.readInt16(1064)+"";
  118. String sout = (float)plc.readInt16(1065)/1000+"";
  119. String fmin = plc.readInt16(1068)+"";
  120. String smin = (float)plc.readInt16(1070)/1000+"";
  121. String fmax = plc.readInt16(1069)+"";
  122. String smax = (float)plc.readInt16(1071)/1000+"";
  123. if(MesClient.bSwitchEnable && MesClient.sortB == MesClient.bSwitchFrom - 1){
  124. writeRecipe(plc, MesClient.bSwitchSMin, MesClient.bSwitchSMax, MesClient.bSwitchFMin, MesClient.bSwitchFMax);
  125. }
  126. MesClient.param4.setText(cur+"");
  127. System.out.println("cur:"+cur);
  128. if(!MesClient.product_sn.getText().isEmpty()){
  129. String qty = "1";
  130. if(Integer.valueOf(fout) < Integer.valueOf(fmin) || Integer.valueOf(fout) > Integer.valueOf(fmax)){
  131. qty = "0";
  132. }
  133. if(Float.valueOf(sout) < Float.valueOf(smin) || Float.valueOf(sout) > Float.valueOf(smax)){
  134. qty = "0";
  135. }
  136. // NG处理
  137. if(qty.equals("0")){
  138. MesClient.zdStatusB = 1;
  139. MesClient.foutB = fout;
  140. MesClient.soutB = sout;
  141. MesClient.fmaxB = fmax;
  142. MesClient.fminB = fmin;
  143. MesClient.smaxB = smax;
  144. MesClient.sminB = smin;
  145. MesClient.curB = cur+"";
  146. MesClient.resetResultB.setEnabled(true);
  147. MesClient.okResultB.setEnabled(true);
  148. MesClient.ngResultB.setEnabled(true);
  149. setPowerOff(plc);
  150. DataUtil.addNgData(MesClient.product_sn.getText(),"B");
  151. }
  152. if(qty.equals("1")){
  153. 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());
  154. }
  155. }
  156. }
  157. if(MesClient.zdStatusA == 0 && MesClient.zdStatusB == 0){
  158. upResult();
  159. }
  160. markOk(plc);
  161. } catch (Exception e) {
  162. markFail(plc);
  163. e.printStackTrace();
  164. }
  165. }
  166. // 上传总结果
  167. public static void upResult(){
  168. if (MesClient.zdStatusA != 0 || MesClient.zdStatusB != 0) {
  169. return;
  170. }
  171. if(!MesClient.curSn.isEmpty() && MesClient.aMax > 0 && MesClient.aMax == MesClient.sortA && MesClient.bMax > 0 && MesClient.bMax == MesClient.sortB){
  172. MesClient.finish_ok_bt.setEnabled(true);
  173. MesClient.finish_ng_bt.setEnabled(true);
  174. if(MesClient.tjStatus == 0 && MesClient.check_quality_result){
  175. MesClient.tjStatus = 1;
  176. MesClient.getUser();
  177. String retf = "OK";
  178. if(MesClient.aFinish != MesClient.aMax){
  179. retf = "NG";
  180. }
  181. if(MesClient.bFinish != MesClient.bMax){
  182. retf = "NG";
  183. }
  184. Boolean ret = DataUtil.sendQuality(MesClient.nettyClient, MesClient.product_sn.getText(),retf, MesClient.user20);
  185. if(!ret){
  186. MesClient.setMenuStatus(MesClient.tjFlagTextErr,-1);
  187. }
  188. }
  189. }
  190. }
  191. // 获取控制模式
  192. public static short getControlModel(ModbusTcp plc){
  193. short control = 0;
  194. if (isUnavailable(plc)) {
  195. return control;
  196. }
  197. try{
  198. control = plc.readInt16(1090);
  199. markOk(plc);
  200. }catch (Exception e){
  201. markFail(plc);
  202. e.printStackTrace();
  203. }
  204. return control;
  205. }
  206. // 获取二维码
  207. public static String getSn(ModbusTcp plc){
  208. String sn = "";
  209. if (isUnavailable(plc)) {
  210. return sn;
  211. }
  212. try{
  213. sn = plc.readString(1216,40, Charset.forName("UTF8"));
  214. markOk(plc);
  215. }catch (Exception e){
  216. markFail(plc);
  217. e.printStackTrace();
  218. }
  219. return splitIntoChunks(sn,2);
  220. }
  221. // 每两个字符分割,并反转
  222. private static String splitIntoChunks(String str, int chunkSize) {
  223. if (str == null || str.isEmpty() || chunkSize <= 0) {
  224. return "";
  225. }
  226. int length = str.length();
  227. int arraySize = (length + chunkSize - 1) / chunkSize;
  228. String[] result = new String[arraySize];
  229. for (int i = 0, j = 0; i < length; i += chunkSize, j++) {
  230. int endIndex = Math.min(i + chunkSize, length);
  231. String sttr = str.substring(i, endIndex);
  232. StringBuilder sb = new StringBuilder(sttr);
  233. String reversedStr = sb.reverse().toString(); // 字符串反转
  234. result[j] = reversedStr;
  235. }
  236. return String.join("",result);
  237. }
  238. // 远程开机
  239. public static Boolean setPowerOn(ModbusTcp plc){
  240. Boolean ret = false;
  241. if (isUnavailable(plc)) {
  242. return ret;
  243. }
  244. try{
  245. plc.writeCoil(3128,true);
  246. markOk(plc);
  247. ret = true;
  248. }catch (Exception e){
  249. markFail(plc);
  250. e.printStackTrace();
  251. ret = false;
  252. }
  253. return ret;
  254. }
  255. // 远程关机
  256. public static Boolean setPowerOff(ModbusTcp plc){
  257. Boolean ret = false;
  258. if (isUnavailable(plc)) {
  259. return ret;
  260. }
  261. try{
  262. plc.writeCoil(3128,false);
  263. markOk(plc);
  264. ret = true;
  265. }catch (Exception e){
  266. markFail(plc);
  267. e.printStackTrace();
  268. ret = false;
  269. }
  270. return ret;
  271. }
  272. // 重置任务,写入颗数和初始行程/拉力
  273. public static void setTask(ModbusTcp plc, Short setNum, short sMin, short sMax, short fMin, short fMax){
  274. if (isUnavailable(plc)) {
  275. return;
  276. }
  277. try{
  278. // 设置模式 1=标记铆接模式
  279. plc.writeInt16(1092,(short) 1);
  280. // 设置任务
  281. plc.writeInt16(1128,setNum);
  282. plc.writeInt16(1136,(short) 0);
  283. plc.writeInt16(1138,(short) 0);
  284. writeRecipe(plc, sMin, sMax, fMin, fMax);
  285. markOk(plc);
  286. }catch (Exception e){
  287. markFail(plc);
  288. e.printStackTrace();
  289. }
  290. }
  291. private static void writeRecipe(ModbusTcp plc, short sMin, short sMax, short fMin, short fMax){
  292. plc.writeInt16(1070, sMin);
  293. plc.writeInt16(1071, sMax);
  294. plc.writeInt16(1068, fMin);
  295. plc.writeInt16(1069, fMax);
  296. }
  297. }