@@ -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>
+ <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>
+ <!--识别到车牌-->
<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>
</eventList>
@@ -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);
@@ -1,9 +1,12 @@
package com.gzlh.api;
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();
}
@@ -10,12 +10,6 @@ import java.util.List;
@Component
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);
@@ -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 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();
+}
@@ -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.device.capture.factory.CaptureFactory;
import com.gzlh.device.capture.properties.CapturePropertiesConfig;
@@ -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;
@@ -20,37 +22,29 @@ import java.util.List;
public class EventThread implements Runnable{
private String eventName;
public EventThread(String eventName) {
this.eventName=eventName;
- 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);
@@ -5,7 +5,6 @@ import com.gzlh.device.capture.properties.CapturePropertiesConfig;
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;
@@ -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;
@@ -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;
@@ -0,0 +1,64 @@
+package com.gzlh.config.dto;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+import java.io.Serializable;
+@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;
+ public static class Weighbridge{
+ private Boolean enable;
+ private int port;
+ private Integer brand;
+ private Integer minKg=1000;
+ public static class LedDTO{
+ public static class PlcDTO{
+ private OutDTO out;
+ private StatusDTO status;
+ @Accessors(chain = true)
+ public static class OutDTO{
+ private String signalRedPoint;
+ private String signalGreenPoint;
+ private String gatePoint;
+ public static class StatusDTO{
+ private String upPoint;
+ private String downPoint;
+ private String radarPoint;
+ private String fRedPoint;
+ private String bRedPoint;
@@ -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,"丰利源"),
;
@@ -1,7 +1,9 @@
package com.gzlh.device.led.client;
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;
@@ -26,8 +28,7 @@ import java.util.concurrent.TimeUnit;
public class LedNettyConfig {
- @Resource
- private LedPropertiesConfig ledConfig;
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() {
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("未建立连接,无法发送消息");
@@ -1,12 +1,13 @@
package com.gzlh.device.led.handler;
import com.gzlh.device.led.brand.LedBrandType;
public interface ILedHandler {
LedBrandType brandType();
- void sendMsg( String content);
+ void sendMsg(String content, LedOptions options);
void handlerAction(String action);
@@ -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 org.springframework.stereotype.Service;
+import javax.annotation.Resource;
+@Service
+public class LedHandlerFengLiYuan implements ILedHandler {
+ @Resource
+ LedNettyConfig ledNettyConfig;
+ @Override
+ public LedBrandType brandType() {
+ return LedBrandType.FEND_LI_YUAN;
+ public void sendMsg(String content, LedOptions options) {
+ log.info("丰利源发送led消息:{}",content);
+ String msgHex= FengLiYuanPackUtils.build(content,options);
+ log.info("数据包:{}",msgHex);
+ ledNettyConfig.send(msgHex);
+ public void handlerAction(String action) {
+ if (StrUtil.contains(action, LedAction.LED_SHOW_CONTENT)) {
+ //展示内容
+ if (StrUtil.contains(action,"platNo")){
+ String carNo= EventDataManager.getCacheData().getCarNo();
+ ledOptions.setColor("05").setLine("02").setShowType("0B");
+ sendMsg(carNo,ledOptions);
@@ -1,9 +1,14 @@
package com.gzlh.device.led.handler.impl;
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.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 {
public void handlerAction(String action) {
log.info("action:{}",action);
@@ -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;
-}
@@ -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));
@@ -0,0 +1,72 @@
+package com.gzlh.device.led.utils;
+import com.gzlh.utils.WordHandlerUtils;
+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;
@@ -0,0 +1,46 @@
+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;
@@ -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";
@@ -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;
+@ChannelHandler.Sharable
+public class PlcClientHandler extends SimpleChannelInboundHandler<String> {
+ private PlcNettyConfig ledNettyConfig;
+ public PlcClientHandler(PlcNettyConfig ledNettyConfig) {
+ this.ledNettyConfig = ledNettyConfig;
+ protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
+ log.info("PLC 客户端收到消息:" + msg);
+ public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+ log.error("PLC 客户端 连接断开,进行重连");
+ ledNettyConfig.connect();
+ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+ cause.printStackTrace();
+ ctx.close();
@@ -0,0 +1,108 @@
+import com.gzlh.config.netty.NettyDecoder;
+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 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.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+@Configuration
+public class PlcNettyConfig {
+ @Autowired
+ private PlcClientHandler plcClientHandler;
+ private Channel channel;
+ @Bean("plcBootstrap")
+ public Bootstrap bootstrap() {
+ 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>() {
+ 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() {
+ 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);
+ future.channel().closeFuture().sync();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ public void send(String message) {
+ if (channel != null && channel.isActive()) {
+ log.error("未建立连接,无法发送消息");
+ public void close() {
+ if (channel != null) {
+ channel.close();
@@ -0,0 +1,42 @@
+package com.gzlh.device.plc.handler;
+import com.gzlh.device.plc.action.PLCAction;
+import com.gzlh.device.plc.client.PlcNettyConfig;
+import com.gzlh.utils.ModbusUtils;
+public class PLCHadnler {
+ 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){
+ 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 command= COMMAND_PREFIX+redPoint+COMMAND_OFF;
@@ -0,0 +1,23 @@
+package com.gzlh.device.plc.job;
+import org.springframework.core.annotation.Order;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+@Component
+@Order(999)
+public class SearchJob {
+ @Scheduled(fixedDelay = 2000)
+ public void searchJob(){
+ plcNettyConfig.send("0102000000187800");
@@ -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;
@@ -16,6 +18,7 @@ import com.gzlh.config.hksdk.HkUtils;
import com.gzlh.config.hksdk.bo.HKCacheManager;
import com.gzlh.device.infrared.client.RedNettyConfig;
import com.gzlh.device.weighbridge.client.WeighbridgeNettyConfig;
import org.springframework.beans.factory.annotation.Value;
@@ -29,15 +32,14 @@ import java.util.Properties;
public class StartupRunner implements CommandLineRunner {
- private EventBus eventBus;
@Resource
private WeighbridgeNettyConfig weighbridgeNettyConfig;
private LedNettyConfig ledNettyConfig;
- private RedNettyConfig redNettyConfig;
private BackgroundPropertiesConfig backgroundPropertiesConfig;
@@ -53,15 +55,15 @@ public class StartupRunner implements CommandLineRunner {
public void run(String... args) throws Exception {
- initConfig();
- if (SystemObject.weighbridgePropertiesConfig.isEnable()) {
+ if (serialSetting.getWeighbridge().getEnable()) {
ThreadUtil.execute(() -> weighbridgeNettyConfig.connect());
- if (SystemObject.ledPropertiesConfig.isEnable()) {
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());
@@ -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;
+ return swapBytes(crc);
+ 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());
package com.gzlh.utils;
+import cn.hutool.core.util.CharsetUtil;
@@ -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");
@@ -30,9 +35,7 @@ public class WordHandlerUtils {
- 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"));
@@ -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;
- System.out.println(xor("0000FF008C"));
+ String s="F5,01,00,05,01,03,00,01,02,F0";
+ System.out.println(hexString2Bytes("F50100050003000102")[0]);
@@ -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