From 5078ee97b67412856f26145275bf71ae0ee504e0 Mon Sep 17 00:00:00 2001 From: yiming Date: Mon, 21 Mar 2022 13:28:59 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9Esick=E6=89=AB=E7=A0=81?= =?UTF-8?q?=E6=9E=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web/config/ConfigProperties.java | 7 ++ .../web/controller/SensorController.java | 31 +++++++ .../com/zhehekeji/web/entity/SensorGun.java | 20 +++++ .../zhehekeji/web/mapper/SensorGunMapper.java | 7 ++ .../zhehekeji/web/service/InitService.java | 3 +- .../web/service/sick/SickClientHandler.java | 47 +++++++++++ .../web/service/sick/SickConnMap.java | 45 +++++++++++ .../web/service/sick/SickDecoder.java | 65 +++++++++++++++ .../web/service/sick/SickEncoder.java | 20 +++++ .../web/service/sick/SickNettyClient.java | 80 +++++++++++++++++++ .../service/sick/SickNettyClientFilter.java | 39 +++++++++ .../web/service/sick/SickSocket.java | 70 ++++++++++++++++ web/src/main/resources/application-dev.yml | 8 +- web/src/main/resources/logback-spring.xml | 26 ++++++ 14 files changed, 465 insertions(+), 3 deletions(-) create mode 100644 web/src/main/java/com/zhehekeji/web/controller/SensorController.java create mode 100644 web/src/main/java/com/zhehekeji/web/entity/SensorGun.java create mode 100644 web/src/main/java/com/zhehekeji/web/mapper/SensorGunMapper.java create mode 100644 web/src/main/java/com/zhehekeji/web/service/sick/SickClientHandler.java create mode 100644 web/src/main/java/com/zhehekeji/web/service/sick/SickConnMap.java create mode 100644 web/src/main/java/com/zhehekeji/web/service/sick/SickDecoder.java create mode 100644 web/src/main/java/com/zhehekeji/web/service/sick/SickEncoder.java create mode 100644 web/src/main/java/com/zhehekeji/web/service/sick/SickNettyClient.java create mode 100644 web/src/main/java/com/zhehekeji/web/service/sick/SickNettyClientFilter.java create mode 100644 web/src/main/java/com/zhehekeji/web/service/sick/SickSocket.java diff --git a/web/src/main/java/com/zhehekeji/web/config/ConfigProperties.java b/web/src/main/java/com/zhehekeji/web/config/ConfigProperties.java index e81a76c..ed1b9a1 100644 --- a/web/src/main/java/com/zhehekeji/web/config/ConfigProperties.java +++ b/web/src/main/java/com/zhehekeji/web/config/ConfigProperties.java @@ -33,6 +33,8 @@ public class ConfigProperties { private LightSource lightSource; + private Sensor sensor; + @Data public static class CameraConfig{ @@ -70,4 +72,9 @@ public class ConfigProperties { private Integer type; private String info; } + + @Data + public static class Sensor{ + private Integer type; + } } diff --git a/web/src/main/java/com/zhehekeji/web/controller/SensorController.java b/web/src/main/java/com/zhehekeji/web/controller/SensorController.java new file mode 100644 index 0000000..d72caca --- /dev/null +++ b/web/src/main/java/com/zhehekeji/web/controller/SensorController.java @@ -0,0 +1,31 @@ +package com.zhehekeji.web.controller; + +import com.alibaba.fastjson.JSONObject; +import com.zhehekeji.common.util.HttpUtil; +import com.zhehekeji.core.pojo.Result; +import com.zhehekeji.core.util.Assert; +import com.zhehekeji.web.pojo.IndexVO; +import com.zhehekeji.web.service.sick.SickConnMap; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.io.IOException; + +@Api( tags = "传感器") +@RequestMapping(value = "/sensor") +@RestController() +@Slf4j +public class SensorController { + + @GetMapping("/start") + @ApiOperation(value = "sick扫码枪开始扫") + public Result userCenter() { + SickConnMap.write(1); + return Result.success(); + } +} diff --git a/web/src/main/java/com/zhehekeji/web/entity/SensorGun.java b/web/src/main/java/com/zhehekeji/web/entity/SensorGun.java new file mode 100644 index 0000000..9288fe8 --- /dev/null +++ b/web/src/main/java/com/zhehekeji/web/entity/SensorGun.java @@ -0,0 +1,20 @@ +package com.zhehekeji.web.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; + +@Data +public class SensorGun { + + @TableId(type = IdType.AUTO) + private Integer id; + + private Integer streetId; + + private Integer direction; + + private String ip; + + private Integer port; +} diff --git a/web/src/main/java/com/zhehekeji/web/mapper/SensorGunMapper.java b/web/src/main/java/com/zhehekeji/web/mapper/SensorGunMapper.java new file mode 100644 index 0000000..3d22053 --- /dev/null +++ b/web/src/main/java/com/zhehekeji/web/mapper/SensorGunMapper.java @@ -0,0 +1,7 @@ +package com.zhehekeji.web.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zhehekeji.web.entity.SensorGun; + +public interface SensorGunMapper extends BaseMapper { +} diff --git a/web/src/main/java/com/zhehekeji/web/service/InitService.java b/web/src/main/java/com/zhehekeji/web/service/InitService.java index 75b08b2..c11e4b8 100644 --- a/web/src/main/java/com/zhehekeji/web/service/InitService.java +++ b/web/src/main/java/com/zhehekeji/web/service/InitService.java @@ -10,9 +10,11 @@ import com.zhehekeji.web.lib.joyware.JoywareCameraControlModuleImpl; import com.zhehekeji.web.lib.joyware.JoywareLoginModuleImpl; import com.zhehekeji.web.lib.joyware.NetSDKLib; import com.zhehekeji.web.mapper.CameraMapper; +import com.zhehekeji.web.mapper.SensorGunMapper; import com.zhehekeji.web.mapper.StreetMapper; import com.zhehekeji.web.service.ksec.KsecNettyClient; import com.zhehekeji.web.service.robotic.NettyClient; +import com.zhehekeji.web.service.sick.SickNettyClient; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; @@ -107,7 +109,6 @@ public class InitService implements ApplicationRunner { } } TaskDelayExecutor.runMp4DownloadExecutor(); - } class loginThread extends Thread{ diff --git a/web/src/main/java/com/zhehekeji/web/service/sick/SickClientHandler.java b/web/src/main/java/com/zhehekeji/web/service/sick/SickClientHandler.java new file mode 100644 index 0000000..1a86379 --- /dev/null +++ b/web/src/main/java/com/zhehekeji/web/service/sick/SickClientHandler.java @@ -0,0 +1,47 @@ +package com.zhehekeji.web.service.sick; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import lombok.extern.slf4j.Slf4j; + +/** + * 与PLC心跳 处理 + * + * @author Administrator + * + */ +@Slf4j +public class SickClientHandler extends ChannelInboundHandlerAdapter { + + private SickNettyClient nettyClient; + + private Integer sensorId; + + public SickClientHandler(Integer sensorId, SickNettyClient nettyClient){ + + this.nettyClient = nettyClient; + this.sensorId = sensorId; + } + + /** + * 建立连接时 + */ + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + log.info("sensorId:{}连接成功",sensorId); + SickConnMap.conn(sensorId,ctx); + ctx.fireChannelActive(); + } + + /** + * 关闭连接时 + */ + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + log.info("sensorId:{} closed",sensorId); + SickConnMap.disConn(sensorId); + log.info(" streetId reconnect......"); + //nettyClient.reconnect(sensorId); + } + +} diff --git a/web/src/main/java/com/zhehekeji/web/service/sick/SickConnMap.java b/web/src/main/java/com/zhehekeji/web/service/sick/SickConnMap.java new file mode 100644 index 0000000..194dd93 --- /dev/null +++ b/web/src/main/java/com/zhehekeji/web/service/sick/SickConnMap.java @@ -0,0 +1,45 @@ +package com.zhehekeji.web.service.sick; + +import io.netty.channel.ChannelHandlerContext; +import lombok.extern.slf4j.Slf4j; + +import java.util.HashMap; +import java.util.Map; + +@Slf4j +public class SickConnMap { + + private static Map connChanel = new HashMap<>(); + + + + public static void conn(Integer id,ChannelHandlerContext channel){ + connChanel.put(id,channel); + } + + public static void disConn(Integer id){ + connChanel.remove(id); + } + + public static ChannelHandlerContext getChannel(Integer id){ + return connChanel.get(id); + } + + /** + * 向sick发送开始扫码指令 + * return 是否发送成功 + * @param sensorId + */ + public static Boolean write(Integer sensorId){ + if(connChanel.get(sensorId) != null){ + try { + connChanel.get(sensorId).channel().writeAndFlush("start"); + return true; + }catch (Exception e){ + log.error(""+e); + } + } + return false; + } + +} diff --git a/web/src/main/java/com/zhehekeji/web/service/sick/SickDecoder.java b/web/src/main/java/com/zhehekeji/web/service/sick/SickDecoder.java new file mode 100644 index 0000000..b148279 --- /dev/null +++ b/web/src/main/java/com/zhehekeji/web/service/sick/SickDecoder.java @@ -0,0 +1,65 @@ +package com.zhehekeji.web.service.sick; + +import com.zhehekeji.web.service.PlcService; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.LineBasedFrameDecoder; +import lombok.extern.slf4j.Slf4j; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.nio.charset.StandardCharsets; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + + +@Slf4j +public class SickDecoder extends LineBasedFrameDecoder { + + private static final Logger tcpLogger = LoggerFactory.getLogger("sick"); + + private static Map OCRMap = new ConcurrentHashMap<>(); + + private PlcService plcService; + private Integer sensorId; + + public SickDecoder(PlcService plcService,Integer sensorId) { + super(1000); + this.plcService = plcService; + this.sensorId = sensorId; + } + + /** + * 解析TCP数据包 + * + * @param ctx + * @param in + * @return + * @throws Exception + */ + @Override + protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { + in = (ByteBuf) super.decode(ctx, in); + if (in == null) { + return null; + } + + String code = in.toString(StandardCharsets.UTF_8); + code = code.replace("\\n",""); + if(!code.equals("NoRead")){ + System.out.println(code); + OCRMap.put(sensorId,code); + //todo 更改stock + }else { + log.warn("no read"); + OCRMap.put(sensorId,null); + } + + in.release(); + ctx.channel().close(); + return null; + } + + + +} diff --git a/web/src/main/java/com/zhehekeji/web/service/sick/SickEncoder.java b/web/src/main/java/com/zhehekeji/web/service/sick/SickEncoder.java new file mode 100644 index 0000000..55f3f21 --- /dev/null +++ b/web/src/main/java/com/zhehekeji/web/service/sick/SickEncoder.java @@ -0,0 +1,20 @@ +package com.zhehekeji.web.service.sick; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToByteEncoder; + +import java.nio.charset.StandardCharsets; + +public class SickEncoder extends MessageToByteEncoder { + + @Override + protected void encode(ChannelHandlerContext ctx, String msg, ByteBuf out) throws Exception { + if(msg == null){ + throw new Exception("msg is null"); + } + out.writeBytes(msg.getBytes(StandardCharsets.UTF_8)); + + + } +} diff --git a/web/src/main/java/com/zhehekeji/web/service/sick/SickNettyClient.java b/web/src/main/java/com/zhehekeji/web/service/sick/SickNettyClient.java new file mode 100644 index 0000000..f67efe7 --- /dev/null +++ b/web/src/main/java/com/zhehekeji/web/service/sick/SickNettyClient.java @@ -0,0 +1,80 @@ +package com.zhehekeji.web.service.sick; + +import com.zhehekeji.web.entity.SensorGun; +import com.zhehekeji.web.mapper.SensorGunMapper; +import com.zhehekeji.web.service.PlcService; +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.nio.NioSocketChannel; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import javax.annotation.Resource; + +@Slf4j +@Component +public class SickNettyClient { + + private static EventLoopGroup group = new NioEventLoopGroup(); + + @Resource + private SensorGunMapper sensorGunMapper; + @Resource + private PlcService plcService; + + /** + * 重连最大次数 + */ + private static int RECONNECT_NUM = 5; + + public void createClient(SensorGun sensorGun) throws InterruptedException { + if (StringUtils.isEmpty(sensorGun.getIp()) || sensorGun.getPort() == null) { + return; + } + Bootstrap client = new Bootstrap(); + client.group(group); + client.channel(NioSocketChannel.class); + client.handler(new SickNettyClientFilter(sensorGun.getId(),plcService,this)); + // 连接服务端 + Channel channel = client.connect(sensorGun.getIp(), sensorGun.getPort()).sync().channel(); + channel.writeAndFlush("start"); + } + + /** + * 断线重连 尝试 RECONNECT_NUM 次 + * + * @param sensorId + */ + public void reconnect(Integer sensorId) { + Boolean isConnected = false; + int num = 0; + SensorGun sensorGun = sensorGunMapper.selectById(sensorId); + if (sensorGun == null) { + log.error("reconnect ,sensorGun is null ,id:{}", sensorId); + return; + } + while (num < RECONNECT_NUM && !isConnected) { + try { + createClient(sensorGun); + } catch (Exception e) { + //没连上 继续 + log.error("sensorGun reconnect error num:{}", num); + try { + Thread.sleep(5000); + } catch (InterruptedException ex) { + ex.printStackTrace(); + } + num++; + continue; + } + isConnected = true; + } + if (isConnected) { + log.info("sensorGun reconnect success"); + } else { + log.error("sensorGun reconnect error .sensorGunId:{},reconnect num:{},ip:{},port:{}", sensorId, num,sensorGun.getIp(),sensorGun.getPort()); + } + } +} diff --git a/web/src/main/java/com/zhehekeji/web/service/sick/SickNettyClientFilter.java b/web/src/main/java/com/zhehekeji/web/service/sick/SickNettyClientFilter.java new file mode 100644 index 0000000..ab775b1 --- /dev/null +++ b/web/src/main/java/com/zhehekeji/web/service/sick/SickNettyClientFilter.java @@ -0,0 +1,39 @@ +package com.zhehekeji.web.service.sick; + +import com.zhehekeji.web.service.PlcService; +import com.zhehekeji.web.service.robotic.*; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.socket.SocketChannel; +import io.netty.handler.timeout.IdleStateHandler; + +import java.util.concurrent.TimeUnit; + +/** + * 客户端过滤器,编解码和心跳的设置 + * + * @author Administrator + * + */ +public class SickNettyClientFilter extends ChannelInitializer { + + private Integer sensorId; + + private PlcService plcService; + + private SickNettyClient nettyClient; + + public SickNettyClientFilter(Integer sensorId, PlcService plcService, SickNettyClient nettyClient){ + this.sensorId = sensorId; + this.plcService = plcService; + this.nettyClient = nettyClient; + } + + @Override + protected void initChannel(SocketChannel ch) throws Exception { + ChannelPipeline ph = ch.pipeline(); + ph.addLast(new SickDecoder(this.plcService,this.sensorId)); + ph.addLast(new SickClientHandler(sensorId,nettyClient)); + ph.addLast(new SickEncoder()); + } +} diff --git a/web/src/main/java/com/zhehekeji/web/service/sick/SickSocket.java b/web/src/main/java/com/zhehekeji/web/service/sick/SickSocket.java new file mode 100644 index 0000000..a246e12 --- /dev/null +++ b/web/src/main/java/com/zhehekeji/web/service/sick/SickSocket.java @@ -0,0 +1,70 @@ +package com.zhehekeji.web.service.sick; + +import lombok.extern.slf4j.Slf4j; + +import java.io.*; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.nio.charset.StandardCharsets; + +/** + * sick扫码枪 + */ +@Slf4j +public class SickSocket { + + public static void main(String[] args) { + String code = readOCR("192.168.8.236", 2002); + System.out.println(code); + } + + public static String readOCR(String ip,int port){ + Socket socket = new Socket(); + String code = null; + OutputStream os = null; + InputStream is = null; + try { + socket.connect(new InetSocketAddress(ip,port),3000); + os = socket.getOutputStream(); + writeCmd(os); + is = socket.getInputStream(); + code = read(is); + } catch (IOException e) { + log.error("sick time out,ip:{},info:{}",ip,e); + }finally { + if(os != null){ + try { + os.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if(is != null){ + try { + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + try { + socket.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + return code; + } + } + + private static void writeCmd(OutputStream os) throws IOException { + String startCmd = "start"; + byte[]bytes = startCmd.getBytes(StandardCharsets.UTF_8); + os.write(bytes); + } + + private static String read(InputStream inStream) throws IOException { + BufferedReader bd = new BufferedReader(new InputStreamReader(inStream)); + return bd.readLine(); + } + +} diff --git a/web/src/main/resources/application-dev.yml b/web/src/main/resources/application-dev.yml index 7ae63a3..8367a7b 100644 --- a/web/src/main/resources/application-dev.yml +++ b/web/src/main/resources/application-dev.yml @@ -7,14 +7,14 @@ spring: maxWait: 60000 minEvictableIdleTimeMillis: 300000 minIdle: 15 - password: Leaper@123 + password: ming1234 poolPreparedStatements: true testOnBorrow: true testOnReturn: false testWhileIdle: false timeBetweenEvictionRunsMillis: 60000 type: com.alibaba.druid.pool.DruidDataSource - url: jdbc:mysql://115.236.65.98:12004/lia_duoji?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8 + url: jdbc:mysql://212.129.248.185:3306/lia_duoji?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8 username: root validationQuery: SELECT 1 FROM DUAL # --------本服务端口号 @@ -54,3 +54,7 @@ videoStyleConfig: lightSource: type: 1 info: "{'num':2,'index':0}" +# -----------扫码枪 +# ------------type 1: sick +sensor: + type: 1 diff --git a/web/src/main/resources/logback-spring.xml b/web/src/main/resources/logback-spring.xml index 577c0e1..278dbcf 100644 --- a/web/src/main/resources/logback-spring.xml +++ b/web/src/main/resources/logback-spring.xml @@ -103,11 +103,37 @@ + + ${LOG_HOME}/${logName}-sick-tcp.log + + ${LOG_HOME}/${logName}-sick-tcp-%d{yyyy-MM-dd}.%i.log + 30 + + 10MB + + + + + %d %p (%file:%line\)- %m%n + + UTF-8 + + + info + ACCEPT + DENY + + + + + + +