Browse Source

led、plc对接

qzyReal 1 year ago
parent
commit
c756f491de
28 changed files with 672 additions and 101 deletions
  1. 44 3
      config.xml
  2. 2 2
      src/main/java/com/gzlh/GatherServerApplication.java
  3. 11 4
      src/main/java/com/gzlh/api/OpenApi.java
  4. 0 7
      src/main/java/com/gzlh/bus/EventBus.java
  5. 38 0
      src/main/java/com/gzlh/bus/EventConfig.java
  6. 11 14
      src/main/java/com/gzlh/bus/EventThread.java
  7. 1 6
      src/main/java/com/gzlh/config/SystemObject.java
  8. 8 0
      src/main/java/com/gzlh/config/dto/ApplicationConfigDTO.java
  9. 64 0
      src/main/java/com/gzlh/config/dto/SerialSetting.java
  10. 2 1
      src/main/java/com/gzlh/device/led/brand/LedBrandType.java
  11. 14 9
      src/main/java/com/gzlh/device/led/client/LedNettyConfig.java
  12. 2 1
      src/main/java/com/gzlh/device/led/handler/ILedHandler.java
  13. 47 0
      src/main/java/com/gzlh/device/led/handler/impl/LedHandlerFengLiYuan.java
  14. 7 1
      src/main/java/com/gzlh/device/led/handler/impl/LedHandlerYangBandV4d2.java
  15. 0 15
      src/main/java/com/gzlh/device/led/properties/LedPropertiesConfig.java
  16. 7 0
      src/main/java/com/gzlh/device/led/utils/CRC16.java
  17. 72 0
      src/main/java/com/gzlh/device/led/utils/FengLiYuanPackUtils.java
  18. 46 0
      src/main/java/com/gzlh/device/led/utils/LedOptions.java
  19. 12 0
      src/main/java/com/gzlh/device/plc/action/PLCAction.java
  20. 37 0
      src/main/java/com/gzlh/device/plc/client/PlcClientHandler.java
  21. 108 0
      src/main/java/com/gzlh/device/plc/client/PlcNettyConfig.java
  22. 42 0
      src/main/java/com/gzlh/device/plc/handler/PLCHadnler.java
  23. 23 0
      src/main/java/com/gzlh/device/plc/job/SearchJob.java
  24. 10 22
      src/main/java/com/gzlh/startup/StartupRunner.java
  25. 44 0
      src/main/java/com/gzlh/utils/ModbusUtils.java
  26. 6 3
      src/main/java/com/gzlh/utils/WordHandlerUtils.java
  27. 12 11
      src/main/java/com/gzlh/utils/XorUtils.java
  28. 2 2
      src/main/resources/application.yml

+ 44 - 3
config.xml

@@ -1,6 +1,45 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
 <config>
+    <sysConfig>
+        <serialSetting>
+            <host>192.168.1.254</host>
+            <weighbridge>
+                <enable>false</enable>
+                <port>4005</port>
+                <brand></brand>
+                <minKg>5000</minKg>
+            </weighbridge>
+            <led>
+                <enable>true</enable>
+                <port>4003</port>
+                <brand>2000</brand>
+            </led>
+            <plc>
+                <enable>true</enable>
+                <port>4001</port>
+                <!--输出-->
+                <out>
+                    <signalRedPoint>00</signalRedPoint>
+                    <signalGreenPoint>01</signalGreenPoint>
+                    <gatePoint>02</gatePoint>
+                </out>
+                <!--状态信号-->
+                <status>
+                    <!--上到位-->
+                    <upPoint>0</upPoint>
+                    <!--下到位-->
+                    <downPoint>1</downPoint>
+                    <!--雷达-->
+                    <radarPoint>2</radarPoint>
+                    <!--前红外-->
+                    <fRedPoint>3</fRedPoint>
+                    <!--后红外-->
+                    <bRedPoint>4</bRedPoint>
+                </status>
+            </plc>
+        </serialSetting>
+    </sysConfig>
     <eventList>
         <event>
             <name>WEIGHBRIDGE.READ</name>
@@ -20,11 +59,13 @@
             </actionList>
         </event>
         <event>
+            <!--识别到车牌-->
             <name>CAPTURE.CAPTURE_CAR_NO</name>
             <actionList>
-                <action>LED.LED_SHOW_CONTENT(识别到车牌${platNo})</action>
-                <action>CENTER.TIMER_SLEEP(10000)</action>
-                <action>CAPTURE.UPLOAD_CAR_NO</action>
+                <action>LED.LED_SHOW_CONTENT(${platNo})</action>
+                <action>PLC.RED_LIGHT_ON</action>
+                <action>CENTER.TIMER_SLEEP(5000)</action>
+                <action>PLC.RED_LIGHT_OFF</action>
             </actionList>
         </event>
     </eventList>

+ 2 - 2
src/main/java/com/gzlh/GatherServerApplication.java

@@ -1,5 +1,6 @@
 package com.gzlh;
 
+import com.gzlh.bus.EventConfig;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -18,9 +19,8 @@ import java.util.Properties;
 @Slf4j
 public class GatherServerApplication  {
 
-
-
     public static void main(String[] args) {
+        EventConfig.initConfig();
         Properties properties = System.getProperties();
         String rootPath = properties.getProperty("user.dir");
         SpringApplication application = new SpringApplication(GatherServerApplication.class);

+ 11 - 4
src/main/java/com/gzlh/api/OpenApi.java

@@ -1,9 +1,12 @@
 package com.gzlh.api;
 
+import com.gzlh.bus.EventConfig;
 import com.gzlh.config.ModuleEnum;
 import com.gzlh.bus.EventBus;
 import com.gzlh.config.SystemObject;
+import com.gzlh.config.dto.SerialSetting;
 import com.gzlh.device.led.event.LedDefaultEvent;
+import com.gzlh.device.led.utils.LedOptions;
 import com.gzlh.utils.ResultJson;
 import com.gzlh.device.weighbridge.event.WeighbridgeEvent;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -21,10 +24,14 @@ public class OpenApi {
     EventBus eventBus;
 
     @RequestMapping("test")
-    public ResultJson test(){
-       // eventBus.startEvent(ModuleEnum.LED_MODULE.getModuleEn()+"."+ LedDefaultEvent.READ);
-       // eventBus.startEvent(ModuleEnum.WEIGHBRIDGE_MODULE.getModuleEn()+"."+ WeighbridgeEvent.READ);
-        SystemObject.ledFactory.handler(SystemObject.ledPropertiesConfig.getBrand()).sendMsg("你好");
+    public ResultJson test(String msg,String line,String showType,String color){
+        eventBus.startEvent(ModuleEnum.LED_MODULE.getModuleEn()+"."+ LedDefaultEvent.READ);
+        eventBus.startEvent(ModuleEnum.WEIGHBRIDGE_MODULE.getModuleEn()+"."+ WeighbridgeEvent.READ);
+        System.out.println();
+        SerialSetting.LedDTO ledDTO= EventConfig.serialSetting.getLed();
+        LedOptions ledOptions=new LedOptions();
+        ledOptions.setLine(line).setShowType(showType).setColor(color);
+        SystemObject.ledFactory.handler(ledDTO.getBrand()).sendMsg(msg,ledOptions);
         return ResultJson.success();
     }
 }

+ 0 - 7
src/main/java/com/gzlh/bus/EventBus.java

@@ -10,12 +10,6 @@ import java.util.List;
 @Component
 @Slf4j
 public class EventBus {
-    private List<EventDTO> eventDTOList;
-
-
-    public void setEventDTOList(List<EventDTO> eventDTOList) {
-        this.eventDTOList = eventDTOList;
-    }
 
     /**
      * 触发事件
@@ -23,7 +17,6 @@ public class EventBus {
      */
     public void startEvent(String eventName){
         EventThread thread = new EventThread(eventName);
-        thread.setEventDTOList(eventDTOList);
         ThreadUtil.execute(thread);
     }
 }

+ 38 - 0
src/main/java/com/gzlh/bus/EventConfig.java

@@ -0,0 +1,38 @@
+package com.gzlh.bus;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.XML;
+import com.gzlh.config.dto.ApplicationConfigDTO;
+import com.gzlh.config.dto.EventDTO;
+import com.gzlh.config.dto.SerialSetting;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.File;
+import java.util.List;
+import java.util.Properties;
+
+@Data
+@Slf4j
+public class EventConfig {
+    public static List<EventDTO> eventDTOList;
+    public static SerialSetting serialSetting;
+
+    public static void initConfig() {
+        Properties properties = System.getProperties();
+        String rootPath = properties.getProperty("user.dir");
+        String separator = File.separator;
+        String configFile = rootPath + separator + "config.xml";
+        if (!FileUtil.exist(configFile)) {
+            log.error("配置文件不存在:{}", configFile);
+            return;
+        }
+        String content = FileUtil.readUtf8String(configFile);
+        JSONObject result = XML.toJSONObject(content);
+        log.info("result:{}",result.toJSONString(0));
+        ApplicationConfigDTO configDTO = result.toBean(ApplicationConfigDTO.class);
+        eventDTOList=configDTO.getConfig().getEventList().getEvent();
+        serialSetting=configDTO.getConfig().getSysConfig().getSerialSetting();
+    }
+}

+ 11 - 14
src/main/java/com/gzlh/bus/EventThread.java

@@ -3,6 +3,8 @@ package com.gzlh.bus;
 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 com.gzlh.config.dto.SerialSetting;
 import com.gzlh.device.capture.factory.CaptureFactory;
 import com.gzlh.device.capture.properties.CapturePropertiesConfig;
 import com.gzlh.config.ModuleEnum;
@@ -11,7 +13,7 @@ import com.gzlh.config.dto.EventDTO;
 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.led.properties.LedPropertiesConfig;
+import com.gzlh.device.plc.handler.PLCHadnler;
 import com.gzlh.device.weighbridge.config.WeighbridgePropertiesConfig;
 import com.gzlh.device.weighbridge.factory.WeighbridgeFactory;
 import lombok.extern.slf4j.Slf4j;
@@ -20,37 +22,29 @@ import java.util.List;
 
 @Slf4j
 public class EventThread implements Runnable{
-    private List<EventDTO> eventDTOList;
     private String eventName;
 
-
-
     public EventThread(String eventName) {
         this.eventName=eventName;
     }
 
-    public void setEventDTOList(List<EventDTO> eventDTOList) {
-        this.eventDTOList = eventDTOList;
-    }
-    public void setEventName(String eventName) {
-        this.eventName = eventName;
-    }
     /**
      * 处理事件
      *
      * @param eventName 服务.事件名 比如led.ready
      */
     public void handlerEvent(String eventName) {
+        SerialSetting serialSetting=EventConfig.serialSetting;
         LedFactory ledFactory= SystemObject.ledFactory;
         RedFactory redFactory=SystemObject.redFactory;
         WeighbridgeFactory weighbridgeFactory=SystemObject.weighbridgeFactory;
         WeighbridgePropertiesConfig weighbridgePropertiesConfig=SystemObject.weighbridgePropertiesConfig;
         RedPropertiesConfig redPropertiesConfig=SystemObject.redPropertiesConfig;
-        LedPropertiesConfig ledPropertiesConfig=SystemObject.ledPropertiesConfig;
+        PLCHadnler plcHadnler= SpringUtil.getBean(PLCHadnler.class);
         CaptureFactory captureFactory=SystemObject.captureFactory;
         CapturePropertiesConfig capturePropertiesConfig=SystemObject.capturePropertiesConfig;
         log.info("event:{}", eventName);
-        eventDTOList.stream().filter(eventDTO -> StrUtil.equals(eventName, eventDTO.getName()))
+        EventConfig.eventDTOList.stream().filter(eventDTO -> StrUtil.equals(eventName, eventDTO.getName()))
                 .findFirst().ifPresent(eventDTO -> {
             List<String> actionList = eventDTO.getActionList().getAction();
             //依次执行动作
@@ -62,14 +56,17 @@ public class EventThread implements Runnable{
                     redFactory.handler(redPropertiesConfig.getBrand()).handlerAction(command);
                 } else if (StrUtil.equals(module, ModuleEnum.LED_MODULE.getModuleEn())) {
                     //动作属于led
-                    ledFactory.handler(ledPropertiesConfig.getBrand()).handlerAction(command);
+                    ledFactory.handler(serialSetting.getLed().getBrand()).handlerAction(command);
                 } else if (StrUtil.equals(module, ModuleEnum.WEIGHBRIDGE_MODULE.getModuleEn())) {
                     //动作属于地磅
                     weighbridgeFactory.handler(weighbridgePropertiesConfig.getBrand()).handlerAction(command);
                 }else if (StrUtil.equals(module, ModuleEnum.CAPTURE_MODULE.getModuleEn())) {
                     //动作属于抓拍单元--车牌识别
                     captureFactory.handler(capturePropertiesConfig.getBrand()).handlerAction(command);
-                } else if (StrUtil.equals(module, ModuleEnum.CENTER_MODULE.getModuleEn())) {
+                }else if (StrUtil.equals(module, ModuleEnum.PLC_MODULE.getModuleEn())) {
+                    //动作属于plc
+                    plcHadnler.handlerAction(command);
+                }  else if (StrUtil.equals(module, ModuleEnum.CENTER_MODULE.getModuleEn())) {
                     //动作属于中心总线
                     handlerAction(command);
                 }

+ 1 - 6
src/main/java/com/gzlh/config/SystemObject.java

@@ -5,7 +5,6 @@ import com.gzlh.device.capture.properties.CapturePropertiesConfig;
 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.led.properties.LedPropertiesConfig;
 import com.gzlh.device.weighbridge.config.WeighbridgePropertiesConfig;
 import com.gzlh.device.weighbridge.factory.WeighbridgeFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -24,7 +23,6 @@ public class SystemObject {
     public static WeighbridgePropertiesConfig weighbridgePropertiesConfig;
 
     public static LedFactory ledFactory;
-    public static LedPropertiesConfig ledPropertiesConfig;
 
     public static CaptureFactory captureFactory;
 
@@ -60,10 +58,7 @@ public class SystemObject {
     void setLedFactory(LedFactory ledFactory) {
         SystemObject.ledFactory = ledFactory;
     }
-    @Autowired
-    void setLedPropertiesConfig(LedPropertiesConfig ledPropertiesConfig) {
-        SystemObject.ledPropertiesConfig = ledPropertiesConfig;
-    }
+
     @Autowired
    void setCaptureFactory(CaptureFactory captureFactory) {
         SystemObject.captureFactory = captureFactory;

+ 8 - 0
src/main/java/com/gzlh/config/dto/ApplicationConfigDTO.java

@@ -17,6 +17,8 @@ public class ApplicationConfigDTO implements Serializable {
     @NoArgsConstructor
     @Data
     public static class ConfigDTO {
+        @JsonProperty("configList")
+        private ConfigListDTO sysConfig;
         @JsonProperty("eventList")
         private EventListDTO eventList;
         @NoArgsConstructor
@@ -24,7 +26,13 @@ public class ApplicationConfigDTO implements Serializable {
         public static class EventListDTO {
             @JsonProperty("event")
             private List<EventDTO> event;
+        }
 
+        @Data
+        @NoArgsConstructor
+        public static class ConfigListDTO{
+            @JsonProperty("serialSetting")
+            private SerialSetting serialSetting;
         }
     }
 }

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

@@ -0,0 +1,64 @@
+package com.gzlh.config.dto;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+@Data
+@Accessors(chain = true)
+public class SerialSetting implements Serializable {
+    @JsonProperty("host")
+    private String host;
+    @JsonProperty("weighbridge")
+    private Weighbridge weighbridge;
+    @JsonProperty("led")
+    private LedDTO led;
+    @JsonProperty("plc")
+    private PlcDTO plc;
+
+    @Data
+    @NoArgsConstructor
+    public static class Weighbridge{
+        private Boolean enable;
+        private int port;
+        private Integer brand;
+        private Integer minKg=1000;
+    }
+    @Data
+    @NoArgsConstructor
+    public static class LedDTO{
+        private Boolean enable;
+        private int port;
+        private Integer brand;
+    }
+    @Data
+    @NoArgsConstructor
+    public static class PlcDTO{
+        private Boolean enable;
+        private int port;
+        private Integer brand;
+        private OutDTO out;
+        private StatusDTO status;
+        @Data
+        @Accessors(chain = true)
+        public static class OutDTO{
+            private String signalRedPoint;
+            private String signalGreenPoint;
+            private String gatePoint;
+        }
+        @Data
+        @Accessors(chain = true)
+        public static class StatusDTO{
+            private String upPoint;
+            private String downPoint;
+            private String radarPoint;
+            private String fRedPoint;
+            private String bRedPoint;
+        }
+    }
+
+
+
+}

+ 2 - 1
src/main/java/com/gzlh/device/led/brand/LedBrandType.java

@@ -7,7 +7,8 @@ import lombok.Getter;
 @AllArgsConstructor
 public enum  LedBrandType {
 
-    SHANGHAI_YANGBAND_BX(1000,"上海仰邦科技股份有限公司BX-5(M)K/6K(YY)-V4.2")
+    SHANGHAI_YANGBAND_BX(1000,"上海仰邦科技股份有限公司BX-5(M)K/6K(YY)-V4.2"),
+    FEND_LI_YUAN(2000,"丰利源"),
 
     ;
 

+ 14 - 9
src/main/java/com/gzlh/device/led/client/LedNettyConfig.java

@@ -1,7 +1,9 @@
 package com.gzlh.device.led.client;
 
+import com.gzlh.bus.EventConfig;
+import com.gzlh.config.dto.SerialSetting;
 import com.gzlh.config.netty.NettyDecoder;
-import com.gzlh.device.led.properties.LedPropertiesConfig;
+import com.gzlh.utils.XorUtils;
 import io.netty.bootstrap.Bootstrap;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
@@ -26,8 +28,7 @@ import java.util.concurrent.TimeUnit;
 @Slf4j
 public class LedNettyConfig {
 
-    @Resource
-    private LedPropertiesConfig ledConfig;
+
 
     @Autowired
     private LedClientHandler ledClientHandler;
@@ -36,9 +37,10 @@ public class LedNettyConfig {
 
     @Bean("ledBootstrap")
     public Bootstrap bootstrap() {
-        String host = ledConfig.getHost();
-        int port = ledConfig.getPort();
-        if (ledConfig.isEnable()) {
+        SerialSetting serialSetting= EventConfig.serialSetting;
+        String host = serialSetting.getHost();
+        int port = serialSetting.getLed().getPort();
+        if (serialSetting.getLed().getEnable()) {
             log.info("初始化 led:{},{}", host, port);
         }
         EventLoopGroup group = new NioEventLoopGroup();
@@ -68,8 +70,9 @@ public class LedNettyConfig {
     }
 
     public void connect() {
-        String host = ledConfig.getHost();
-        int port = ledConfig.getPort();
+        SerialSetting serialSetting= EventConfig.serialSetting;
+        String host = serialSetting.getHost();
+        int port = serialSetting.getLed().getPort();
         ChannelFuture future = bootstrap().connect();
         future.addListener((ChannelFutureListener) future1 -> {
             if (future1.isSuccess()) {
@@ -89,7 +92,9 @@ public class LedNettyConfig {
 
     public void send(String message) {
         if (channel != null && channel.isActive()) {
-            channel.writeAndFlush("010f00000010020900e470");
+            ByteBuf bufff = Unpooled.buffer();
+            bufff.writeBytes(XorUtils.hexString2Bytes(message));
+            channel.writeAndFlush(bufff);
         } else {
             log.error("未建立连接,无法发送消息");
         }

+ 2 - 1
src/main/java/com/gzlh/device/led/handler/ILedHandler.java

@@ -1,12 +1,13 @@
 package com.gzlh.device.led.handler;
 
 import com.gzlh.device.led.brand.LedBrandType;
+import com.gzlh.device.led.utils.LedOptions;
 
 public interface ILedHandler {
 
     LedBrandType brandType();
 
-    void sendMsg( String content);
+    void sendMsg(String content, LedOptions options);
 
     void handlerAction(String action);
 }

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

@@ -0,0 +1,47 @@
+package com.gzlh.device.led.handler.impl;
+
+import cn.hutool.core.util.StrUtil;
+import com.gzlh.bus.EventDataManager;
+import com.gzlh.device.led.action.LedAction;
+import com.gzlh.device.led.brand.LedBrandType;
+import com.gzlh.device.led.client.LedNettyConfig;
+import com.gzlh.device.led.handler.ILedHandler;
+import com.gzlh.device.led.utils.FengLiYuanPackUtils;
+import com.gzlh.device.led.utils.LedOptions;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+@Service
+@Slf4j
+public class LedHandlerFengLiYuan implements ILedHandler {
+    @Resource
+    LedNettyConfig ledNettyConfig;
+
+    @Override
+    public LedBrandType brandType() {
+        return LedBrandType.FEND_LI_YUAN;
+    }
+
+    @Override
+    public void sendMsg(String content, LedOptions options) {
+        log.info("丰利源发送led消息:{}",content);
+       String msgHex= FengLiYuanPackUtils.build(content,options);
+        log.info("数据包:{}",msgHex);
+        ledNettyConfig.send(msgHex);
+    }
+
+    @Override
+    public void handlerAction(String action) {
+        if (StrUtil.contains(action, LedAction.LED_SHOW_CONTENT)) {
+            //展示内容
+            if (StrUtil.contains(action,"platNo")){
+                String carNo= EventDataManager.getCacheData().getCarNo();
+                LedOptions ledOptions=new LedOptions();
+                ledOptions.setColor("05").setLine("02").setShowType("0B");
+                sendMsg(carNo,ledOptions);
+            }
+        }
+    }
+}

+ 7 - 1
src/main/java/com/gzlh/device/led/handler/impl/LedHandlerYangBandV4d2.java

@@ -1,9 +1,14 @@
 package com.gzlh.device.led.handler.impl;
 
+import cn.hutool.core.util.StrUtil;
+import com.gzlh.bus.EventConfig;
+import com.gzlh.bus.EventDataManager;
+import com.gzlh.device.led.action.LedAction;
 import com.gzlh.device.led.brand.LedBrandType;
 import com.gzlh.device.led.client.LedNettyConfig;
 import com.gzlh.device.led.handler.ILedHandler;
 import com.gzlh.device.led.utils.ColorConver;
+import com.gzlh.device.led.utils.LedOptions;
 import com.gzlh.device.led.utils.YangBandPackage;
 import com.gzlh.device.infrared.brand.RedBrandType;
 import com.gzlh.utils.WordHandlerUtils;
@@ -28,7 +33,7 @@ public class LedHandlerYangBandV4d2 implements ILedHandler {
     }
 
     @Override
-    public void sendMsg(String content) {
+    public void sendMsg(String content, LedOptions ledOptions) {
         log.info(RedBrandType.SHANGHAI_YANGBAND_BX.getBrand() + "发送消息:{}", content);
         String pack = YangBandPackage.buildPackage(ColorConver.NU_TO_HEX.get(1) + WordHandlerUtils.msgToASCII(content));
         log.info(RedBrandType.SHANGHAI_YANGBAND_BX.getBrand() + "转换后的数据:{}", pack);
@@ -41,6 +46,7 @@ public class LedHandlerYangBandV4d2 implements ILedHandler {
      */
     @Override
     public void handlerAction(String action) {
+
         log.info("action:{}",action);
     }
 }

+ 0 - 15
src/main/java/com/gzlh/device/led/properties/LedPropertiesConfig.java

@@ -1,15 +0,0 @@
-package com.gzlh.device.led.properties;
-
-import lombok.Data;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.context.annotation.Configuration;
-
-@ConfigurationProperties(prefix = "led")
-@Configuration
-@Data
-public class LedPropertiesConfig {
-    private String host;
-    private int port;
-    private int brand;
-    private boolean enable;
-}

+ 7 - 0
src/main/java/com/gzlh/device/led/utils/CRC16.java

@@ -1,5 +1,7 @@
 package com.gzlh.device.led.utils;
 
+import cn.hutool.core.util.HexUtil;
+
 public class CRC16 {
     public static String crc16(int[] data, int size) {
         char crc = 0x0;
@@ -35,5 +37,10 @@ public class CRC16 {
         return sb.toString();
     }
 
+    public static void main(String[] args) {
+        System.out.println(HexUtil.toHex(51));
+        System.out.println(Integer.toHexString(51));
+    }
+
 
 }

+ 72 - 0
src/main/java/com/gzlh/device/led/utils/FengLiYuanPackUtils.java

@@ -0,0 +1,72 @@
+package com.gzlh.device.led.utils;
+
+import cn.hutool.core.util.StrUtil;
+import com.gzlh.utils.WordHandlerUtils;
+import com.gzlh.utils.XorUtils;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class FengLiYuanPackUtils {
+    private static final String HEADER_HEX="F501";
+    /**
+     * 构建
+     * @param message 发送的信息
+     * @param line 行号
+     * @return 起始字 F501 长度(从[屏地址]到[数据]最后字节) 屏地址 00 命令 01 发送 01 数据 总包校
+     * 验
+     */
+    public static String build(String message, LedOptions options){
+        //消息的15进制
+         String msgHex=  WordHandlerUtils.msgToASCII(message);
+         int msgLength= msgHex.length();
+         String msgLenHex=Integer.toHexString(msgLength/2);
+         if (msgLenHex.length()==1){
+             msgLenHex="0"+msgLenHex;
+         }
+         String line= options.getLine();
+         if (StrUtil.isEmpty(line)){
+             line="02";
+         }
+         String showType= options.getShowType();
+        if (StrUtil.isEmpty(showType)){
+            showType="00";
+        }
+        String color= options.getColor();
+        if (StrUtil.isEmpty(color)){
+            color="01";
+        }
+        //内容=行号(01->08)+显示方式(00左移入)+日期显示方式(00固定信息)+速度(00->02)+颜色(01红色)+固定信息长度(xx)+message
+        String content=line+showType+"0001"+color+msgLenHex+msgHex;
+         //屏地址-->数据包内容
+         String packData="000101"+content;
+         int packLength=packData.length();
+        String packLengthHex= Integer.toHexString(packLength/2);
+        if (packLengthHex.length()==2){
+           packLengthHex="00"+packLengthHex;
+        }else if (packLengthHex.length()==1){
+            packLengthHex="000"+packLengthHex;
+        }
+        //长度->内容
+       String dataContent= packLengthHex+packData;
+        //异或校验
+       String xor= XorUtils.xor(HEADER_HEX+dataContent);
+        //将特殊字节做处理
+        String str=dataContent+xor;
+        int len=str.length();
+        StringBuilder sb=new StringBuilder();
+       log.info ("xor:{}",xor);
+        for (int i=0;i<len;i+=2){
+            String hex=  str.substring(i,i+2);
+            if (hex.equals("F5")){
+                hex="FA05";
+            }else if (hex.equals("FA")){
+                hex="FA0A";
+            }
+            sb.append(hex);
+        }
+
+        return HEADER_HEX+sb;
+    }
+
+
+}

+ 46 - 0
src/main/java/com/gzlh/device/led/utils/LedOptions.java

@@ -0,0 +1,46 @@
+package com.gzlh.device.led.utils;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+@Data
+@Accessors(chain = true)
+public class LedOptions {
+    /**
+     * 0->8
+     */
+    private String line;
+    /**
+     * 0x01
+     * 0x02
+     * 0x03
+     * 0x04
+     * 0x05
+     * 0x06
+     * 0x07
+     * 1=红色
+     * 2=绿色
+     * 3=黄色
+     * 4=蓝色
+     * 5=粉色
+     * 6=青色
+     * 7=白
+     */
+    private String color;
+    /**
+     * 展示方式
+     * 0x00 左移入
+     * 0x01 上移入
+     * 0x02 下移入
+     * 0x03 左展入
+     * 0x04 右展入
+     * 0x05 上展入
+     * 0x06 下展入
+     * 0x07 横向展开
+     * 0x08 横向闭合
+     * 0x09 纵向展开
+     * 0x0A 纵向闭合
+     * 0x0B 同时显示
+     */
+    private String showType;
+}

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

@@ -0,0 +1,12 @@
+package com.gzlh.device.plc.action;
+
+public interface PLCAction {
+    /**
+     * 红灯亮
+     */
+    String RED_LIGHT_ON="RED_LIGHT_ON";
+    /**
+     * 龙灯灭
+     */
+    String RED_LIGHT_OFF="RED_LIGHT_OFF";
+}

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

@@ -0,0 +1,37 @@
+package com.gzlh.device.plc.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 PlcClientHandler extends SimpleChannelInboundHandler<String> {
+
+    private PlcNettyConfig ledNettyConfig;
+
+    public PlcClientHandler(PlcNettyConfig ledNettyConfig) {
+        this.ledNettyConfig = ledNettyConfig;
+    }
+
+    @Override
+    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
+        log.info("PLC 客户端收到消息:" + msg);
+
+    }
+
+    @Override
+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+        log.error("PLC 客户端 连接断开,进行重连");
+        ledNettyConfig.connect();
+    }
+
+    @Override
+    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+        cause.printStackTrace();
+        ctx.close();
+    }
+
+}
+

+ 108 - 0
src/main/java/com/gzlh/device/plc/client/PlcNettyConfig.java

@@ -0,0 +1,108 @@
+package com.gzlh.device.plc.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 javax.annotation.Resource;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+@Configuration
+@Slf4j
+public class PlcNettyConfig {
+
+
+
+    @Autowired
+    private PlcClientHandler plcClientHandler;
+
+    private Channel channel;
+
+    @Bean("plcBootstrap")
+    public Bootstrap bootstrap() {
+        SerialSetting serialSetting=EventConfig.serialSetting;
+        String host = serialSetting.getHost();
+        int port = serialSetting.getPlc().getPort();
+        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( plcClientHandler);
+                        } catch (Exception e) {
+                            log.info("error connect:{}", e.getMessage());
+                        }
+                    }
+                });
+    }
+
+    @Bean("plcClientHandler")
+    public PlcClientHandler ledClientHandler() {
+        return new PlcClientHandler(this);
+    }
+
+    public void connect() {
+        SerialSetting serialSetting=EventConfig.serialSetting;
+        String host = serialSetting.getHost();
+        int port = serialSetting.getPlc().getPort();
+        ChannelFuture future = bootstrap().connect();
+        future.addListener((ChannelFutureListener) future1 -> {
+            if (future1.isSuccess()) {
+                channel = future1.channel();
+                log.info("plc 串口服务器连接成功,{},{}", host, port);
+            } else {
+                log.error("-------------plc 连接服务器失败,{},{}-----------,进行重连", 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();
+        }
+    }
+
+
+}
+

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

@@ -0,0 +1,42 @@
+package com.gzlh.device.plc.handler;
+
+import cn.hutool.core.util.StrUtil;
+import com.gzlh.bus.EventConfig;
+import com.gzlh.config.dto.SerialSetting;
+import com.gzlh.device.plc.action.PLCAction;
+import com.gzlh.device.plc.client.PlcNettyConfig;
+import com.gzlh.utils.ModbusUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+@Service
+@Slf4j
+public class PLCHadnler {
+    @Resource
+    private PlcNettyConfig plcNettyConfig;
+    private final String COMMAND_PREFIX="010500";
+    private final String COMMAND_ON="FF00";
+    private final String COMMAND_OFF="0000";
+
+    public void handlerAction(String action){
+      SerialSetting serialSetting= EventConfig.serialSetting;
+        if (StrUtil.equals(action, PLCAction.RED_LIGHT_ON)){
+            //亮红灯
+            String redPoint= serialSetting.getPlc().getOut().getSignalRedPoint();
+            String command= COMMAND_PREFIX+redPoint+COMMAND_ON;
+            log.info("plc发送消息:{}",command);
+            String packData= ModbusUtils.buildRequestPacket(command);
+           plcNettyConfig.send(packData);
+        }else if (StrUtil.equals(action, PLCAction.RED_LIGHT_OFF)){
+            //灭红灯
+            String redPoint= serialSetting.getPlc().getOut().getSignalRedPoint();
+            String command= COMMAND_PREFIX+redPoint+COMMAND_OFF;
+            log.info("plc发送消息:{}",command);
+            String packData= ModbusUtils.buildRequestPacket(command);
+            plcNettyConfig.send(packData);
+        }
+    }
+
+}

+ 23 - 0
src/main/java/com/gzlh/device/plc/job/SearchJob.java

@@ -0,0 +1,23 @@
+package com.gzlh.device.plc.job;
+
+import com.gzlh.device.plc.client.PlcNettyConfig;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.core.annotation.Order;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+@Component
+@Slf4j
+@Order(999)
+public class SearchJob {
+    @Resource
+    private PlcNettyConfig plcNettyConfig;
+    @Scheduled(fixedDelay = 2000)
+    public void searchJob(){
+        plcNettyConfig.send("0102000000187800");
+    }
+
+}

+ 10 - 22
src/main/java/com/gzlh/startup/StartupRunner.java

@@ -6,6 +6,8 @@ import cn.hutool.json.JSONObject;
 import cn.hutool.json.XML;
 import com.gzlh.background.client.BackgroundClientNetty;
 import com.gzlh.background.properties.BackgroundPropertiesConfig;
+import com.gzlh.bus.EventConfig;
+import com.gzlh.config.dto.SerialSetting;
 import com.gzlh.device.capture.properties.CapturePropertiesConfig;
 import com.gzlh.config.ModuleEnum;
 import com.gzlh.config.SystemObject;
@@ -16,6 +18,7 @@ import com.gzlh.config.hksdk.HkUtils;
 import com.gzlh.config.hksdk.bo.HKCacheManager;
 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 lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Value;
@@ -29,15 +32,14 @@ import java.util.Properties;
 @Component
 @Slf4j
 public class StartupRunner implements CommandLineRunner {
-    @Resource
-    private EventBus eventBus;
+
     @Resource
     private WeighbridgeNettyConfig weighbridgeNettyConfig;
 
     @Resource
     private LedNettyConfig ledNettyConfig;
     @Resource
-    private RedNettyConfig redNettyConfig;
+    private PlcNettyConfig plcNettyConfig;
 
     @Resource
     private BackgroundPropertiesConfig backgroundPropertiesConfig;
@@ -53,15 +55,15 @@ public class StartupRunner implements CommandLineRunner {
 
     @Override
     public void run(String... args) throws Exception {
-        initConfig();
-        if (SystemObject.weighbridgePropertiesConfig.isEnable()) {
+        SerialSetting serialSetting=EventConfig.serialSetting;
+        if (serialSetting.getWeighbridge().getEnable()) {
             ThreadUtil.execute(() -> weighbridgeNettyConfig.connect());
         }
-        if (SystemObject.ledPropertiesConfig.isEnable()) {
+        if (serialSetting.getLed().getEnable()) {
             ThreadUtil.execute(() -> ledNettyConfig.connect());
         }
-        if (SystemObject.redPropertiesConfig.isEnable()) {
-            ThreadUtil.execute(() -> redNettyConfig.connect());
+        if (serialSetting.getPlc().getEnable()){
+            ThreadUtil.execute(() -> plcNettyConfig.connect());
         }
         if (backgroundPropertiesConfig.isEnable()) {
             //ThreadUtil.execute(() -> backgroundClientNetty.connect());
@@ -82,19 +84,5 @@ public class StartupRunner implements CommandLineRunner {
 
     }
 
-    private void initConfig() {
-        Properties properties = System.getProperties();
-        String rootPath = properties.getProperty("user.dir");
-        String separator = File.separator;
-        String configFile = rootPath + separator + "config.xml";
-        if (!FileUtil.exist(configFile)) {
-            log.error("配置文件不存在:{}", configFile);
-            return;
-        }
-        String content = FileUtil.readUtf8String(configFile);
-        JSONObject result = XML.toJSONObject(content);
-        ApplicationConfigDTO configDTO = result.toBean(ApplicationConfigDTO.class);
-        eventBus.setEventDTOList(configDTO.getConfig().getEventList().getEvent());
 
-    }
 }

+ 44 - 0
src/main/java/com/gzlh/utils/ModbusUtils.java

@@ -0,0 +1,44 @@
+package com.gzlh.utils;
+
+public class ModbusUtils {
+    public static String buildRequestPacket(String packData) {
+        int[] a = new int[packData.length() / 2];
+        for (int i = 0; i < packData.length(); i += 2) {
+            a[i / 2] = Integer.parseInt(packData.substring(i, i + 2), 16);
+        }
+        int crc = calculateCRC(a);
+       return packData+String.format("%04X",crc);
+    }
+    private static int swapBytes(int value) {
+        int highByte = (value >> 8) & 0xFF; // 获取高字节
+        int lowByte = value & 0xFF; // 获取低字节
+
+        return (lowByte << 8) | highByte; // 交换高低字节位置
+    }
+    public static int calculateCRC(int[] data) {
+        int crc = 0xFFFF;
+
+        for (int b : data) {
+            crc ^= (int) b & 0xFF;
+            for (int i = 0; i < 8; i++) {
+                if ((crc & 0x0001) != 0) {
+                    crc >>= 1;
+                    crc ^= 0xA001;
+                } else {
+                    crc >>= 1;
+                }
+            }
+        }
+
+        return swapBytes(crc);
+    }
+
+    public static void main(String[] args) {
+        String packData = "01050000FF00";
+        System.out.println(buildRequestPacket(packData));
+        String s="F5,01,00,33,01,01,00,01,00,01,00,01,08,BB,B6,D3,AD,B9,E2,C1,D9,02,00,00,00,01,1C,C9,EE,DB,DA,CA,D0,5B,40,32,5D,B7,E1,C0,FB,D4,B4,5B,40,33,5D,D3,D0,CF,DE,B9,AB,CB,BE,A4";
+        System.out.println(s.replaceAll(",",""));
+        String sr="010100010001000108BBB6D3ADB9E2C1D902000000011CC9EEDBDACAD05B40325DB7E1C0FBD4B45B40335DD3D0CFDEB9ABCBBE";
+        System.out.println(sr.length());
+    }
+}

+ 6 - 3
src/main/java/com/gzlh/utils/WordHandlerUtils.java

@@ -1,5 +1,6 @@
 package com.gzlh.utils;
 
+import cn.hutool.core.util.CharsetUtil;
 import cn.hutool.core.util.StrUtil;
 import com.gzlh.device.led.utils.ColorConver;
 import com.gzlh.device.led.utils.YangBandPackage;
@@ -23,6 +24,10 @@ public class WordHandlerUtils {
                 sb.append(Integer.parseInt(bit) + 30);
             }else if (StrUtil.equals(".", bit)) {
                 sb.append("2E");
+            }else if (Character.isLetter(ch)){
+                sb.append(Integer.toHexString(ch));
+            }else if (StrUtil.contains(ch+""," ")){
+                sb.append("20");
             }
         }
         return sb.toString();
@@ -30,9 +35,7 @@ public class WordHandlerUtils {
 
 
     public static void main(String[] args) {
-        System.out.println(msgToASCII("你好"));
-        String pack=YangBandPackage.buildPackage(ColorConver.NU_TO_HEX.get(1)+msgToASCII("8222.2吨"));
-        System.out.println(pack);
+        System.out.println(msgToASCII("你好ssss"));
     }
 
     /**

+ 12 - 11
src/main/java/com/gzlh/utils/XorUtils.java

@@ -3,7 +3,7 @@ package com.gzlh.utils;
 public class XorUtils {
 
     public static String xor(String hexStr){
-       return Byte2Hex(getXor(hexStrToByte(hexStr)));
+       return Byte2Hex(getXor(hexString2Bytes(hexStr)));
     }
 
     //1字节转2个Hex字符
@@ -19,24 +19,25 @@ public class XorUtils {
         }
         return temp;
     }
+
     /**
      * 十六进制字符串转换成字节数组
      * @param hexstr 十六进制字符串
      * @return 字节数组
      */
-    private static byte[] hexStrToByte(String hexstr) {
-        int len = (hexstr.length() / 2);
-        byte[] result = new byte[len];
-        char[] achar = hexstr.toCharArray();
-        for (int i = 0; i < len; i++) {
-            int pos = i * 2;
-            result[i] = (byte) (((byte)"0123456789ABCDEF".indexOf(achar[pos])) << 4 | ((byte)"0123456789ABCDEF".indexOf(achar[pos + 1])));
+    public static byte[] hexString2Bytes(String src) {
+        int l = src.length() / 2;
+        byte[] ret = new byte[l];
+        for (int i = 0; i < l; i++) {
+            ret[i] =Integer
+                    .valueOf(src.substring(i * 2, i * 2 + 2), 16).byteValue();
         }
-        return result;
+        return ret;
     }
-
     public static void main(String[] args) {
-        System.out.println(xor("0000FF008C"));
+        String s="F5,01,00,05,01,03,00,01,02,F0";
+        System.out.println(hexString2Bytes("F50100050003000102")[0]);
+        System.out.println(hexString2Bytes("F50100050003000102")[0]);
     }
 
 }

+ 2 - 2
src/main/resources/application.yml

@@ -14,7 +14,7 @@ weighbridge:
 #LED配置
 led:
   host: 192.168.1.254
-  port: 4002
+  port: 4003
   brand: 1000
   enable: true
  #红外
@@ -40,7 +40,7 @@ capture:
   port: 8000
   username: admin
   pwd: ap123456
-  enable: false
+  enable: true
 
 background:
   host: 127.0.0.1