소스 검색

Merge branch 'master' of http://git.aseanbusiness.cn/qzyReal/gather-server

# Conflicts:
#	src/main/java/com/gzlh/config/SystemObject.java
#	src/main/java/com/gzlh/startup/StartupRunner.java
qzyReal 11 달 전
부모
커밋
ed5cecb88a
26개의 변경된 파일802개의 추가작업 그리고 60개의 파일을 삭제
  1. 49 5
      config.xml
  2. 47 4
      src/main/java/com/gzlh/background/client/BackgroundClientHandler.java
  3. 4 1
      src/main/java/com/gzlh/bus/CenterActionCommand.java
  4. 58 2
      src/main/java/com/gzlh/bus/EventThread.java
  5. 1 1
      src/main/java/com/gzlh/config/ModuleEnum.java
  6. 9 0
      src/main/java/com/gzlh/config/dto/SerialSetting.java
  7. 0 41
      src/main/java/com/gzlh/device/camera/controller/CameraController.java
  8. 8 0
      src/main/java/com/gzlh/device/car/action/CarAction.java
  9. 17 0
      src/main/java/com/gzlh/device/car/brand/CarBrandType.java
  10. 37 0
      src/main/java/com/gzlh/device/car/client/CarClientHandler.java
  11. 115 0
      src/main/java/com/gzlh/device/car/client/CarNettyConfig.java
  12. 12 0
      src/main/java/com/gzlh/device/car/event/CarDefaultEvent.java
  13. 21 0
      src/main/java/com/gzlh/device/car/factory/CarFactory.java
  14. 12 0
      src/main/java/com/gzlh/device/car/handler/ICarHandler.java
  15. 39 0
      src/main/java/com/gzlh/device/car/handler/impl/CarHandlerRuiDei.java
  16. 56 0
      src/main/java/com/gzlh/device/car/utils/RuiDeiPackUtils.java
  17. 10 0
      src/main/java/com/gzlh/device/led/handler/impl/LedHandlerFengLiYuan.java
  18. 19 0
      src/main/java/com/gzlh/device/plc/action/PLCAction.java
  19. 82 0
      src/main/java/com/gzlh/device/plc/client/PlcClientHandler.java
  20. 13 0
      src/main/java/com/gzlh/device/plc/event/PLCEvent.java
  21. 28 0
      src/main/java/com/gzlh/device/plc/handler/PLCHadnler.java
  22. 126 0
      src/main/java/com/gzlh/device/plc/service/PLCService.java
  23. 2 0
      src/main/java/com/gzlh/device/weighbridge/handler/impl/CommonWeighbridgeHandler.java
  24. 6 4
      src/main/java/com/gzlh/startup/StartupRunner.java
  25. 29 1
      src/main/java/com/gzlh/utils/DeviceCache.java
  26. 2 1
      src/main/java/com/gzlh/utils/FileUtils.java

+ 49 - 5
config.xml

@@ -10,6 +10,11 @@
                 <brand></brand>
                 <minKg>5000</minKg>
             </weighbridge>
+            <car>
+                <enable>false</enable>
+                <port>4002</port>
+                <brand>1000</brand>
+            </car>
             <led>
                 <enable>true</enable>
                 <port>4003</port>
@@ -25,9 +30,9 @@
                 <port>4001</port>
                 <!--输出-->
                 <out>
-                    <signalRedPoint>00</signalRedPoint>
-                    <signalGreenPoint>01</signalGreenPoint>
-                    <gatePoint>02</gatePoint>
+                    <signalRedPoint>02</signalRedPoint>
+                    <signalGreenPoint>03</signalGreenPoint>
+                    <gatePoint>00</gatePoint>
                 </out>
                 <!--状态信号-->
                 <status>
@@ -52,7 +57,12 @@
             <actionList>
                 <action>LED.LED_SHOW_CONTENT(地磅初始化)</action>
                 <action>CENTER.TIMER_SLEEP(1500)</action>
-                <action>LED.LED_SHOW_CONTENT(地磅初始化成功)</action>
+                <action>LED.LED_SHOW_CONTENT(即将称重,请停稳车辆)</action>
+                <action>CENTER.TIMER_SLEEP(3000)</action>
+                <action>LED.LED_SHOW_CONTENT(地磅称重中)</action>
+                <action>WEIGHBRIDGE.START_READ</action>
+                <action>LED.LED_SHOW_CONTENT(${weight})</action>
+                <action>CENTER.SUBMIT</action>
             </actionList>
         </event>
         <event>
@@ -73,5 +83,39 @@
                 <action>PLC.RED_LIGHT_OFF</action>
             </actionList>
         </event>
+        <event>
+            <!--通过校验,抬杆-->
+            <name>PLC.RAILING_RISE</name>
+            <actionList>
+                <action>LED.LED_SHOW_CONTENT(校验已通过)</action>
+                <action>PLC.RAILING_RISE_ON</action>
+                <action>CENTER.TIMER_SLEEP(5000)</action>
+                <action>PLC.RAILING_RISE_OFF</action>
+            </actionList>
+        </event>
+        <event>
+            <!--校验失败-->
+            <name>PLC.CHECK_FAILED</name>
+            <actionList>
+                <action>LED.LED_SHOW_CONTENT(校验失败,请退出通道)</action>
+            </actionList>
+        </event>
+        <event>
+            <!--通道重置-->
+            <name>PLC.IDLE</name>
+            <actionList>
+                <action>PLC.GREEN_LIGHT_ON</action>
+                <action>LED.LED_SHOW_CONTENT(${platNo})</action>
+                <action>LED.LED_SHOW_CONTENT(通道就绪,请通行)</action>
+                <action>CENTER.TIMER_SLEEP(5000)</action>
+                <action>PLC.GREEN_LIGHT_OFF</action>
+            </actionList>
+        </event>
+        <event>
+            <name>WEIGHBRIDGE.TIMEOUT</name>
+            <actionList>
+                <action>LED.LED_SHOW_CONTENT(地磅称重数据异常,请联系管理人员)</action>
+            </actionList>
+        </event>
     </eventList>
-</config>
+</config>

+ 47 - 4
src/main/java/com/gzlh/background/client/BackgroundClientHandler.java

@@ -1,17 +1,21 @@
 package com.gzlh.background.client;
 
 import cn.hutool.json.JSONUtil;
-import com.gzlh.background.properties.BackgroundPropertiesConfig;
 import com.gzlh.bus.EventBus;
-import com.gzlh.bus.EventDataManager;
+import com.gzlh.bus.EventConfig;
+import com.gzlh.config.ModuleEnum;
 import com.gzlh.config.SystemObject;
+import com.gzlh.config.hksdk.HCNetSDK;
+import com.gzlh.config.hksdk.HkUtils;
+import com.gzlh.config.hksdk.bo.HKCacheManager;
+import com.gzlh.device.capture.brand.CaptureBrandType;
+import com.gzlh.device.capture.properties.CapturePropertiesConfig;
 import com.gzlh.utils.DeviceCache;
 import io.netty.channel.ChannelHandler;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.SimpleChannelInboundHandler;
 import io.netty.handler.timeout.IdleStateEvent;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Value;
 
 import javax.annotation.Resource;
 import java.util.HashMap;
@@ -26,6 +30,10 @@ public class BackgroundClientHandler extends SimpleChannelInboundHandler<String>
     @Resource
     private EventBus eventBus;
 
+    @Resource
+    private HCNetSDK hcNetSDK;
+    @Resource
+    private HkUtils hkUtils;
 
     public BackgroundClientHandler(BackgroundClientNetty client) {
         this.client = client;
@@ -42,7 +50,42 @@ public class BackgroundClientHandler extends SimpleChannelInboundHandler<String>
 
     protected void sendHeartbeat(ChannelHandlerContext context) {
 //        向后台发送设备信息json字符串
-        DeviceCache.add("channelCode", SystemObject.applicationConfig.getChannelCode());
+//        获取海康摄像头连接状态
+        if (SystemObject.capturePropertiesConfig.getBrand()== CaptureBrandType.HK_BRAND.getCode()){
+            Map<String,Object> captrue = new HashMap<String,Object>();
+            captrue.put("brand",SystemObject.capturePropertiesConfig.getBrand());
+            captrue.put("host",SystemObject.capturePropertiesConfig.getHost());
+            captrue.put("port",SystemObject.capturePropertiesConfig.getPort());
+            int userId = HKCacheManager.getUserId(ModuleEnum.CAPTURE_MODULE);
+            boolean status = hkUtils.getStatus(hcNetSDK, userId);
+
+            int loginV40=0;
+            if (!status){
+                CapturePropertiesConfig capturePropertiesConfig=SystemObject.capturePropertiesConfig;
+                short port= (short) capturePropertiesConfig.getPort();
+                String ip=capturePropertiesConfig.getHost();
+                loginV40 = hkUtils.Login_V40(ip, port, capturePropertiesConfig.getUsername(), capturePropertiesConfig.getPwd(), hcNetSDK);
+            }
+            captrue.put("status",loginV40!=-1?1:0);
+            DeviceCache.put("captrue",captrue);
+        }
+
+//        Map<String,Object> led = new HashMap<String,Object>();
+//        led.put("brand",SystemObject.ledPropertiesConfig.getBrand());
+//        led.put("host",SystemObject.ledPropertiesConfig.getHost());
+//        led.put("port",SystemObject.ledPropertiesConfig.getPort());
+//        led.put("status",0);
+//        DeviceCache.add("led",led);
+
+        Map<String,Object> led = new HashMap<String,Object>();
+        led.put("brand",EventConfig.serialSetting.getLed().getBrand());
+        led.put("host",EventConfig.serialSetting.getHost());
+        led.put("port",EventConfig.serialSetting.getLed().getPort());
+        led.put("status",0);
+        DeviceCache.put("led",led);
+
+
+        DeviceCache.put("channelCode", SystemObject.applicationConfig.getChannelCode());
         String jsonStr = JSONUtil.toJsonStr(DeviceCache.getCacheMap());
         context.writeAndFlush(jsonStr);
 //        System.out.println(" sent ping msg to " + context.channel().remoteAddress());

+ 4 - 1
src/main/java/com/gzlh/bus/CenterActionCommand.java

@@ -3,6 +3,9 @@ package com.gzlh.bus;
 
 public interface CenterActionCommand {
     //现成休眠
-  String   SLEEP_COMMAND="TIMER_SLEEP";
+    String SLEEP_COMMAND = "TIMER_SLEEP";
+
+    //    提交数据
+    String SUBMIT = "SUBMIT";
 
 }

+ 58 - 2
src/main/java/com/gzlh/bus/EventThread.java

@@ -4,18 +4,23 @@ import cn.hutool.core.thread.ThreadUtil;
 import cn.hutool.core.util.NumberUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.extra.spring.SpringUtil;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import cn.hutool.json.JSONUtil;
 import com.gzlh.config.dto.SerialSetting;
 import com.gzlh.device.capture.factory.CaptureFactory;
 import com.gzlh.device.capture.properties.CapturePropertiesConfig;
 import com.gzlh.config.ModuleEnum;
 import com.gzlh.config.SystemObject;
-import com.gzlh.config.dto.EventDTO;
+import com.gzlh.device.car.factory.CarFactory;
 import com.gzlh.device.infrared.config.RedPropertiesConfig;
 import com.gzlh.device.infrared.factory.RedFactory;
 import com.gzlh.device.led.factory.LedFactory;
+import com.gzlh.device.plc.event.PLCEvent;
 import com.gzlh.device.plc.handler.PLCHadnler;
 import com.gzlh.device.weighbridge.config.WeighbridgePropertiesConfig;
 import com.gzlh.device.weighbridge.factory.WeighbridgeFactory;
+import com.gzlh.utils.DeviceCache;
 import lombok.extern.slf4j.Slf4j;
 
 import java.util.List;
@@ -38,6 +43,7 @@ public class EventThread implements Runnable{
         LedFactory ledFactory= SystemObject.ledFactory;
         RedFactory redFactory=SystemObject.redFactory;
         WeighbridgeFactory weighbridgeFactory=SystemObject.weighbridgeFactory;
+        CarFactory carFactory= SystemObject.carFactory;
         WeighbridgePropertiesConfig weighbridgePropertiesConfig=SystemObject.weighbridgePropertiesConfig;
         RedPropertiesConfig redPropertiesConfig=SystemObject.redPropertiesConfig;
         PLCHadnler plcHadnler= SpringUtil.getBean(PLCHadnler.class);
@@ -66,7 +72,10 @@ public class EventThread implements Runnable{
                 }else if (StrUtil.equals(module, ModuleEnum.PLC_MODULE.getModuleEn())) {
                     //动作属于plc
                     plcHadnler.handlerAction(command);
-                }  else if (StrUtil.equals(module, ModuleEnum.CENTER_MODULE.getModuleEn())) {
+                }else if (StrUtil.equals(module, ModuleEnum.CAR_MODULE.getModuleEn())) {
+                    //动作属于电子车牌
+                    carFactory.handler(serialSetting.getCar().getBrand()).handlerAction(command);
+                }   else if (StrUtil.equals(module, ModuleEnum.CENTER_MODULE.getModuleEn())) {
                     //动作属于中心总线
                     handlerAction(command);
                 }
@@ -85,6 +94,8 @@ public class EventThread implements Runnable{
         if (StrUtil.contains(action, CenterActionCommand.SLEEP_COMMAND)) {
             //休眠
             handlerSleep(action);
+        }else if (StrUtil.contains(action, CenterActionCommand.SUBMIT)){
+            handlerSubmit();
         }
     }
 
@@ -100,6 +111,51 @@ public class EventThread implements Runnable{
         }
     }
 
+    /**
+     * 提交数据
+     *
+     * @param
+     */
+    private void handlerSubmit() {
+        String address = SystemObject.applicationConfig.getServerUrl();
+        String api="/open/submit";
+        HttpResponse response = request(address+api, JSONUtil.toJsonStr(EventDataManager.getCacheData()));
+        EventBus eventBus= SpringUtil.getBean(EventBus.class);
+        if (response!=null&&response.getStatus()==200){
+            eventBus.startEvent(ModuleEnum.PLC_MODULE.getModuleEn()+"."+ PLCEvent.RAILING_RISE);
+        }else {
+            eventBus.startEvent(ModuleEnum.PLC_MODULE.getModuleEn()+"."+ PLCEvent.CHECK_FAILED);
+        }
+//        重置记录的设备触发时间
+        DeviceCache.resetTimeMap();
+    }
+
+    public HttpResponse request(String url,String json) {
+
+        HttpResponse res = null;
+//        url = "http://192.168.1.8:9191/open/submit";
+        long startTime = System.currentTimeMillis();
+        System.out.println(startTime);
+
+        String body = json;
+        try {
+//            System.out.printf("请求地址:%s, 请求体:%s ", url,body);
+
+            res = HttpRequest.post(url)
+                    .header("Content-Type", "application/json;character=utf-8;")
+                    .body(body)
+                    .execute();
+            String bodyResult = res.body();
+//            System.out.printf("ReqStatus:%s,返回结果:{%s} ",res.getStatus(), bodyResult);
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return res;
+    }
+
+
+
     @Override
     public void run(){
         handlerEvent(eventName);

+ 1 - 1
src/main/java/com/gzlh/config/ModuleEnum.java

@@ -14,7 +14,7 @@ public enum ModuleEnum {
     CAPTURE_MODULE("抓拍单元","CAPTURE"),
     PLC_MODULE("PLC","PLC"),
     CENTER_MODULE("action调度中心","CENTER"),
-
+    CAR_MODULE("电子车牌","CAR"),
     ;
     /**
      * 模块(硬件)中文名

+ 9 - 0
src/main/java/com/gzlh/config/dto/SerialSetting.java

@@ -17,6 +17,8 @@ public class SerialSetting implements Serializable {
     private LedDTO led;
     @JsonProperty("plc")
     private PlcDTO plc;
+    @JsonProperty("car")
+    private CarDTO car;
 
     @JsonProperty("electron")
     private ElectronSetting electron;
@@ -45,6 +47,13 @@ public class SerialSetting implements Serializable {
     }
     @Data
     @NoArgsConstructor
+    public static class CarDTO{
+        private Boolean enable;
+        private int port;
+        private Integer brand;
+    }
+    @Data
+    @NoArgsConstructor
     public static class PlcDTO{
         private Boolean enable;
         private int port;

+ 0 - 41
src/main/java/com/gzlh/device/camera/controller/CameraController.java

@@ -2,17 +2,12 @@ package com.gzlh.device.camera.controller;
 
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.XmlUtil;
-import cn.hutool.http.HttpRequest;
-import cn.hutool.http.HttpResponse;
-import cn.hutool.json.JSONUtil;
 import com.gzlh.bus.EventDataManager;
 import com.gzlh.config.SystemObject;
 import com.gzlh.device.camera.factory.CameraFactory;
 import com.gzlh.device.camera.properties.CameraPropertiesConfig;
-import com.gzlh.entity.ReqBO;
 import com.gzlh.utils.FileUtils;
 import org.springframework.beans.factory.annotation.Value;
-import org.springframework.http.HttpHeaders;
 import org.springframework.util.StringUtils;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
@@ -87,42 +82,6 @@ public class CameraController {
         EventDataManager.cacheData("boxFImgList",fList);
         EventDataManager.cacheData("boxBImgList",bList);
 
-//        // TODO: 2023/11/10
-//        cameraFactory.handler(cameraPropertiesConfig.getBrand()).handlerAction("");
 
-        request("",JSONUtil.toJsonStr(EventDataManager.getCacheData()));
-
-    }
-
-
-    public void request(String url,String json) {
-
-        HttpHeaders headers = new HttpHeaders();
-        url = "http://192.168.1.8:9191/open/submit";
-        long startTime = System.currentTimeMillis();
-        System.out.println(startTime);
-
-        String body = json;
-//        String method = Thread.currentThread().getStackTrace()[1].getMethodName();
-        try {
-//            System.out.printf("%s/请求地址:%s,请求头:%s,  请求体:%s ", method,url, headers, body);
-
-            System.out.println();
-//            log.info("【{}/{}】请求地址:{},请求头:{},  请求体:{} ", OperateTypeEnum.OPERATE_TYPE_2.desc, logContent, url, headers, body);
-            HttpResponse res = HttpRequest.post(url)
-                    .header("Content-Type", "application/json;character=utf-8;")
-                    .body(body)
-                    .execute();
-            String bodyResult = res.body();
-            System.out.printf("ReqStatus:%s,返回结果:{%s} ",res.getStatus(), bodyResult);
-
-//            if(200 == res.getStatus()){
-//
-//            }
-
-        } catch (Exception e) {
-
-        }
     }
-
 }

+ 8 - 0
src/main/java/com/gzlh/device/car/action/CarAction.java

@@ -0,0 +1,8 @@
+package com.gzlh.device.car.action;
+
+public interface CarAction {
+    /**
+     * 展示内容
+     */
+    String READ="READ";
+}

+ 17 - 0
src/main/java/com/gzlh/device/car/brand/CarBrandType.java

@@ -0,0 +1,17 @@
+package com.gzlh.device.car.brand;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public enum CarBrandType {
+
+    SHENZHEN_RUIDEI(1000,"深圳市瑞得智能技术有限公司"),
+
+    ;
+
+
+    private int code;
+    private String brand;
+}

+ 37 - 0
src/main/java/com/gzlh/device/car/client/CarClientHandler.java

@@ -0,0 +1,37 @@
+package com.gzlh.device.car.client;
+
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@ChannelHandler.Sharable
+public class CarClientHandler extends SimpleChannelInboundHandler<String> {
+
+    private CarNettyConfig carNettyConfig;
+
+    public CarClientHandler(CarNettyConfig carNettyConfig) {
+        this.carNettyConfig = carNettyConfig;
+    }
+
+    @Override
+    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
+        log.info("Car 客户端收到消息:" + msg);
+
+    }
+
+    @Override
+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+        log.error("car 客户端 连接断开,进行重连");
+        carNettyConfig.connect();
+    }
+
+    @Override
+    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+        cause.printStackTrace();
+        ctx.close();
+    }
+
+}
+

+ 115 - 0
src/main/java/com/gzlh/device/car/client/CarNettyConfig.java

@@ -0,0 +1,115 @@
+package com.gzlh.device.car.client;
+
+import com.gzlh.bus.EventConfig;
+import com.gzlh.config.dto.SerialSetting;
+import com.gzlh.config.netty.NettyDecoder;
+import com.gzlh.utils.XorUtils;
+import io.netty.bootstrap.Bootstrap;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.*;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import io.netty.handler.codec.string.StringEncoder;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.TimeUnit;
+
+@Configuration
+@Slf4j
+public class CarNettyConfig {
+
+
+
+    @Autowired
+    private CarClientHandler carClientHandler;
+
+    private Channel channel;
+
+    @Bean("carBootstrap")
+    public Bootstrap bootstrap() {
+        SerialSetting serialSetting= EventConfig.serialSetting;
+        String host = serialSetting.getHost();
+        int port = serialSetting.getCar().getPort();
+        if (serialSetting.getCar().getEnable()) {
+            log.info("初始化 car:{},{}", host, port);
+        }
+        EventLoopGroup group = new NioEventLoopGroup();
+        return new Bootstrap()
+                .group(group)
+                .channel(NioSocketChannel.class)
+                .remoteAddress(host, port)
+                .option(ChannelOption.SO_KEEPALIVE, true)
+                .handler(new ChannelInitializer<SocketChannel>() {
+                    @Override
+                    protected void initChannel(SocketChannel ch) {
+                        try {
+                            ChannelPipeline pipeline = ch.pipeline();
+                            pipeline.addLast( new NettyDecoder());
+                            pipeline.addLast( new StringEncoder(StandardCharsets.UTF_8));
+                            pipeline.addLast("handler", carClientHandler);
+                        } catch (Exception e) {
+                            log.info("error connect:{}", e.getMessage());
+                        }
+                    }
+                });
+    }
+
+    @Bean("carClientHandler")
+    public CarClientHandler carClientHandler() {
+        return new CarClientHandler(this);
+    }
+
+    public void connect() {
+        SerialSetting serialSetting= EventConfig.serialSetting;
+        String host = serialSetting.getHost();
+        int port = serialSetting.getCar().getPort();
+        ChannelFuture future = bootstrap().connect();
+        future.addListener((ChannelFutureListener) future1 -> {
+            if (future1.isSuccess()) {
+                channel = future1.channel();
+                log.info("car 串口服务器连接成功,{},{}", host, port);
+            } else {
+                log.error("-------------car 连接服务器失败,{},{}-----------,进行重连", host, port);
+                future1.channel().eventLoop().schedule(this::connect, 5, TimeUnit.SECONDS);
+            }
+        });
+        try {
+            future.channel().closeFuture().sync();
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void send(String message) {
+        if (channel != null && channel.isActive()) {
+            ByteBuf bufff = Unpooled.buffer();
+            bufff.writeBytes(XorUtils.hexString2Bytes(message));
+            channel.writeAndFlush(bufff);
+        } else {
+            log.error("未建立连接,无法发送消息");
+        }
+    }
+
+    public void close() {
+        if (channel != null) {
+            channel.close();
+        }
+    }
+    private byte[] hexStringToByteArray(String hexString) {
+
+        int len = hexString.length();
+        byte[] data = new byte[len / 2];
+        for (int i = 0; i < len; i += 2) {
+            data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
+                    + Character.digit(hexString.charAt(i+1), 16));
+        }
+        return data;
+    }
+}
+

+ 12 - 0
src/main/java/com/gzlh/device/car/event/CarDefaultEvent.java

@@ -0,0 +1,12 @@
+package com.gzlh.device.car.event;
+
+/**
+ * Car内置事件
+ */
+public interface CarDefaultEvent {
+    /**
+     * 超时事件
+     */
+    String TIMEOUT = "TIMEOUT";
+    String READ = "READ";
+}

+ 21 - 0
src/main/java/com/gzlh/device/car/factory/CarFactory.java

@@ -0,0 +1,21 @@
+package com.gzlh.device.car.factory;
+
+
+
+import com.gzlh.device.car.handler.ICarHandler;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class CarFactory {
+    @Autowired
+    private List<ICarHandler>handlers;
+
+    public ICarHandler handler(int code){
+       return handlers.stream().filter(h->h.brandType().getCode()==code)
+                .findAny().orElseThrow(()->new IllegalArgumentException("不支持交互"));
+    }
+
+}

+ 12 - 0
src/main/java/com/gzlh/device/car/handler/ICarHandler.java

@@ -0,0 +1,12 @@
+package com.gzlh.device.car.handler;
+
+import com.gzlh.device.car.brand.CarBrandType;
+
+public interface ICarHandler {
+
+    CarBrandType brandType();
+
+    void sendMsg(String content, String param);
+
+    void handlerAction(String action);
+}

+ 39 - 0
src/main/java/com/gzlh/device/car/handler/impl/CarHandlerRuiDei.java

@@ -0,0 +1,39 @@
+package com.gzlh.device.car.handler.impl;
+
+import cn.hutool.core.util.StrUtil;
+import com.gzlh.device.car.action.CarAction;
+import com.gzlh.device.car.brand.CarBrandType;
+import com.gzlh.device.car.client.CarNettyConfig;
+import com.gzlh.device.car.handler.ICarHandler;
+import com.gzlh.device.car.utils.RuiDeiPackUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+@Service
+@Slf4j
+public class CarHandlerRuiDei implements ICarHandler {
+    @Resource
+    CarNettyConfig carNettyConfig;
+
+    @Override
+    public CarBrandType brandType() {
+        return CarBrandType.SHENZHEN_RUIDEI;
+    }
+
+    @Override
+    public void sendMsg(String content, String param) {
+        log.info("发送电子车牌消息:{}",content);
+        String msgHex= RuiDeiPackUtils.build(content,param);
+        log.info("数据包:{}",msgHex);
+        carNettyConfig.send(msgHex);
+    }
+
+    @Override
+    public void handlerAction(String action) {
+        if (StrUtil.contains(action, CarAction.READ)) {
+            sendMsg("","");
+        }
+    }
+}

+ 56 - 0
src/main/java/com/gzlh/device/car/utils/RuiDeiPackUtils.java

@@ -0,0 +1,56 @@
+package com.gzlh.device.car.utils;
+
+import com.gzlh.utils.WordHandlerUtils;
+import com.gzlh.utils.XorUtils;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class RuiDeiPackUtils {
+    private static final String bootCode = "40";
+
+    /**
+     * 构建
+     *
+     * @param command       命令
+     * @param commandParam  命令参数
+     * @return 起始字40 长度(从[命令]到[校验和]最后字节)
+     *
+     */
+    public static String build(String command, String commandParam) {
+        //消息的16进制
+        String msgHex = WordHandlerUtils.msgToASCII(commandParam);
+
+        String content = command + commandParam;
+        int packLength = content.length();
+//        计算长度,校验和长度固定为1
+        String packLengthHex = Integer.toHexString((packLength / 2) + 1);
+        if (packLengthHex.length() == 1) {
+            packLengthHex = "0" + packLengthHex;
+        }
+        //长度->内容
+        String dataContent = bootCode + packLengthHex + content;
+        String checkSum = checkSum(dataContent);
+        String str = dataContent + checkSum;
+        System.out.println(str);
+        return str;
+    }
+
+    public static String checkSum(String dataContent) {
+        String checkSum = "";
+        byte[] bytes = XorUtils.hexString2Bytes(dataContent);
+        byte sum = 0;
+        for (byte b : bytes) {
+            sum += b;
+        }
+//        和取补去进位,转为十六进制字符串
+        checkSum = String.format("%02x", (~sum + 1 & 0xff)).toUpperCase();
+//        System.out.println("TCC-Hex:"+checkSum);
+        return checkSum;
+    }
+
+    public static void main(String[] args) {
+        RuiDeiPackUtils.build("FE","");
+    }
+
+
+}

+ 10 - 0
src/main/java/com/gzlh/device/led/handler/impl/LedHandlerFengLiYuan.java

@@ -41,6 +41,16 @@ public class LedHandlerFengLiYuan implements ILedHandler {
                 LedOptions ledOptions=new LedOptions();
                 ledOptions.setColor("05").setLine("02").setShowType("0B");
                 sendMsg(carNo,ledOptions);
+            }else  if (StrUtil.contains(action,"weight")){
+                String weight= String.format("%.0f", EventDataManager.getCacheData().getWeight());
+                LedOptions ledOptions=new LedOptions();
+                ledOptions.setColor("04").setLine("03").setShowType("0B");
+                sendMsg(weight,ledOptions);
+            }else{
+                String content = action.substring(action.indexOf("(")+1, action.indexOf(")"));
+                LedOptions ledOptions=new LedOptions();
+                ledOptions.setColor("03").setLine("04").setShowType("00");
+                sendMsg(content,ledOptions);
             }
         }
     }

+ 19 - 0
src/main/java/com/gzlh/device/plc/action/PLCAction.java

@@ -9,4 +9,23 @@ public interface PLCAction {
      * 龙灯灭
      */
     String RED_LIGHT_OFF="RED_LIGHT_OFF";
+    /**
+     * 绿灯亮
+     */
+    String GREEN_LIGHT_ON="GREEN_LIGHT_ON";
+    /**
+     * 绿灯灭
+     */
+    String GREEN_LIGHT_OFF="GREEN_LIGHT_OFF";
+    /**
+     * 抬杆
+     */
+    String RAILING_RISE_ON="RAILING_RISE_ON";
+    String RAILING_RISE_OFF="RAILING_RISE_OFF";
+    /**
+     * 落杆
+     */
+    String RAILING_FALL_ON="RAILING_FALL_ON";
+    String RAILING_FALL_OFF="RAILING_FALL_OFF";
+
 }

+ 82 - 0
src/main/java/com/gzlh/device/plc/client/PlcClientHandler.java

@@ -1,16 +1,25 @@
 package com.gzlh.device.plc.client;
 
+import com.gzlh.bus.EventConfig;
+import com.gzlh.config.dto.SerialSetting;
+import com.gzlh.device.plc.service.PLCService;
+import com.gzlh.utils.DeviceCache;
 import io.netty.channel.ChannelHandler;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.SimpleChannelInboundHandler;
 import lombok.extern.slf4j.Slf4j;
 
+import java.lang.reflect.Field;
+import java.util.*;
+
 @Slf4j
 @ChannelHandler.Sharable
 public class PlcClientHandler extends SimpleChannelInboundHandler<String> {
 
     private PlcNettyConfig ledNettyConfig;
 
+    private PLCService plcService = new PLCService();
+
     public PlcClientHandler(PlcNettyConfig ledNettyConfig) {
         this.ledNettyConfig = ledNettyConfig;
     }
@@ -18,6 +27,79 @@ public class PlcClientHandler extends SimpleChannelInboundHandler<String> {
     @Override
     protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
         log.info("PLC 客户端收到消息:" + msg);
+        DeviceCache.put("plc",1);
+        String result = Integer.toBinaryString(Integer.parseInt(msg.substring(6, 8),16));
+
+        String oldPlcInfo = DeviceCache.getPlcStatus();
+        String newPlcInfo = String.format("%8s", result).replace(" ", "0");
+//        将plc的设备信息补到8存入缓存
+        DeviceCache.setPlcStatus(newPlcInfo);
+
+//        设备信息发生变化时进入
+        if (oldPlcInfo!=null&&!newPlcInfo.equals(oldPlcInfo)){
+            SerialSetting.PlcDTO.StatusDTO status = EventConfig.serialSetting.getPlc().getStatus();
+
+            String newStr = new StringBuffer(newPlcInfo).reverse().toString();
+            String oldStr = new StringBuffer(oldPlcInfo).reverse().toString();
+
+            for (int i=0;i<newStr.length();i++){
+//                第i位设备的值
+                String value = String.valueOf(newStr.charAt(i));
+//                设备被触发
+                if (value.equals("1")&&!value.equals(String.valueOf(oldStr.charAt(i)))){
+//                    记录时间 配置的设备地址为map的key
+                    for (Field field:status.getClass().getDeclaredFields()){
+                        field.setAccessible(true);
+                        if (Integer.parseInt(String.valueOf(field.get(status)))==i){
+//                            String name = fields[i].getName();
+                            DeviceCache.putTime((String) field.get(status),new Date());
+                            break;
+                        }
+                    }
+//                    前红外触发时调用方法
+                    if (String.valueOf(i).equals(status.getFRedPoint())){
+                        new Thread(()-> {
+                            try {
+                                plcService.fRedTrigger(newPlcInfo);
+                            } catch (InterruptedException e) {
+                                e.printStackTrace();
+                            }
+                        }).start();
+                    }
+//                    雷达外触发时调用方法
+                    if (String.valueOf(i).equals(status.getRadarPoint())){
+                        new Thread(()-> {
+                            try {
+                                plcService.radarTrigger();
+                            } catch (InterruptedException e) {
+                                e.printStackTrace();
+                            }
+                        }).start();
+                    }
+//                    上到位触发时调用方法
+                    if (String.valueOf(i).equals(status.getUpPoint())){
+                        new Thread(()-> {
+                            try {
+                                plcService.upTrigger();
+                            } catch (InterruptedException e) {
+                                e.printStackTrace();
+                            }
+                        }).start();
+                    }
+                }
+            }
+        }
+
+
+
+        //        for (int i=0;i<result.length();i++){
+//            String status = String.valueOf(result.charAt((result.length() - 1) - i));
+//            if (status.equals("1")){
+//                list.add(i);
+//            }
+//        }
+//        System.out.println(list);
+//        log.info("PLC 客户端收到消息:" + msg);
 
     }
 

+ 13 - 0
src/main/java/com/gzlh/device/plc/event/PLCEvent.java

@@ -0,0 +1,13 @@
+package com.gzlh.device.plc.event;
+
+/**
+ * led内置事件
+ */
+public interface PLCEvent {
+
+    String RAILING_RISE = "RAILING_RISE";
+
+    String CHECK_FAILED = "CHECK_FAILED";
+
+    String IDLE = "IDLE";
+}

+ 28 - 0
src/main/java/com/gzlh/device/plc/handler/PLCHadnler.java

@@ -36,6 +36,34 @@ public class PLCHadnler {
             log.info("plc发送消息:{}",command);
             String packData= ModbusUtils.buildRequestPacket(command);
             plcNettyConfig.send(packData);
+        }else if (StrUtil.equals(action, PLCAction.GREEN_LIGHT_ON)){
+            //亮绿灯
+            String greenPoint= serialSetting.getPlc().getOut().getSignalGreenPoint();
+            String command= COMMAND_PREFIX+greenPoint+COMMAND_ON;
+            log.info("plc发送消息:{}",command);
+            String packData= ModbusUtils.buildRequestPacket(command);
+            plcNettyConfig.send(packData);
+        }else if (StrUtil.equals(action, PLCAction.GREEN_LIGHT_OFF)){
+            //灭绿灯
+            String greenPoint= serialSetting.getPlc().getOut().getSignalGreenPoint();
+            String command= COMMAND_PREFIX+greenPoint+COMMAND_OFF;
+            log.info("plc发送消息:{}",command);
+            String packData= ModbusUtils.buildRequestPacket(command);
+            plcNettyConfig.send(packData);
+        }else if (StrUtil.equals(action, PLCAction.RAILING_RISE_ON)){
+            //抬杆
+            String gatePoint= serialSetting.getPlc().getOut().getGatePoint();
+            String command= COMMAND_PREFIX+gatePoint+COMMAND_ON;
+            log.info("plc发送消息:{}",command);
+            String packData= ModbusUtils.buildRequestPacket(command);
+            plcNettyConfig.send(packData);
+        }else if (StrUtil.equals(action, PLCAction.RAILING_RISE_OFF)){
+            //抬杆关闭
+            String gatePoint= serialSetting.getPlc().getOut().getGatePoint();
+            String command= COMMAND_PREFIX+gatePoint+COMMAND_OFF;
+            log.info("plc发送消息:{}",command);
+            String packData= ModbusUtils.buildRequestPacket(command);
+            plcNettyConfig.send(packData);
         }
     }
 

+ 126 - 0
src/main/java/com/gzlh/device/plc/service/PLCService.java

@@ -0,0 +1,126 @@
+package com.gzlh.device.plc.service;
+
+import cn.hutool.extra.spring.SpringUtil;
+import com.gzlh.bus.EventBus;
+import com.gzlh.bus.EventConfig;
+import com.gzlh.bus.EventDataManager;
+import com.gzlh.config.ModuleEnum;
+import com.gzlh.config.dto.SerialSetting;
+import com.gzlh.device.plc.event.PLCEvent;
+import com.gzlh.device.weighbridge.event.WeighbridgeEvent;
+import com.gzlh.utils.DeviceCache;
+
+import java.util.Date;
+
+public class PLCService {
+    public void fRedTrigger(String plcInfo) throws InterruptedException {
+        EventBus eventBus = SpringUtil.getBean(EventBus.class);
+        //向总线发送抓拍到车牌事件
+        SerialSetting.PlcDTO.StatusDTO status = EventConfig.serialSetting.getPlc().getStatus();
+//        将plc设备信息的字符串反转
+        plcInfo = new StringBuffer(plcInfo).reverse().toString();
+        String newStatus = null;
+        String oldFRed = String.valueOf(plcInfo.charAt(Integer.parseInt(status.getFRedPoint())));
+        String newFRed = null;
+        boolean bool = true;
+        while (bool) {
+            newStatus = new StringBuffer(DeviceCache.getPlcStatus()).reverse().toString();
+            newFRed = String.valueOf(newStatus.charAt(Integer.parseInt(status.getFRedPoint())));
+//            前红外信息发生变化之后再继续
+            if (oldFRed.equals(newFRed)) {
+                Thread.sleep(2000);
+            } else {
+                bool = false;
+            }
+        }
+
+        String BRed = String.valueOf(newStatus.charAt(Integer.parseInt(status.getBRedPoint())));
+        String radar = String.valueOf(newStatus.charAt(Integer.parseInt(status.getRadarPoint())));
+
+//        车辆处于前后红外之间(外)
+        if (newFRed.equals("0") && BRed.equals("0")) {
+            Date fRedTime = DeviceCache.getTime(status.getFRedPoint());
+            Date radarTime = DeviceCache.getTime(status.getRadarPoint());
+
+//            雷达时间小于前红外时间为进,车辆前后红外之间
+            if (radarTime.before(fRedTime)) {
+                eventBus.startEvent(ModuleEnum.WEIGHBRIDGE_MODULE.getModuleEn() + "." + WeighbridgeEvent.READ);
+            }
+        }
+    }
+
+
+    public void radarTrigger() throws InterruptedException {
+        EventBus eventBus = SpringUtil.getBean(EventBus.class);
+        //向总线发送抓拍到车牌事件
+        SerialSetting.PlcDTO.StatusDTO status = EventConfig.serialSetting.getPlc().getStatus();
+//        将plc设备信息的字符串反转
+        String newStatus = null;
+        String newRadar = null;
+        boolean bool = true;
+        while (bool) {
+//            反转当前设备信息
+            newStatus = new StringBuffer(DeviceCache.getPlcStatus()).reverse().toString();
+            newRadar = String.valueOf(newStatus.charAt(Integer.parseInt(status.getRadarPoint())));
+//            雷达信息发生变化之后再继续
+            if ("0".equals(newRadar)) {
+                bool = false;
+            } else {
+                Thread.sleep(2000);
+            }
+        }
+
+        String BRed = String.valueOf(newStatus.charAt(Integer.parseInt(status.getBRedPoint())));
+        String radar = String.valueOf(newStatus.charAt(Integer.parseInt(status.getRadarPoint())));
+
+//        设置str为只有栏杆下到位的状态
+        String str = "00000000";
+        StringBuilder sb = new StringBuilder(str);
+        sb.setCharAt(Integer.parseInt(status.getDownPoint()), '1');
+        str = sb.toString();
+        System.out.println(str);
+//        判断当前PLC状态
+        if (str.equals(newStatus)) {
+            Date fRedTime = DeviceCache.getTime(status.getFRedPoint());
+            Date radarTime = DeviceCache.getTime(status.getRadarPoint());
+//           雷达时间大于前红外时间为退,并且只有下到位触发,判断车辆不在通道内,触发通道空闲状态
+            if (radarTime.after(fRedTime)) {
+                EventDataManager.cleanData();
+                eventBus.startEvent(ModuleEnum.PLC_MODULE.getModuleEn() + "." + PLCEvent.IDLE);
+            }
+        }
+    }
+
+    public void upTrigger() throws InterruptedException {
+        EventBus eventBus = SpringUtil.getBean(EventBus.class);
+        //向总线发送抓拍到车牌事件
+        SerialSetting.PlcDTO.StatusDTO status = EventConfig.serialSetting.getPlc().getStatus();
+//        将plc设备信息的字符串反转
+        String newStatus = null;
+        String downPoint = null;
+        boolean bool = true;
+        while (bool) {
+//            反转当前设备信息
+            newStatus = new StringBuffer(DeviceCache.getPlcStatus()).reverse().toString();
+            downPoint = String.valueOf(newStatus.charAt(Integer.parseInt(status.getDownPoint())));
+//            落杆后结束循环
+            if ("1".equals(downPoint)) {
+                bool = false;
+            } else {
+                Thread.sleep(2000);
+            }
+        }
+
+//        设置只有栏杆下到位的状态
+        String downOnly = "00000000";
+        StringBuilder sb = new StringBuilder(downOnly);
+        sb.setCharAt(Integer.parseInt(status.getDownPoint()), '1');
+        downOnly = sb.toString();
+//        System.out.println(downOnly);
+//        判断当前PLC状态
+        if (downOnly.equals(newStatus)) {
+            EventDataManager.cleanData();
+            eventBus.startEvent(ModuleEnum.PLC_MODULE.getModuleEn() + "." + PLCEvent.IDLE);
+        }
+    }
+}

+ 2 - 0
src/main/java/com/gzlh/device/weighbridge/handler/impl/CommonWeighbridgeHandler.java

@@ -2,6 +2,7 @@ package com.gzlh.device.weighbridge.handler.impl;
 
 import cn.hutool.core.thread.ThreadUtil;
 import cn.hutool.extra.spring.SpringUtil;
+import com.gzlh.bus.EventDataManager;
 import com.gzlh.config.ApplicationConfig;
 import com.gzlh.config.ModuleEnum;
 import com.gzlh.bus.EventBus;
@@ -69,6 +70,7 @@ public class CommonWeighbridgeHandler {
             //上传地磅数据
             String channelName = applicationConfig.getChannelName();
             String serverUrl = applicationConfig.getServerUrl();
+            EventDataManager.cacheData("weight",averaWeight);
         }
     }
 }

+ 6 - 4
src/main/java/com/gzlh/startup/StartupRunner.java

@@ -17,13 +17,16 @@ import com.gzlh.config.hksdk.HCNetSDK;
 import com.gzlh.config.hksdk.HkUtils;
 import com.gzlh.config.hksdk.bo.HKCacheManager;
 import com.gzlh.device.electron.client.ElectronNettyConfig;
+import com.gzlh.device.car.client.CarNettyConfig;
 import com.gzlh.device.led.client.LedNettyConfig;
 import com.gzlh.device.infrared.client.RedNettyConfig;
 import com.gzlh.device.plc.client.PlcNettyConfig;
 import com.gzlh.device.weighbridge.client.WeighbridgeNettyConfig;
+import com.gzlh.utils.WordHandlerUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.boot.CommandLineRunner;
+import org.springframework.core.env.PropertyResolver;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
@@ -43,19 +46,18 @@ public class StartupRunner implements CommandLineRunner {
     private PlcNettyConfig plcNettyConfig;
     @Resource
     private ElectronNettyConfig electronNettyConfig;
+    @Resource
+    private CarNettyConfig carNettyConfig;
 
     @Resource
     private BackgroundPropertiesConfig backgroundPropertiesConfig;
     @Resource
     private BackgroundClientNetty backgroundClientNetty;
-    @Value("${application.channel-code}")
-    private String channelCode;
 
     @Resource
     private HkUtils hkUtils;
     @Resource
     private HCNetSDK hcNetSDK;
-
     @Override
     public void run(String... args) throws Exception {
         SerialSetting serialSetting=EventConfig.serialSetting;
@@ -72,7 +74,7 @@ public class StartupRunner implements CommandLineRunner {
             ThreadUtil.execute(() -> electronNettyConfig.connect());
         }
         if (backgroundPropertiesConfig.isEnable()) {
-            //ThreadUtil.execute(() -> backgroundClientNetty.connect());
+            ThreadUtil.execute(() -> backgroundClientNetty.connect());
         }
         if (SystemObject.capturePropertiesConfig.isEnable()){
             CapturePropertiesConfig capturePropertiesConfig=SystemObject.capturePropertiesConfig;

+ 29 - 1
src/main/java/com/gzlh/utils/DeviceCache.java

@@ -1,13 +1,36 @@
 package com.gzlh.utils;
 
 
+import java.util.Date;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
 public class DeviceCache {
     private static Map<String,Object> map = new ConcurrentHashMap<String,Object>();
+    private static Map<String, Date> plcTimeMap = new ConcurrentHashMap<String,Date>();
 
-    public static void add(String k,Object v){
+    static String plcStatus = null;
+
+    public static void setPlcStatus(String status){
+        plcStatus=status;
+    }
+
+    public static String getPlcStatus(){
+        return plcStatus;
+    }
+
+    public static void putTime(String k, Date v){
+        plcTimeMap.put(k,v);
+    }
+    public static Date getTime(String k){
+        return plcTimeMap.get(k);
+    }
+    public static void resetTimeMap(){
+        plcTimeMap=new ConcurrentHashMap<String,Date>();;
+    }
+
+
+    public static void put(String k, Object v){
         map.put(k,v);
     }
 
@@ -22,4 +45,9 @@ public class DeviceCache {
     public static Map<String,Object> getCacheMap(){
         return map;
     }
+    public static Map<String, Date> getTimeMap(){
+        return plcTimeMap;
+    }
+
+
 }

+ 2 - 1
src/main/java/com/gzlh/utils/FileUtils.java

@@ -32,6 +32,7 @@ public class FileUtils {
             String hour =""+ calendar.get(Calendar.HOUR_OF_DAY);
             String minute =""+calendar.get(Calendar.MINUTE);
             String second =""+calendar.get(Calendar.SECOND);
+            String millisecond = ""+calendar.get(Calendar.MILLISECOND);
             if (hour.length()<2){
                 hour="0"+hour;
             }
@@ -41,7 +42,7 @@ public class FileUtils {
             if (second.length()<2){
                 second="0"+second;
             }
-            String path=savePath+"/"+hour+minute+second+suffix;
+            String path=savePath+"/"+hour+minute+second+millisecond+suffix;
             out = new FileOutputStream(path);
 
             byte[] buffer = new byte[1024];