CodeReader8Connect.java 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. package com.warewms.hailiang.connect;
  2. import cn.hutool.core.util.ObjectUtil;
  3. import cn.hutool.extra.spring.SpringUtil;
  4. import com.github.rholder.retry.*;
  5. import com.warewms.common.core.redis.RedisCache;
  6. import com.warewms.hailiang.MES.MesService;
  7. import com.warewms.hailiang.config.CodeReadProperties;
  8. import com.warewms.hailiang.connect.base.TCPConnectBase;
  9. import com.warewms.hailiang.domain.Device;
  10. import com.warewms.hailiang.domain.DeviceLog;
  11. import com.warewms.hailiang.domain.RetroactiveNow;
  12. import com.warewms.hailiang.enums.DaSanPanPlcEnum;
  13. import com.warewms.hailiang.enums.DeviceNameEnum;
  14. import com.warewms.hailiang.init.PlcConnectServiceRunner;
  15. import com.warewms.hailiang.service.RetroactiveNowService;
  16. import io.netty.bootstrap.Bootstrap;
  17. import io.netty.buffer.ByteBuf;
  18. import io.netty.buffer.Unpooled;
  19. import io.netty.channel.*;
  20. import io.netty.channel.nio.NioEventLoopGroup;
  21. import io.netty.channel.socket.SocketChannel;
  22. import io.netty.channel.socket.nio.NioSocketChannel;
  23. import io.netty.handler.timeout.IdleStateHandler;
  24. import io.netty.util.CharsetUtil;
  25. import lombok.extern.slf4j.Slf4j;
  26. import java.util.concurrent.*;
  27. import java.util.concurrent.atomic.AtomicBoolean;
  28. /**
  29. * Created with IntelliJ IDEA.
  30. *
  31. * @author: liuzhifei
  32. * Date: 2023/8/9
  33. * Time: 15:45
  34. * To change this template use File | Settings | File Templates.
  35. * Description:大散盘行车2号读码器
  36. **/
  37. @Slf4j
  38. public class CodeReader8Connect implements TCPConnectBase {
  39. private final String IP_ADDR = "172.20.27.8";
  40. private final int PORT = 51236;
  41. private final String deviceName ="CodeReader8";
  42. private boolean enable = true;
  43. private ChannelFuture future;
  44. private Bootstrap bootstrap;
  45. private EventLoopGroup group;
  46. private ChannelPipeline pipeline;
  47. private MesService mesService;
  48. private RetroactiveNowService retroactiveNowService;
  49. private PlcConnectServiceRunner plcConnectServiceRunner;
  50. private ScheduledFuture<?> scheduledFuture =null;
  51. private ScheduledExecutorService scheduledExecutorService;
  52. {
  53. mesService = SpringUtil.getBean(MesService.class);
  54. retroactiveNowService = SpringUtil.getBean(RetroactiveNowService.class);
  55. plcConnectServiceRunner = SpringUtil.getBean(PlcConnectServiceRunner.class);
  56. scheduledExecutorService = SpringUtil.getBean(ScheduledExecutorService.class);
  57. }
  58. @Override
  59. public void init() throws InterruptedException {
  60. if (enable) {
  61. log.info("ip:{},deviceName:{}正在进行连接", IP_ADDR, deviceName);
  62. group = new NioEventLoopGroup();
  63. try {
  64. bootstrap = new Bootstrap();
  65. bootstrap.group(group).channel(NioSocketChannel.class)
  66. .option(ChannelOption.TCP_NODELAY, true)
  67. .handler(new ChannelInitializer<SocketChannel>() {
  68. @Override
  69. protected void initChannel(SocketChannel socketChannel) throws Exception {
  70. pipeline = socketChannel.pipeline();
  71. pipeline.addLast(new IdleStateHandler(1,0,0,TimeUnit.SECONDS));
  72. pipeline.addLast(new ChannelInboundHandlerAdapter(){
  73. @Override
  74. public void channelInactive(ChannelHandlerContext ctx) {
  75. SpringUtil.getApplicationContext().publishEvent(new Device(deviceName, "2"));
  76. log.error("设备:{}连接已断开!",deviceName);
  77. scheduledFuture.cancel(true);
  78. retry();
  79. }
  80. @Override
  81. public void channelRead(ChannelHandlerContext ctx, Object msg) {
  82. ByteBuf byteBuf = (ByteBuf) msg;
  83. processMessages(String.valueOf(byteBuf.toString(CharsetUtil.UTF_8)));
  84. }
  85. });
  86. }
  87. });
  88. future = bootstrap.connect(IP_ADDR, PORT).sync();
  89. future.addListener((channelFuture) -> {
  90. if (channelFuture.isSuccess()) {
  91. SpringUtil.getApplicationContext().publishEvent(new Device(deviceName, "1"));
  92. log.info("ip:{},deviceName:{}连接成功", IP_ADDR, deviceName);
  93. ConnectsTheHeartbeat();
  94. } else {
  95. log.info("ip:{},deviceName:{}连接失败等待重试!", IP_ADDR, deviceName);
  96. retry();
  97. }
  98. });
  99. } catch (Exception e) {
  100. log.error("ip:{},deviceName:{}连接异常,{},准备重试", IP_ADDR, deviceName, e.getMessage());
  101. retry();
  102. }
  103. }
  104. }
  105. @Override
  106. public void retry() {
  107. Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
  108. .retryIfResult(Boolean.FALSE::equals)
  109. .retryIfExceptionOfType(Exception.class)
  110. .withStopStrategy(StopStrategies.neverStop())
  111. .withWaitStrategy(WaitStrategies.fixedWait(5, TimeUnit.SECONDS))
  112. .build();
  113. try {
  114. retryer.call(new Callable<Boolean>() {
  115. AtomicBoolean isSuccess = new AtomicBoolean(false);
  116. @Override
  117. public Boolean call() throws Exception {
  118. log.info("ip:{},deviceName:{}连接重试",IP_ADDR,deviceName);
  119. future = bootstrap.connect(IP_ADDR, PORT).sync();
  120. future.addListener((channelFuture) -> {
  121. isSuccess.set(channelFuture.isSuccess());
  122. if (channelFuture.isSuccess()) {
  123. SpringUtil.getApplicationContext().publishEvent(new Device(deviceName,"1"));
  124. log.info("ip:{},deviceName:{}连接成功",IP_ADDR,deviceName);
  125. ConnectsTheHeartbeat();
  126. }else {
  127. log.info("ip:{},deviceName:{}连接失败等待重试!",IP_ADDR,deviceName);
  128. }
  129. });
  130. Thread.sleep(3000);
  131. return isSuccess.get();
  132. }
  133. });
  134. } catch (RetryException | ExecutionException e) {
  135. e.printStackTrace();
  136. }
  137. }
  138. /**
  139. * 连接心跳
  140. *
  141. */
  142. private void ConnectsTheHeartbeat() {
  143. scheduledFuture = scheduledExecutorService.scheduleWithFixedDelay(() -> {
  144. try {
  145. // log.info("发送心跳,设备:{}", deviceName);
  146. pipeline.writeAndFlush(Unpooled.copiedBuffer(CodeReadProperties.heartbeat, CharsetUtil.UTF_8));
  147. } catch (Exception e) {
  148. log.error("设备:{},连接中断", deviceName);
  149. SpringUtil.getApplicationContext().publishEvent(new Device(deviceName, "2"));
  150. retry();
  151. }
  152. }, 0, 3, TimeUnit.SECONDS);
  153. }
  154. @Override
  155. public void close() {
  156. group.shutdownGracefully();
  157. }
  158. @Override
  159. public String getDeviceName() {
  160. return deviceName;
  161. }
  162. @Override
  163. public ChannelPipeline getChannel() {
  164. return pipeline;
  165. }
  166. @Override
  167. public void processMessages(String message) {
  168. try {
  169. log.info("大散盘2号行车读码器消息:{}", message);
  170. if (CodeReadProperties.failureReturnInstruction.equals(message)) {
  171. SpringUtil.getApplicationContext().publishEvent(new DeviceLog("Z1_DaSanPan_DMQ-2-27.8", deviceName, "未识别到码", "2"));
  172. plcConnectServiceRunner.getPlcServer(DeviceNameEnum.DASANPANPLC.getDeviceName()).writeByte(DaSanPanPlcEnum.ISREAD_two.getMetadata(), (byte) 2);
  173. Thread.sleep(10000L);
  174. plcConnectServiceRunner.getPlcServer(DeviceNameEnum.DASANPANPLC.getDeviceName()).writeByte(DaSanPanPlcEnum.ISREAD_two.getMetadata(),(byte) 0);
  175. } else {
  176. //获取出料位
  177. float v = plcConnectServiceRunner.getPlcServer(DeviceNameEnum.DASANPANPLC.getDeviceName()).readFloat32(DaSanPanPlcEnum.TASK_ADD_1.getMetadata());
  178. String deviceId = v == 10 ? "Z1SZ10" : "Z1SP0" + v;
  179. String batchNo = mesService.bindLotNo(deviceId, message);
  180. //读取到托盘号保存到数据库中
  181. RetroactiveNow retroactiveNow = new RetroactiveNow();
  182. retroactiveNow.setBatchNo(batchNo);
  183. retroactiveNow.setLotNo(message);
  184. retroactiveNow.setStatus("5");
  185. retroactiveNow.setDeviceId("Z1_DaSanPan_DMQ-1-27.8");
  186. retroactiveNow.setSanPanDevice(deviceId);
  187. retroactiveNowService.DataTwins(retroactiveNow);
  188. plcConnectServiceRunner.getPlcServer(DeviceNameEnum.DASANPANPLC.getDeviceName()).writeByte(DaSanPanPlcEnum.ISREAD_two.getMetadata(), (byte) 0);
  189. //添加设备日志
  190. SpringUtil.getApplicationContext().publishEvent(new DeviceLog("Z1_DaSanPan_DMQ-2-27.8", deviceName, "读码器识别到码:" + message, "1"));
  191. }
  192. }catch (Exception e){
  193. log.error("大散盘2号行车读码任务执行异常,msg:",e);
  194. SpringUtil.getApplicationContext().publishEvent(new DeviceLog("Z1_DaSanPan_DMQ-2-27.8", deviceName, "读码任务出错,msg:"+e.getMessage(), "2"));
  195. }
  196. }
  197. }