YtNettyClientHandler.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. package com.mes.util.ytnetty;
  2. import com.mes.ui.MesClient;
  3. import com.mes.util.DateLocalUtils;
  4. import com.mes.util.TestParam;
  5. import io.netty.channel.Channel;
  6. import io.netty.channel.ChannelHandlerContext;
  7. import io.netty.channel.ChannelInboundHandlerAdapter;
  8. import io.netty.handler.timeout.IdleState;
  9. import io.netty.handler.timeout.IdleStateEvent;
  10. import org.slf4j.Logger;
  11. import org.slf4j.LoggerFactory;
  12. import java.awt.*;
  13. import java.text.SimpleDateFormat;
  14. import java.util.Date;
  15. public class YtNettyClientHandler extends ChannelInboundHandlerAdapter {
  16. public static final Logger log = LoggerFactory.getLogger(YtNettyClientHandler.class);
  17. /** 泄露值合格区间(含边界) */
  18. private static final double LEAK_OK_MIN = -10.0;
  19. private static final double LEAK_OK_MAX = 2.5;
  20. private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  21. public static byte[] responseByte;
  22. private int timeoutNum = 0;
  23. private int timeoutNumMax = 3;
  24. @Override
  25. public void channelActive(ChannelHandlerContext ctx) throws Exception {
  26. log.info("mes connecting:" + sdf.format(new Date()));
  27. }
  28. @Override
  29. public void channelInactive(ChannelHandlerContext ctx) throws Exception {
  30. Channel channel = ctx.channel();
  31. log.error("close tcp, ip:" + channel.remoteAddress());
  32. YtNettyClient.tcpOnline = 0;
  33. System.out.println("3s 之后尝试重新连接服务器...");
  34. Thread.sleep(3 * 1000);
  35. YtNettyClient.doConnect();
  36. }
  37. @Override
  38. public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
  39. IdleState state = ((IdleStateEvent) evt).state();
  40. if (state.equals(IdleState.READER_IDLE)) {
  41. System.out.println("客户端read超时" + (timeoutNum++) + "次");
  42. if (timeoutNum > timeoutNumMax) {
  43. System.out.println("超时次数上限,关闭这个不活跃的连接");
  44. ctx.channel().close();
  45. }
  46. }
  47. if (state.equals(IdleState.ALL_IDLE)) {
  48. sendHeartbeatPacket(ctx);
  49. }
  50. }
  51. @Override
  52. public void channelRead(ChannelHandlerContext ctx, Object message) throws Exception {
  53. timeoutNum = 0;
  54. log.info("message:" + message);
  55. String msg = message + "";
  56. String code = YtUtil.getCode(msg);
  57. log.info("code:" + code);
  58. log.info("msg:" + msg);
  59. try {
  60. if (MesClient.configParam != null && !isInntaiDevice(MesClient.configParam.getDevice())) {
  61. return;
  62. }
  63. switch (code) {
  64. case "4353": // 最终结果 CS
  65. if (MesClient.work_status != 1 || MesClient.mesTjFlag == 1) {
  66. log.info("忽略4353:未在测试中或本轮已提交");
  67. break;
  68. }
  69. MesClient.mesTjFlag = 1;
  70. String sn = MesClient.product_sn.getText().trim();
  71. QmResultUtil qmResultUtil = new QmResultUtil(msg);
  72. log.info("INNTAI最终结果 {}", qmResultUtil);
  73. MesClient.param1.setText(qmResultUtil.pressureValue);
  74. MesClient.param2.setText(qmResultUtil.leakValue);
  75. if ("OK".equals(qmResultUtil.result)) {
  76. MesClient.result.setText("OK");
  77. MesClient.result.setForeground(Color.GREEN);
  78. } else {
  79. MesClient.result.setText("NG");
  80. MesClient.result.setForeground(Color.RED);
  81. }
  82. TestParam testParam = new TestParam();
  83. testParam.setSn(sn);
  84. testParam.setOprno(MesClient.getEffectiveOprno());
  85. testParam.setOprnoTitle(MesClient.configParam != null ? MesClient.configParam.getOprnoTitle() : "");
  86. testParam.setLineSn(MesClient.getEffectiveLineSn());
  87. testParam.setUcode(MesClient.user_menu != null ? MesClient.user_menu.getText().trim() : "");
  88. testParam.setParam1(qmResultUtil.pressureValue);
  89. testParam.setParam2(qmResultUtil.pressureUnit);
  90. testParam.setParam3(qmResultUtil.leakValue);
  91. testParam.setParam4(qmResultUtil.leakUnit);
  92. testParam.setParam5(MesClient.configParam != null && MesClient.configParam.getProgramNo() != null
  93. ? MesClient.configParam.getProgramNo() : "");
  94. testParam.setResult(qmResultUtil.result);
  95. testParam.setDeviceType(MesClient.configParam != null ? MesClient.configParam.getDevice() : "INNTAI");
  96. testParam.setRemark("");
  97. testParam.setCreateTime(DateLocalUtils.getCurrentTime());
  98. MesClient.afterTestSaveAndUpload(testParam);
  99. break;
  100. case "5253": // 实时结果
  101. if (MesClient.work_status != 1 || MesClient.workstop == 1) {
  102. break;
  103. }
  104. QmCurUtil qmCurUtil = new QmCurUtil(msg);
  105. log.info("qmCurUtil:" + qmCurUtil.toString());
  106. // 仅中间步骤开启本轮
  107. if (qmCurUtil.isRunningStep()) {
  108. if (MesClient.mesStartFlag == 0 || MesClient.mesTjFlag == 1) {
  109. MesClient.mesStartFlag = 1;
  110. MesClient.mesTjFlag = 0;
  111. log.info("本轮测试已开始,step={}", qmCurUtil.step);
  112. }
  113. // 测试中不显示OK/NG
  114. if (MesClient.result != null
  115. && !"等待结果".equals(MesClient.result.getText())) {
  116. MesClient.result.setText("等待结果");
  117. MesClient.result.setForeground(Color.GRAY);
  118. }
  119. }
  120. MesClient.setMenuStatus("当前步骤:" + qmCurUtil.step, 0);
  121. // 实时只刷压强/泄漏数值,不刷OK/NG
  122. MesClient.param1.setText(qmCurUtil.pressureValue);
  123. MesClient.param2.setText(qmCurUtil.leakValue);
  124. if (qmCurUtil.pressureValue != null && !qmCurUtil.pressureValue.trim().isEmpty()) {
  125. MesClient.lastQmPressure = qmCurUtil.pressureValue.trim();
  126. }
  127. if (qmCurUtil.leakValue != null && !qmCurUtil.leakValue.trim().isEmpty()) {
  128. MesClient.lastQmLeak = qmCurUtil.leakValue.trim();
  129. }
  130. // 气密仪结束步:才判定并显示OK/NG、提交
  131. if (MesClient.mesStartFlag == 1 && MesClient.mesTjFlag == 0 && qmCurUtil.isEndStep()) {
  132. // finishByLeakRange();
  133. MesClient.workstop = 1;
  134. ctx.writeAndFlush(YtUtil.getSendByteBuf(YtUtil.getResultCommon()));
  135. }
  136. break;
  137. case "5453":
  138. case "4F4B":
  139. case "4552":
  140. break;
  141. }
  142. } catch (Exception e) {
  143. e.printStackTrace();
  144. }
  145. }
  146. /**
  147. * 测试结束:按泄露值 [-4, 8] 判定 OK/NG,显示并提交。
  148. * 不再使用气密仪 4353 自带判定结果。
  149. */
  150. private void finishByLeakRange() {
  151. String sn = MesClient.product_sn.getText().trim();
  152. if (sn.isEmpty()) {
  153. log.info("结束判定跳过:工件码为空");
  154. return;
  155. }
  156. String pressureValue = MesClient.lastQmPressure != null ? MesClient.lastQmPressure.trim() : "";
  157. String leakValue = MesClient.lastQmLeak != null ? MesClient.lastQmLeak.trim() : "";
  158. if (leakValue.isEmpty()) {
  159. log.info("结束判定跳过:泄露值尚未收到");
  160. return;
  161. }
  162. MesClient.mesTjFlag = 1;
  163. boolean ok = isLeakOk(leakValue);
  164. String lastRet = ok ? "OK" : "NG";
  165. log.info("测试结束判定:leak={}, 区间[{}, {}], result={}",
  166. leakValue, LEAK_OK_MIN, LEAK_OK_MAX, lastRet);
  167. String pressureUnit = "kPa";
  168. MesClient.param1.setText(pressureValue + pressureUnit);
  169. MesClient.param2.setText(leakValue);
  170. if (ok) {
  171. MesClient.result.setText("OK");
  172. MesClient.result.setForeground(Color.GREEN);
  173. } else {
  174. MesClient.result.setText("NG");
  175. MesClient.result.setForeground(Color.RED);
  176. }
  177. TestParam testParam = new TestParam();
  178. testParam.setSn(sn);
  179. testParam.setParam1(pressureValue);
  180. testParam.setParam2(pressureUnit);
  181. testParam.setParam3(leakValue);
  182. testParam.setParam4("");
  183. testParam.setResult(lastRet);
  184. testParam.setRemark(ok ? "" : "泄露值超限(" + LEAK_OK_MIN + "~" + LEAK_OK_MAX + ")");
  185. testParam.setOprno(MesClient.getEffectiveOprno());
  186. testParam.setOprnoTitle(MesClient.configParam != null ? MesClient.configParam.getOprnoTitle() : "");
  187. testParam.setLineSn(MesClient.getEffectiveLineSn());
  188. testParam.setUcode(MesClient.user_menu != null ? MesClient.user_menu.getText().trim() : "");
  189. testParam.setParam5(MesClient.configParam != null && MesClient.configParam.getProgramNo() != null
  190. ? MesClient.configParam.getProgramNo() : "");
  191. testParam.setDeviceType(MesClient.configParam != null ? MesClient.configParam.getDevice() : "INNTAI");
  192. testParam.setCreateTime(DateLocalUtils.getCurrentTime());
  193. MesClient.afterTestSaveAndUpload(testParam);
  194. }
  195. /** 泄露值在 [-4, 8](含边界)为 OK,否则 NG */
  196. static boolean isLeakOk(String leakValue) {
  197. try {
  198. double v = Double.parseDouble(leakValue.trim());
  199. return v >= LEAK_OK_MIN && v <= LEAK_OK_MAX;
  200. } catch (Exception e) {
  201. log.warn("泄露值无法解析为数字: {}", leakValue);
  202. return false;
  203. }
  204. }
  205. static boolean isInntaiDevice(String device) {
  206. if (device == null) {
  207. return false;
  208. }
  209. String d = device.trim();
  210. return "INNTAI".equalsIgnoreCase(d) || "中皖英泰".equals(d);
  211. }
  212. @Override
  213. public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
  214. System.out.println("exceptionCaught");
  215. }
  216. private void sendHeartbeatPacket(ChannelHandlerContext ctx) {
  217. ctx.writeAndFlush(YtUtil.getSendByteBuf(YtUtil.getStateCommon()));
  218. }
  219. }