作者 钟来

历史数据存储

正在显示 14 个修改的文件 包含 352 行增加49 行删除
@@ -2,7 +2,9 @@ package com.zhonglai.luhui.smart.feeder; @@ -2,7 +2,9 @@ package com.zhonglai.luhui.smart.feeder;
2 2
3 import com.zhonglai.luhui.smart.feeder.config.OpenCVConfig; 3 import com.zhonglai.luhui.smart.feeder.config.OpenCVConfig;
4 4
  5 +import com.zhonglai.luhui.smart.feeder.config.OperatingData;
5 import com.zhonglai.luhui.smart.feeder.service.InitService; 6 import com.zhonglai.luhui.smart.feeder.service.InitService;
  7 +import com.zhonglai.luhui.smart.spare.feeder.service.SerialPortService;
6 import org.bytedeco.javacv.FFmpegFrameGrabber; 8 import org.bytedeco.javacv.FFmpegFrameGrabber;
7 import org.slf4j.Logger; 9 import org.slf4j.Logger;
8 import org.slf4j.LoggerFactory; 10 import org.slf4j.LoggerFactory;
@@ -17,6 +19,14 @@ public class Main { @@ -17,6 +19,14 @@ public class Main {
17 logger.info("配置参数"); 19 logger.info("配置参数");
18 InitService.initConfig(); 20 InitService.initConfig();
19 21
  22 + logger.info("开始加载FFmpeg");
  23 + try {
  24 + FFmpegFrameGrabber.tryLoad();
  25 + } catch (FFmpegFrameGrabber.Exception e) {
  26 + throw new RuntimeException(e);
  27 + }
  28 + logger.info("FFmpeg加载完成");
  29 +
20 logger.info("启动服务"); 30 logger.info("启动服务");
21 InitService.startService(); 31 InitService.startService();
22 32
@@ -14,9 +14,9 @@ import com.zhonglai.luhui.smart.feeder.dto.mqtt.CmdDto; @@ -14,9 +14,9 @@ import com.zhonglai.luhui.smart.feeder.dto.mqtt.CmdDto;
14 import com.zhonglai.luhui.smart.feeder.dto.mqtt.Condata; 14 import com.zhonglai.luhui.smart.feeder.dto.mqtt.Condata;
15 import com.zhonglai.luhui.smart.feeder.dto.mqtt.DevicedatRequest; 15 import com.zhonglai.luhui.smart.feeder.dto.mqtt.DevicedatRequest;
16 import com.zhonglai.luhui.smart.feeder.dto.mqtt.Info; 16 import com.zhonglai.luhui.smart.feeder.dto.mqtt.Info;
17 -import com.zhonglai.luhui.smart.feeder.service.device.SerialPortService;  
18 import com.zhonglai.luhui.smart.feeder.util.FeederCommdUtil; 17 import com.zhonglai.luhui.smart.feeder.util.FeederCommdUtil;
19 import com.zhonglai.luhui.smart.feeder.util.MessageUtil; 18 import com.zhonglai.luhui.smart.feeder.util.MessageUtil;
  19 +import com.zhonglai.luhui.smart.spare.feeder.service.SerialPortService;
20 import org.slf4j.Logger; 20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory; 21 import org.slf4j.LoggerFactory;
22 22
@@ -42,6 +42,7 @@ public class DateListenService { @@ -42,6 +42,7 @@ public class DateListenService {
42 42
43 public void run() 43 public void run()
44 { 44 {
  45 + logger.info("数据上报");
45 //更新投料机数据 46 //更新投料机数据
46 ScheduledConfig.scheduler.scheduleWithFixedDelay(() -> { 47 ScheduledConfig.scheduler.scheduleWithFixedDelay(() -> {
47 ModbusDto modbusDto = serialPortService.sendHexData(FeederCommdUtil.readAll()); 48 ModbusDto modbusDto = serialPortService.sendHexData(FeederCommdUtil.readAll());
@@ -67,6 +67,7 @@ public class FishGroupImageRecognitionService { @@ -67,6 +67,7 @@ public class FishGroupImageRecognitionService {
67 67
68 public void run() 68 public void run()
69 { 69 {
  70 + logger.info("图像识别");
70 scheduledFuture = ScheduledConfig.scheduler.scheduleWithFixedDelay(() -> { 71 scheduledFuture = ScheduledConfig.scheduler.scheduleWithFixedDelay(() -> {
71 if (!OperatingData.cameraData.getFishGroupImageRecognIsRun()) 72 if (!OperatingData.cameraData.getFishGroupImageRecognIsRun())
72 { 73 {
@@ -85,10 +86,11 @@ public class FishGroupImageRecognitionService { @@ -85,10 +86,11 @@ public class FishGroupImageRecognitionService {
85 86
86 if(!cameraHandle.isOpen()) 87 if(!cameraHandle.isOpen())
87 { 88 {
88 - if (!cameraHandle.init())  
89 - {  
90 - return;  
91 - } 89 + return;
  90 +// if (!cameraHandle.init())
  91 +// {
  92 +// return;
  93 +// }
92 } 94 }
93 OperatingData.cameraData.setFishGroupImageRecognIsRun(true); 95 OperatingData.cameraData.setFishGroupImageRecognIsRun(true);
94 brightnessIdentifyFishRegion(); 96 brightnessIdentifyFishRegion();
1 package com.zhonglai.luhui.smart.feeder.service; 1 package com.zhonglai.luhui.smart.feeder.service;
2 2
3 3
  4 +import com.zhonglai.luhui.smart.feeder.config.OperatingData;
4 import com.zhonglai.luhui.smart.feeder.service.device.CameraHandle; 5 import com.zhonglai.luhui.smart.feeder.service.device.CameraHandle;
5 -import com.zhonglai.luhui.smart.feeder.service.device.SerialPortService;  
6 import com.zhonglai.luhui.smart.feeder.service.device.handle.CameraRtspHandle; 6 import com.zhonglai.luhui.smart.feeder.service.device.handle.CameraRtspHandle;
7 -import com.zhonglai.luhui.smart.feeder.service.netty.NettyClient; 7 +import com.zhonglai.luhui.smart.spare.feeder.service.NettyClient;
  8 +import com.zhonglai.luhui.smart.spare.feeder.service.SerialPortService;
8 9
9 import java.io.BufferedReader; 10 import java.io.BufferedReader;
10 import java.io.InputStreamReader; 11 import java.io.InputStreamReader;
@@ -36,13 +37,17 @@ public class InitService { @@ -36,13 +37,17 @@ public class InitService {
36 /** 37 /**
37 * 串口服务器启动 38 * 串口服务器启动
38 */ 39 */
  40 + String portName = OperatingData.feederConfig.getSerialPortConfig().getPortName();
39 serialPortService = new SerialPortService(); 41 serialPortService = new SerialPortService();
  42 + serialPortService.connect(portName);
  43 + // 启动重连线程
  44 + new Thread(() -> serialPortService.reconnect(portName, 5000)).start(); // 每5秒尝试重连一次
40 45
41 /** 46 /**
42 * mq远程登录 47 * mq远程登录
43 */ 48 */
44 - nettyClient = new NettyClient();  
45 - nettyClient.run(); 49 + nettyClient = new NettyClient(OperatingData.sysConfig.getNettyConfig().getHost(), OperatingData.sysConfig.getNettyConfig().getPort());
  50 + nettyClient.start();
46 51
47 /** 52 /**
48 * 初始化海康的摄像头 53 * 初始化海康的摄像头
@@ -67,6 +72,5 @@ public class InitService { @@ -67,6 +72,5 @@ public class InitService {
67 mqttService = new MqttService(); 72 mqttService = new MqttService();
68 mqttService.start(); 73 mqttService.start();
69 74
70 -  
71 } 75 }
72 } 76 }
@@ -55,6 +55,7 @@ public class MqttService { @@ -55,6 +55,7 @@ public class MqttService {
55 55
56 public void start() 56 public void start()
57 { 57 {
  58 + log.info("数据转发服务");
58 if(null == mqttclient) 59 if(null == mqttclient)
59 { 60 {
60 init(); 61 init();
@@ -4,9 +4,11 @@ import com.ruoyi.common.utils.DateUtils; @@ -4,9 +4,11 @@ import com.ruoyi.common.utils.DateUtils;
4 import com.zhonglai.luhui.smart.feeder.config.OperatingData; 4 import com.zhonglai.luhui.smart.feeder.config.OperatingData;
5 import com.zhonglai.luhui.smart.feeder.config.ScheduledConfig; 5 import com.zhonglai.luhui.smart.feeder.config.ScheduledConfig;
6 import com.zhonglai.luhui.smart.feeder.dto.mqtt.Condata; 6 import com.zhonglai.luhui.smart.feeder.dto.mqtt.Condata;
7 -import com.zhonglai.luhui.smart.feeder.service.device.SerialPortService;  
8 import com.zhonglai.luhui.smart.feeder.util.FeederCommd06ResponseType; 7 import com.zhonglai.luhui.smart.feeder.util.FeederCommd06ResponseType;
9 import com.zhonglai.luhui.smart.feeder.util.FeederCommdUtil; 8 import com.zhonglai.luhui.smart.feeder.util.FeederCommdUtil;
  9 +import com.zhonglai.luhui.smart.spare.feeder.service.SerialPortService;
  10 +import org.slf4j.Logger;
  11 +import org.slf4j.LoggerFactory;
10 12
11 import java.util.Date; 13 import java.util.Date;
12 import java.util.concurrent.ScheduledFuture; 14 import java.util.concurrent.ScheduledFuture;
@@ -16,6 +18,8 @@ import java.util.concurrent.TimeUnit; @@ -16,6 +18,8 @@ import java.util.concurrent.TimeUnit;
16 * 尺度步长法 18 * 尺度步长法
17 */ 19 */
18 public class ScaleStepMethodService { 20 public class ScaleStepMethodService {
  21 + private static final Logger logger = LoggerFactory.getLogger(ScaleStepMethodService.class);
  22 +
19 private Integer logTady = Integer.parseInt(DateUtils.parseDateToStr("yyyyMMdd",new Date())); 23 private Integer logTady = Integer.parseInt(DateUtils.parseDateToStr("yyyyMMdd",new Date()));
20 private ScheduledFuture scheduledFuture; 24 private ScheduledFuture scheduledFuture;
21 25
@@ -28,6 +32,7 @@ public class ScaleStepMethodService { @@ -28,6 +32,7 @@ public class ScaleStepMethodService {
28 32
29 public void run() 33 public void run()
30 { 34 {
  35 + logger.info("鱼群图像识别控制投料控制");
31 scheduledFuture = ScheduledConfig.scheduler.scheduleWithFixedDelay(() -> { 36 scheduledFuture = ScheduledConfig.scheduler.scheduleWithFixedDelay(() -> {
32 Integer nowTady = Integer.parseInt(DateUtils.parseDateToStr("yyyyMMdd",new Date())); 37 Integer nowTady = Integer.parseInt(DateUtils.parseDateToStr("yyyyMMdd",new Date()));
33 if( OperatingData.cameraData.getScaleAreaList().size()==0) 38 if( OperatingData.cameraData.getScaleAreaList().size()==0)
@@ -69,7 +74,7 @@ public class ScaleStepMethodService { @@ -69,7 +74,7 @@ public class ScaleStepMethodService {
69 if (OperatingData.cameraConfig.getFeedingControl()) 74 if (OperatingData.cameraConfig.getFeedingControl())
70 { 75 {
71 //发送停止投料指令 76 //发送停止投料指令
72 - if (serialPortService.isOpen()) 77 + if (serialPortService.isConnected())
73 { 78 {
74 if(OperatingData.feederConfig.getCondata().getRunmode()==1) 79 if(OperatingData.feederConfig.getCondata().getRunmode()==1)
75 { 80 {
@@ -62,6 +62,7 @@ public class SerialPortService { @@ -62,6 +62,7 @@ public class SerialPortService {
62 } 62 }
63 OperatingData.feederData.setInfo(info); 63 OperatingData.feederData.setInfo(info);
64 } 64 }
  65 + logger.info("端口启动情况:{}",serialPort.isOpen());
65 } 66 }
66 67
67 private SerialPort findSerialPort() 68 private SerialPort findSerialPort()
@@ -70,10 +71,8 @@ public class SerialPortService { @@ -70,10 +71,8 @@ public class SerialPortService {
70 SerialPort[] serialPorts = SerialPort.getCommPorts();//查找所有串口 71 SerialPort[] serialPorts = SerialPort.getCommPorts();//查找所有串口
71 72
72 for(SerialPort port:serialPorts){ 73 for(SerialPort port:serialPorts){
73 - System.out.println("Port:"+port.getSystemPortName());//打印串口名称,如COM4  
74 - System.out.println("PortDesc:"+port.getPortDescription());//打印串口类型,如USB Serial  
75 - System.out.println("PortDesc:"+port.getDescriptivePortName());//打印串口的完整类型,如USB-SERIAL CH340(COM4)  
76 - if(port.getPortDescription().indexOf("USB")>=0) 74 + logger.info("Port:{},PortDesc:{},PortDesc:{}",port.getSystemPortName(),port.getPortDescription(),port.getDescriptivePortName());//打印串口名称,如COM4;打印串口类型,如USB Serial;打印串口的完整类型,如USB-SERIAL CH340(COM4)
  75 + if(port.getSystemPortName().indexOf("ttyS0")>=0)
77 { 76 {
78 serialPort = port; 77 serialPort = port;
79 break; 78 break;
@@ -35,6 +35,7 @@ public class CameraRtspHandle implements CameraHandle { @@ -35,6 +35,7 @@ public class CameraRtspHandle implements CameraHandle {
35 35
36 public CameraRtspHandle() 36 public CameraRtspHandle()
37 { 37 {
  38 + logger.info("初始化海康的摄像头");
38 init(); 39 init();
39 40
40 } 41 }
@@ -46,10 +47,8 @@ public class CameraRtspHandle implements CameraHandle { @@ -46,10 +47,8 @@ public class CameraRtspHandle implements CameraHandle {
46 { 47 {
47 return true; 48 return true;
48 } 49 }
49 -  
50 try { 50 try {
51 - FFmpegFrameGrabber.tryLoad();  
52 - 51 + logger.info("配置的视频源类型"+OperatingData.cameraConfig.getCameraInterfaceType().toLowerCase());
53 switch (OperatingData.cameraConfig.getCameraInterfaceType().toLowerCase()) 52 switch (OperatingData.cameraConfig.getCameraInterfaceType().toLowerCase())
54 { 53 {
55 case "rtsp": 54 case "rtsp":
@@ -138,6 +137,7 @@ public class CameraRtspHandle implements CameraHandle { @@ -138,6 +137,7 @@ public class CameraRtspHandle implements CameraHandle {
138 } 137 }
139 138
140 private boolean initRtsp() throws FFmpegFrameGrabber.Exception, InterruptedException { 139 private boolean initRtsp() throws FFmpegFrameGrabber.Exception, InterruptedException {
  140 + logger.error("加载Rtsp");
141 String ip = findCameraIp(); 141 String ip = findCameraIp();
142 if(StringUtils.isEmpty(ip)) 142 if(StringUtils.isEmpty(ip))
143 { 143 {
@@ -327,7 +327,7 @@ public class CameraRtspHandle implements CameraHandle { @@ -327,7 +327,7 @@ public class CameraRtspHandle implements CameraHandle {
327 while (addresses.hasMoreElements()) { 327 while (addresses.hasMoreElements()) {
328 InetAddress addr = addresses.nextElement(); 328 InetAddress addr = addresses.nextElement();
329 if (addr.isSiteLocalAddress()) { // Checks if this address is a "site local" address. 329 if (addr.isSiteLocalAddress()) { // Checks if this address is a "site local" address.
330 - 330 + logger.info("主机的IP:{}",addr.getHostAddress());
331 if(addr.getHostAddress().contains("192.168")) 331 if(addr.getHostAddress().contains("192.168"))
332 { 332 {
333 return addr.getHostAddress(); 333 return addr.getHostAddress();
@@ -342,6 +342,7 @@ public class CameraRtspHandle implements CameraHandle { @@ -342,6 +342,7 @@ public class CameraRtspHandle implements CameraHandle {
342 342
343 public static String findCameraIp() { 343 public static String findCameraIp() {
344 String localIP = getLocalIp(); 344 String localIP = getLocalIp();
  345 + logger.info("找到的主机ip:"+localIP);
345 if(null == localIP) 346 if(null == localIP)
346 { 347 {
347 return null; 348 return null;
@@ -366,7 +367,7 @@ public class CameraRtspHandle implements CameraHandle { @@ -366,7 +367,7 @@ public class CameraRtspHandle implements CameraHandle {
366 while (StringUtils.isEmpty(ip[0])) 367 while (StringUtils.isEmpty(ip[0]))
367 { 368 {
368 findCamera(localIP); 369 findCamera(localIP);
369 - Thread.sleep(1000); 370 + Thread.sleep(10000);
370 } 371 }
371 } catch (InterruptedException e) { 372 } catch (InterruptedException e) {
372 e.printStackTrace(); 373 e.printStackTrace();
@@ -381,6 +382,7 @@ public class CameraRtspHandle implements CameraHandle { @@ -381,6 +382,7 @@ public class CameraRtspHandle implements CameraHandle {
381 } 382 }
382 return ip[0]; 383 return ip[0];
383 } catch (InterruptedException e) { 384 } catch (InterruptedException e) {
  385 + logger.error("查找摄像头失败",e);
384 } 386 }
385 return null; 387 return null;
386 } 388 }
@@ -412,24 +414,32 @@ public class CameraRtspHandle implements CameraHandle { @@ -412,24 +414,32 @@ public class CameraRtspHandle implements CameraHandle {
412 414
413 415
414 private static String getCameraIp(String ip) throws Exception { 416 private static String getCameraIp(String ip) throws Exception {
  417 + logger.info("开始查找摄像头的ip");
415 // 1.创建组播socket,加入指定的组播地址和端口 418 // 1.创建组播socket,加入指定的组播地址和端口
416 InetAddress group = InetAddress.getByName("239.255.255.250"); 419 InetAddress group = InetAddress.getByName("239.255.255.250");
417 MulticastSocket multicastSocket = new MulticastSocket(37020); 420 MulticastSocket multicastSocket = new MulticastSocket(37020);
418 421
419 multicastSocket.joinGroup(new InetSocketAddress(group,37020),NetworkInterface.getByInetAddress(InetAddress.getByName(ip))); 422 multicastSocket.joinGroup(new InetSocketAddress(group,37020),NetworkInterface.getByInetAddress(InetAddress.getByName(ip)));
420 - multicastSocket.setSoTimeout(100000); 423 + multicastSocket.setSoTimeout(10000);
421 // 2.创建接收的数据包 424 // 2.创建接收的数据包
422 byte[] buf = new byte[1024]; 425 byte[] buf = new byte[1024];
423 426
424 -  
425 // 4.解析数据包,并打印出来 427 // 4.解析数据包,并打印出来
426 HCCameraRepose probe = null; 428 HCCameraRepose probe = null;
427 while (ObjectUtil.isEmpty(probe)) 429 while (ObjectUtil.isEmpty(probe))
428 { 430 {
429 DatagramPacket dpReceive = new DatagramPacket(buf, buf.length); 431 DatagramPacket dpReceive = new DatagramPacket(buf, buf.length);
  432 + logger.info("发送组播查找信息");
430 // 3.调用socket对象的接收方法接收数据包 433 // 3.调用socket对象的接收方法接收数据包
431 - multicastSocket.receive(dpReceive); 434 + try {
  435 + multicastSocket.receive(dpReceive);
  436 + }catch (Exception e)
  437 + {
  438 + logger.error("组播查找异常",e);
  439 + }
  440 +
432 String receivedXml = new String(dpReceive.getData(), 0, dpReceive.getLength()); 441 String receivedXml = new String(dpReceive.getData(), 0, dpReceive.getLength());
  442 + logger.info("查找海康摄像头的结果:{}",receivedXml);
433 443
434 String startTag = "<IPv4Address>"; 444 String startTag = "<IPv4Address>";
435 String endTag = "</IPv4Address>"; 445 String endTag = "</IPv4Address>";
@@ -5,8 +5,8 @@ import com.ruoyi.common.utils.GsonConstructor; @@ -5,8 +5,8 @@ import com.ruoyi.common.utils.GsonConstructor;
5 import com.zhonglai.luhui.smart.feeder.config.OperatingData; 5 import com.zhonglai.luhui.smart.feeder.config.OperatingData;
6 import com.zhonglai.luhui.smart.feeder.dto.mqtt.CmdDto; 6 import com.zhonglai.luhui.smart.feeder.dto.mqtt.CmdDto;
7 import com.zhonglai.luhui.smart.feeder.dto.mqtt.HeadDto; 7 import com.zhonglai.luhui.smart.feeder.dto.mqtt.HeadDto;
8 -import com.zhonglai.luhui.smart.feeder.service.netty.NettyClient;  
9 import com.zhonglai.luhui.smart.feeder.util.MessageUtil; 8 import com.zhonglai.luhui.smart.feeder.util.MessageUtil;
  9 +import com.zhonglai.luhui.smart.spare.feeder.service.NettyClient;
10 import io.netty.channel.ChannelHandlerContext; 10 import io.netty.channel.ChannelHandlerContext;
11 import io.netty.handler.codec.MessageToMessageDecoder; 11 import io.netty.handler.codec.MessageToMessageDecoder;
12 import org.apache.commons.lang3.StringUtils; 12 import org.apache.commons.lang3.StringUtils;
@@ -14,6 +14,7 @@ import org.slf4j.Logger; @@ -14,6 +14,7 @@ import org.slf4j.Logger;
14 import org.slf4j.LoggerFactory; 14 import org.slf4j.LoggerFactory;
15 15
16 import java.util.List; 16 import java.util.List;
  17 +import java.util.concurrent.TimeUnit;
17 import java.util.regex.Matcher; 18 import java.util.regex.Matcher;
18 import java.util.regex.Pattern; 19 import java.util.regex.Pattern;
19 20
@@ -29,28 +30,7 @@ public class AgreementHandler extends MessageToMessageDecoder<String> { @@ -29,28 +30,7 @@ public class AgreementHandler extends MessageToMessageDecoder<String> {
29 30
30 private CameracontrolService cameracontrolService = new CameracontrolService(); 31 private CameracontrolService cameracontrolService = new CameracontrolService();
31 32
32 - private NettyClient nettyClient;  
33 33
34 - public AgreementHandler(NettyClient nettyClient)  
35 - {  
36 - this.nettyClient = nettyClient;  
37 - }  
38 -  
39 - @Override  
40 - public void channelActive(ChannelHandlerContext ctx) throws Exception {  
41 - logger.info("设备上线");  
42 - nettyClient.setCtx(ctx);  
43 - // 连接建立时的处理,发送请求注册消息给服务器  
44 - JsonObject jsonObject = new JsonObject();  
45 - jsonObject.addProperty("cmd","manualcontrol");  
46 - jsonObject.addProperty("type","4G.hs");  
47 - MessageUtil.sendMessage(ctx, new CmdDto().setImei(OperatingData.sysConfig.getNettyConfig().getClientId()).setJsonObject(jsonObject).generateCmd(),true);  
48 - }  
49 -  
50 - @Override  
51 - public void channelInactive(ChannelHandlerContext ctx) {  
52 - logger.info("设备离线");  
53 - }  
54 34
55 private static boolean checkAgreement(String data) 35 private static boolean checkAgreement(String data)
56 { 36 {
@@ -65,6 +45,7 @@ public class AgreementHandler extends MessageToMessageDecoder<String> { @@ -65,6 +45,7 @@ public class AgreementHandler extends MessageToMessageDecoder<String> {
65 return rs; 45 return rs;
66 } 46 }
67 47
  48 +
68 @Override 49 @Override
69 protected void decode(ChannelHandlerContext ctx, String msg, List<Object> out) throws Exception { 50 protected void decode(ChannelHandlerContext ctx, String msg, List<Object> out) throws Exception {
70 try { 51 try {
@@ -81,6 +62,7 @@ public class AgreementHandler extends MessageToMessageDecoder<String> { @@ -81,6 +62,7 @@ public class AgreementHandler extends MessageToMessageDecoder<String> {
81 break; 62 break;
82 case "cfgdata": 63 case "cfgdata":
83 cfgdataService.noticeFeeder(ctx,cmdDto); 64 cfgdataService.noticeFeeder(ctx,cmdDto);
  65 + logger.info("cfgdata数据通知结束");
84 break; 66 break;
85 case "manualcontrol": 67 case "manualcontrol":
86 manualcontrolService.noticeFeeder(ctx,cmdDto); 68 manualcontrolService.noticeFeeder(ctx,cmdDto);
@@ -31,7 +31,7 @@ public class CfgdataService { @@ -31,7 +31,7 @@ public class CfgdataService {
31 private static final Logger logger = LoggerFactory.getLogger(CfgdataService.class); 31 private static final Logger logger = LoggerFactory.getLogger(CfgdataService.class);
32 public void noticeFeeder(ChannelHandlerContext ctx,CmdDto cmdDto) 32 public void noticeFeeder(ChannelHandlerContext ctx,CmdDto cmdDto)
33 { 33 {
34 - if(!InitService.serialPortService.open()) 34 + if(!InitService.serialPortService.isConnected())
35 { 35 {
36 MessageUtil.sendFeederResponseMessage(ctx,"cfgdataOK", FeederBackstateTtpe.serialPortErr,0); 36 MessageUtil.sendFeederResponseMessage(ctx,"cfgdataOK", FeederBackstateTtpe.serialPortErr,0);
37 return; 37 return;
@@ -25,7 +25,7 @@ public class ManualcontrolService { @@ -25,7 +25,7 @@ public class ManualcontrolService {
25 25
26 public void noticeFeeder(ChannelHandlerContext ctx,CmdDto cmdDto) 26 public void noticeFeeder(ChannelHandlerContext ctx,CmdDto cmdDto)
27 { 27 {
28 - if(!InitService.serialPortService.open()) 28 + if(!InitService.serialPortService.isConnected())
29 { 29 {
30 MessageUtil.sendFeederResponseMessage(ctx,"manualcontrolOK", FeederBackstateTtpe.serialPortErr,0); 30 MessageUtil.sendFeederResponseMessage(ctx,"manualcontrolOK", FeederBackstateTtpe.serialPortErr,0);
31 return; 31 return;
@@ -104,7 +104,7 @@ public class NettyClient { @@ -104,7 +104,7 @@ public class NettyClient {
104 ChannelPipeline pipeline = ch.pipeline(); 104 ChannelPipeline pipeline = ch.pipeline();
105 pipeline.addLast("StringEncoder", new StringEncoder(Charset.forName("gb2312"))); 105 pipeline.addLast("StringEncoder", new StringEncoder(Charset.forName("gb2312")));
106 pipeline.addLast("StringDecoder", new StringDecoder(Charset.forName("gb2312"))); 106 pipeline.addLast("StringDecoder", new StringDecoder(Charset.forName("gb2312")));
107 - pipeline.addLast("AgreementHandler", new AgreementHandler(nettyClient)); 107 + pipeline.addLast("AgreementHandler", new AgreementHandler());
108 } 108 }
109 } 109 }
110 110
  1 +package com.zhonglai.luhui.smart.spare.feeder.service;
  2 +
  3 +import com.google.gson.JsonObject;
  4 +import com.zhonglai.luhui.smart.feeder.config.OperatingData;
  5 +import com.zhonglai.luhui.smart.feeder.dto.mqtt.CmdDto;
  6 +import com.zhonglai.luhui.smart.feeder.service.feeder.AgreementHandler;
  7 +import com.zhonglai.luhui.smart.feeder.util.MessageUtil;
  8 +import io.netty.bootstrap.Bootstrap;
  9 +import io.netty.channel.*;
  10 +import io.netty.channel.nio.NioEventLoopGroup;
  11 +import io.netty.channel.socket.SocketChannel;
  12 +import io.netty.channel.socket.nio.NioSocketChannel;
  13 +import io.netty.handler.codec.string.StringDecoder;
  14 +import io.netty.handler.codec.string.StringEncoder;
  15 +import org.slf4j.Logger;
  16 +import org.slf4j.LoggerFactory;
  17 +
  18 +import java.nio.charset.Charset;
  19 +import java.util.concurrent.TimeUnit;
  20 +import java.util.concurrent.atomic.AtomicInteger;
  21 +
  22 +public class NettyClient {
  23 + private static final Logger logger = LoggerFactory.getLogger(NettyClient.class);
  24 + private final String host;
  25 + private final int port;
  26 + private Bootstrap bootstrap;
  27 + private EventLoopGroup group;
  28 + private Channel channel;
  29 +
  30 + private ChannelHandlerContext ctx;
  31 +
  32 + private ChannelFuture future;
  33 + private final AtomicInteger retryCount = new AtomicInteger();
  34 +
  35 + public NettyClient(String host, int port) {
  36 + this.host = host;
  37 + this.port = port;
  38 + }
  39 +
  40 + public void start() {
  41 + group = new NioEventLoopGroup();
  42 + try {
  43 + bootstrap = new Bootstrap();
  44 + bootstrap.group(group)
  45 + .channel(NioSocketChannel.class)
  46 + .handler(new ChannelInitializer<SocketChannel>() {
  47 + @Override
  48 + protected void initChannel(SocketChannel ch) throws Exception {
  49 + ch.pipeline().addLast("StringEncoder", new StringEncoder(Charset.forName("gb2312")));
  50 + ch.pipeline().addLast("StringDecoder", new StringDecoder(Charset.forName("gb2312")));
  51 + ch.pipeline().addLast(new AgreementHandler());
  52 + ch.pipeline().addLast(new ChannelInboundHandlerAdapter(){
  53 + @Override
  54 + public void channelActive(ChannelHandlerContext ctx) throws Exception {
  55 + logger.info("设备上线");
  56 + setCtx(ctx);
  57 + // 连接建立时的处理,发送请求注册消息给服务器
  58 + JsonObject jsonObject = new JsonObject();
  59 + jsonObject.addProperty("cmd","manualcontrol");
  60 + jsonObject.addProperty("type","4G.hs");
  61 + MessageUtil.sendMessage(ctx, new CmdDto().setImei(OperatingData.sysConfig.getNettyConfig().getClientId()).setJsonObject(jsonObject).generateCmd(),true);
  62 + }
  63 + @Override
  64 + public void channelInactive(ChannelHandlerContext ctx) {
  65 + logger.info("设备离线");
  66 + future.channel().eventLoop().schedule(NettyClient.this::connect, 5, TimeUnit.SECONDS);
  67 + }
  68 +
  69 + @Override
  70 + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
  71 + cause.printStackTrace();
  72 + ctx.close();
  73 + }
  74 + });
  75 + }
  76 + });
  77 +
  78 + connect();
  79 + } catch (Exception e) {
  80 + e.printStackTrace();
  81 + }
  82 + }
  83 +
  84 + public void shutdown() {
  85 + group.shutdownGracefully();
  86 + }
  87 +
  88 + private void connect() {
  89 + if (channel != null && channel.isActive()) {
  90 + return;
  91 + }
  92 +
  93 +
  94 + try {
  95 + future = bootstrap.connect(host, port);
  96 + future.addListener(new ChannelFutureListener() {
  97 + @Override
  98 + public void operationComplete(ChannelFuture future) throws Exception {
  99 + if (future.isSuccess()) {
  100 + channel = future.channel();
  101 + logger.info("运程连接成功");
  102 + } else {
  103 + logger.info("运程连接失败,尝试重连...");
  104 + retryCount.incrementAndGet();
  105 + future.channel().eventLoop().schedule(NettyClient.this::connect, 5, TimeUnit.SECONDS);
  106 + }
  107 + }
  108 +
  109 + }).sync();
  110 + } catch (InterruptedException e) {
  111 + logger.error("连接失败",e);
  112 + future.channel().eventLoop().schedule(NettyClient.this::connect, 5, TimeUnit.SECONDS);
  113 + }
  114 +
  115 +
  116 + }
  117 +
  118 +
  119 +
  120 + public ChannelHandlerContext getCtx() {
  121 + return ctx;
  122 + }
  123 + public void setCtx(ChannelHandlerContext ctx)
  124 + {
  125 + this.ctx = ctx;
  126 + }
  127 +}
  1 +package com.zhonglai.luhui.smart.spare.feeder.service;
  2 +
  3 +import com.fazecast.jSerialComm.SerialPort;
  4 +import com.fazecast.jSerialComm.SerialPortEvent;
  5 +import com.ruoyi.common.utils.ByteUtil;
  6 +import com.zhonglai.luhui.smart.feeder.config.OperatingData;
  7 +import com.zhonglai.luhui.smart.feeder.dto.ModbusDto;
  8 +import com.zhonglai.luhui.smart.feeder.dto.SerialPortConfig;
  9 +import com.zhonglai.luhui.smart.feeder.dto.commd.FeederCommdDto;
  10 +import org.slf4j.Logger;
  11 +import org.slf4j.LoggerFactory;
  12 +
  13 +import java.util.concurrent.BlockingQueue;
  14 +import java.util.concurrent.LinkedBlockingQueue;
  15 +import java.util.concurrent.TimeUnit;
  16 +
  17 +/**
  18 + * 端口服务
  19 + */
  20 +public class SerialPortService implements com.fazecast.jSerialComm.SerialPortDataListener {
  21 + private static final Logger logger = LoggerFactory.getLogger(SerialPortService.class);
  22 + private SerialPort serialPort;
  23 + private boolean isConnected = false;
  24 + private final Object lock = new Object();
  25 +
  26 + private BlockingQueue<ModbusDto> dataQueue = new LinkedBlockingQueue<>();
  27 +
  28 + public void connect(String portName) {
  29 + serialPort = findSerialPort(portName);
  30 + // 尝试打开串口
  31 + logger.info("尝试打开串口:"+portName);
  32 +// serialPort = SerialPort.getCommPort(portName);
  33 + if (serialPort == null) {
  34 + logger.error("无法找到串口: " + portName);
  35 + return;
  36 + }
  37 + logger.info("串口尝试打开成功,准备连接:"+portName);
  38 +
  39 + try {
  40 + SerialPortConfig serialPortConfig = OperatingData.feederConfig.getSerialPortConfig();
  41 +
  42 + // 配置串口参数
  43 + serialPort.setBaudRate(serialPortConfig.getBaudrate());
  44 + serialPort.setNumDataBits(serialPortConfig.getDataBits());
  45 + serialPort.setNumStopBits(serialPortConfig.getStopBits());
  46 + serialPort.setParity(serialPortConfig.getParity());
  47 +
  48 + // 打开串口
  49 + serialPort.openPort();
  50 + serialPort.addDataListener(this);
  51 +
  52 + // 设置串口为非阻塞模式,以便可以异步接收数据
  53 + serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 0, 0);
  54 +
  55 + isConnected = true;
  56 + logger.info("串口已连接: " + portName);
  57 +
  58 + } catch (Exception e) {
  59 + logger.error("串口连接失败: " , e);
  60 + }
  61 + }
  62 +
  63 + @Override
  64 + public int getListeningEvents() {
  65 + // 监听数据到达事件
  66 + return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;//返回要监听的事件类型,以供回调函数使用。可发回的事件包括:SerialPort.LISTENING_EVENT_DATA_AVAILABLE,SerialPort.LISTENING_EVENT_DATA_WRITTEN,SerialPort.LISTENING_EVENT_DATA_RECEIVED。分别对应有数据在串口(不论是读的还是写的),有数据写入串口,从串口读取数据。如果AVAILABLE和RECEIVED同时被监听,优先触发RECEIVED
  67 + }
  68 +
  69 + @Override
  70 + public void serialEvent(SerialPortEvent event) {
  71 + if (event.getEventType() == SerialPort.LISTENING_EVENT_DATA_AVAILABLE) {
  72 + try {
  73 + // 读取串口数据
  74 + byte[] newData = new byte[serialPort.bytesAvailable()];
  75 + int numRead = serialPort.readBytes(newData, newData.length);
  76 +
  77 + logger.info("串口返回{}字节数据:{}",numRead, ByteUtil.toHexString(newData));
  78 + FeederCommdDto commdDto = new FeederCommdDto(newData);
  79 + dataQueue.offer(commdDto); // 将数据添加到队列中// 处理串口返回的数据
  80 + } catch (Exception e) {
  81 + logger.error("读取串口数据时出错: " , e);
  82 + }
  83 + }
  84 + }
  85 +
  86 +
  87 + public void disconnect() {
  88 + if (isConnected) {
  89 + try {
  90 + serialPort.removeDataListener();
  91 + serialPort.closePort();
  92 + isConnected = false;
  93 + logger.info("串口已断开连接");
  94 + } catch (Exception e) {
  95 + logger.error("串口断开失败: " , e);
  96 + }
  97 + }
  98 + }
  99 +
  100 + public boolean isConnected() {
  101 + return isConnected;
  102 + }
  103 +
  104 + // 实现掉线重连逻辑
  105 + public void reconnect(String portName, int reconnectIntervalMillis) {
  106 + while (!isConnected) {
  107 + try {
  108 + Thread.sleep(reconnectIntervalMillis);
  109 + connect(portName);
  110 + } catch (InterruptedException e) {
  111 + logger.error("重连线程被中断: " , e);
  112 + Thread.currentThread().interrupt();
  113 + return;
  114 + }
  115 + }
  116 + }
  117 +
  118 + public ModbusDto sendByte(byte[] bytes)
  119 + {
  120 + synchronized (lock)
  121 + {
  122 + if(isConnected)
  123 + {
  124 + serialPort.writeBytes(bytes,bytes.length);
  125 + try {
  126 + ModbusDto reStr = dataQueue.poll(15, TimeUnit.SECONDS);
  127 + logger.info("接串口通知数据:{}",reStr);
  128 + return reStr;
  129 + } catch (InterruptedException e) {
  130 + logger.error("等待串口返回数据异常!" + e);
  131 + disconnect();
  132 + }
  133 + }else{
  134 + logger.error("串口未打开!" );
  135 + return null;
  136 + }
  137 +
  138 + }
  139 + return null;
  140 + }
  141 +
  142 + private SerialPort findSerialPort(String portName)
  143 + {
  144 + SerialPort[] serialPorts = SerialPort.getCommPorts();//查找所有串口
  145 + logger.info("总串口数"+serialPorts.length);
  146 + for(SerialPort port:serialPorts){
  147 + logger.info("Port:{},PortDesc:{},PortDesc:{}",port.getSystemPortName(),port.getPortDescription(),port.getDescriptivePortName());//打印串口名称,如COM4;打印串口类型,如USB Serial;打印串口的完整类型,如USB-SERIAL CH340(COM4)
  148 + if(port.getSystemPortName().equals(portName))
  149 + {
  150 + return port;
  151 + }
  152 + }
  153 +
  154 + return null;
  155 + }
  156 +
  157 + public ModbusDto sendHexData(String hexStr) {
  158 + logger.info("串口写入:{}",hexStr);
  159 + byte[] bytes = ByteUtil.hexStringToByte(hexStr.replace(" ","").trim().toUpperCase());
  160 + return sendByte(bytes);
  161 + }
  162 +}