作者 钟来

模块整理

正在显示 26 个修改的文件 包含 447 行增加755 行删除
@@ -65,20 +65,6 @@ @@ -65,20 +65,6 @@
65 <artifactId>spring-boot-starter-websocket</artifactId> 65 <artifactId>spring-boot-starter-websocket</artifactId>
66 </dependency> 66 </dependency>
67 67
68 - <!-- 串口开发 -->  
69 - <dependency>  
70 - <groupId>com.github.purejavacomm</groupId>  
71 - <artifactId>purejavacomm</artifactId>  
72 - <version>1.0.1.RELEASE</version>  
73 - </dependency>  
74 -  
75 - <dependency>  
76 - <groupId>org.ehcache</groupId>  
77 - <artifactId>ehcache</artifactId>  
78 - <version>3.10.8</version>  
79 - </dependency>  
80 -  
81 -  
82 <!-- sqlite --> 68 <!-- sqlite -->
83 <dependency> 69 <dependency>
84 <groupId>com.zhonglai.luhui</groupId> 70 <groupId>com.zhonglai.luhui</groupId>
@@ -98,11 +84,6 @@ @@ -98,11 +84,6 @@
98 <version>3.21.0.1</version> 84 <version>3.21.0.1</version>
99 </dependency> 85 </dependency>
100 86
101 -<!-- <dependency>-->  
102 -<!-- <groupId>mysql</groupId>-->  
103 -<!-- <artifactId>mysql-connector-java</artifactId>-->  
104 -<!-- </dependency>-->  
105 -  
106 <!-- mqtt --> 87 <!-- mqtt -->
107 <dependency> 88 <dependency>
108 <groupId>org.eclipse.paho</groupId> 89 <groupId>org.eclipse.paho</groupId>
@@ -112,6 +93,14 @@ @@ -112,6 +93,14 @@
112 <groupId>cn.hutool</groupId> 93 <groupId>cn.hutool</groupId>
113 <artifactId>hutool-all</artifactId> 94 <artifactId>hutool-all</artifactId>
114 </dependency> 95 </dependency>
  96 +
  97 + <!-- 串口开发 -->
  98 + <!-- https://mvnrepository.com/artifact/com.fazecast/jSerialComm -->
  99 + <dependency>
  100 + <groupId>com.fazecast</groupId>
  101 + <artifactId>jSerialComm</artifactId>
  102 + <version>2.10.3</version>
  103 + </dependency>
115 </dependencies> 104 </dependencies>
116 105
117 <build> 106 <build>
@@ -2,7 +2,6 @@ package com.zhonglai.luhui.smart.feeder; @@ -2,7 +2,6 @@ package com.zhonglai.luhui.smart.feeder;
2 2
3 import com.ruoyi.framework.config.ResourcesConfig; 3 import com.ruoyi.framework.config.ResourcesConfig;
4 import com.zhonglai.luhui.smart.feeder.config.OpenCVConfig; 4 import com.zhonglai.luhui.smart.feeder.config.OpenCVConfig;
5 -import com.zhonglai.luhui.smart.feeder.config.v2apibug.ResponseFilter;  
6 import org.springframework.boot.SpringApplication; 5 import org.springframework.boot.SpringApplication;
7 import org.springframework.boot.autoconfigure.SpringBootApplication; 6 import org.springframework.boot.autoconfigure.SpringBootApplication;
8 7
@@ -2,6 +2,7 @@ package com.zhonglai.luhui.smart.feeder.config.manager; @@ -2,6 +2,7 @@ package com.zhonglai.luhui.smart.feeder.config.manager;
2 2
3 import com.zhonglai.luhui.smart.feeder.service.DeviceService; 3 import com.zhonglai.luhui.smart.feeder.service.DeviceService;
4 import com.zhonglai.luhui.smart.feeder.service.EhCacheService; 4 import com.zhonglai.luhui.smart.feeder.service.EhCacheService;
  5 +import com.zhonglai.luhui.smart.feeder.service.SerialPortService;
5 import com.zhonglai.luhui.smart.feeder.service.TerminalService; 6 import com.zhonglai.luhui.smart.feeder.service.TerminalService;
6 import org.slf4j.Logger; 7 import org.slf4j.Logger;
7 import org.slf4j.LoggerFactory; 8 import org.slf4j.LoggerFactory;
@@ -24,7 +25,7 @@ public class ShutdownManager @@ -24,7 +25,7 @@ public class ShutdownManager
24 private EhCacheService ehCacheService; 25 private EhCacheService ehCacheService;
25 26
26 @Autowired 27 @Autowired
27 - private DeviceService deviceService; 28 + private SerialPortService serialPortService;
28 29
29 @Autowired 30 @Autowired
30 private TerminalService terminalService; 31 private TerminalService terminalService;
@@ -33,7 +34,7 @@ public class ShutdownManager @@ -33,7 +34,7 @@ public class ShutdownManager
33 public void destroy() 34 public void destroy()
34 { 35 {
35 terminalService.close(); 36 terminalService.close();
36 - deviceService.close(); 37 + serialPortService.close();
37 ehCacheService.shutdown(); 38 ehCacheService.shutdown();
38 shutdownAsyncManager(); 39 shutdownAsyncManager();
39 } 40 }
@@ -26,22 +26,6 @@ public class CameraController { @@ -26,22 +26,6 @@ public class CameraController {
26 @Autowired 26 @Autowired
27 private DeviceService deviceService; 27 private DeviceService deviceService;
28 28
29 - @ApiOperation("打开鱼群识别")  
30 - @GetMapping("/open")  
31 - public AjaxResult open()  
32 - {  
33 -// fishGroupImageRecognitionService.start(VeiwType.html);  
34 - return AjaxResult.success();  
35 - }  
36 -  
37 - @ApiOperation("关闭鱼群识别")  
38 - @GetMapping("/close")  
39 - public AjaxResult close()  
40 - {  
41 -// fishGroupImageRecognitionService.stop();  
42 - return AjaxResult.success();  
43 - }  
44 -  
45 @ApiOperation("关闭连接") 29 @ApiOperation("关闭连接")
46 @GetMapping("/discon/{userId}") 30 @GetMapping("/discon/{userId}")
47 public AjaxResult discon( @PathVariable(value = "userId") Integer userId) 31 public AjaxResult discon( @PathVariable(value = "userId") Integer userId)
@@ -50,54 +34,4 @@ public class CameraController { @@ -50,54 +34,4 @@ public class CameraController {
50 return AjaxResult.success(); 34 return AjaxResult.success();
51 } 35 }
52 36
53 - @ApiOperation("打开串口")  
54 - @ApiImplicitParams({  
55 - @ApiImplicitParam(value = "串口名称",name = "portName"),  
56 - @ApiImplicitParam(value = "波特率",name = "baudrate"),  
57 - @ApiImplicitParam(value = "数据位",name = "dataBits"),  
58 - @ApiImplicitParam(value = "停止位",name = "stopBits"),  
59 - @ApiImplicitParam(value = "校验位",name = "parity"),  
60 - })  
61 - @GetMapping("/openSerial")  
62 - public AjaxResult openSerial(String portName, Integer baudrate, Integer dataBits, Integer stopBits,Integer parity) throws Exception {  
63 - deviceService.openSerialPort(portName,baudrate,dataBits,stopBits,parity);  
64 - return AjaxResult.success();  
65 - }  
66 -  
67 - @ApiOperation("强行打开串口")  
68 - @ApiImplicitParams({  
69 - @ApiImplicitParam(value = "串口名称",name = "portName"),  
70 - @ApiImplicitParam(value = "波特率",name = "baudrate"),  
71 - @ApiImplicitParam(value = "数据位",name = "dataBits"),  
72 - @ApiImplicitParam(value = "停止位",name = "stopBits"),  
73 - @ApiImplicitParam(value = "校验位",name = "parity"),  
74 - })  
75 - @GetMapping("/nowOpenSerial")  
76 - public AjaxResult nowOpenSerial(String portName, Integer baudrate, Integer dataBits, Integer stopBits,Integer parity) throws Exception {  
77 - deviceService.nowOpenSerial(portName,baudrate,dataBits,stopBits,parity);  
78 - return AjaxResult.success();  
79 - }  
80 -  
81 - @ApiOperation("串口发送指令")  
82 - @GetMapping("/sendSerialData")  
83 - public AjaxResult sendSerialData(String hexStr) throws IOException {  
84 - hexStr = hexStr.replace(" ","").trim();  
85 - ModbusDto commdDto = deviceService.sendData(hexStr);  
86 - return AjaxResult.success(commdDto);  
87 - }  
88 -  
89 - @ApiOperation("地址发送指令")  
90 - @GetMapping("/controlData")  
91 - public AjaxResult controlData(FeederCommd06ResponseType feederCommd06ResponseType,int value) throws IOException {  
92 - ModbusDto commdDto = deviceService.sendData(FeederCommdUtil.controlData( feederCommd06ResponseType, value));  
93 - return AjaxResult.success(commdDto);  
94 - }  
95 -  
96 - @ApiOperation("获取所有串口")  
97 - @GetMapping("/getAllSerial")  
98 - public AjaxResult getAllSerial() {  
99 - return AjaxResult.success().put("data",deviceService.getAllSerial());  
100 - }  
101 -  
102 -  
103 } 37 }
@@ -3,17 +3,12 @@ package com.zhonglai.luhui.smart.feeder.controller; @@ -3,17 +3,12 @@ package com.zhonglai.luhui.smart.feeder.controller;
3 import com.ruoyi.common.core.domain.AjaxResult; 3 import com.ruoyi.common.core.domain.AjaxResult;
4 import com.zhonglai.luhui.dao.service.PublicService; 4 import com.zhonglai.luhui.dao.service.PublicService;
5 import com.zhonglai.luhui.smart.feeder.dto.ConfigDto; 5 import com.zhonglai.luhui.smart.feeder.dto.ConfigDto;
6 -import com.zhonglai.luhui.smart.feeder.dto.ConfigurationParameter;  
7 -import com.zhonglai.luhui.smart.feeder.dto.VeiwType;  
8 import com.zhonglai.luhui.smart.feeder.service.ConfigurationParameterService; 6 import com.zhonglai.luhui.smart.feeder.service.ConfigurationParameterService;
9 -import com.zhonglai.luhui.smart.feeder.service.FishGroupImageRecognitionService;  
10 import io.swagger.annotations.Api; 7 import io.swagger.annotations.Api;
11 import io.swagger.annotations.ApiOperation; 8 import io.swagger.annotations.ApiOperation;
12 -import org.ehcache.Cache;  
13 import org.springframework.beans.factory.annotation.Autowired; 9 import org.springframework.beans.factory.annotation.Autowired;
14 import org.springframework.web.bind.annotation.*; 10 import org.springframework.web.bind.annotation.*;
15 11
16 -import java.util.Iterator;  
17 import java.util.List; 12 import java.util.List;
18 import java.util.Map; 13 import java.util.Map;
19 14
@@ -30,14 +25,10 @@ public class ConfigController { @@ -30,14 +25,10 @@ public class ConfigController {
30 public AjaxResult all() 25 public AjaxResult all()
31 { 26 {
32 AjaxResult ajaxResult = AjaxResult.success(); 27 AjaxResult ajaxResult = AjaxResult.success();
33 - Cache<String, Object> cache = configurationParameterService.getAll();  
34 - Iterator<Cache.Entry<String, Object>> iterator = cache.iterator();  
35 - while (iterator.hasNext()) {  
36 - Cache.Entry<String, Object> entry = iterator.next();  
37 - String key = entry.getKey();  
38 - Object value = entry.getValue(); 28 + Map<String, Object> cache = configurationParameterService.getAll();
  29 + for (String key:cache.keySet()) {
39 // Process the key and value as needed. 30 // Process the key and value as needed.
40 - ajaxResult.put(key,value); 31 + ajaxResult.put(key,cache.get(key));
41 } 32 }
42 return ajaxResult; 33 return ajaxResult;
43 } 34 }
  1 +package com.zhonglai.luhui.smart.feeder.controller;
  2 +
  3 +import com.fazecast.jSerialComm.SerialPort;
  4 +import com.ruoyi.common.core.domain.AjaxResult;
  5 +import com.zhonglai.luhui.smart.feeder.dto.ConfigDto;
  6 +import com.zhonglai.luhui.smart.feeder.dto.commd.*;
  7 +import com.zhonglai.luhui.smart.feeder.service.DeviceService;
  8 +import com.zhonglai.luhui.smart.feeder.service.SerialPortService;
  9 +import io.swagger.annotations.Api;
  10 +import io.swagger.annotations.ApiOperation;
  11 +import org.springframework.beans.factory.annotation.Autowired;
  12 +import org.springframework.web.bind.annotation.*;
  13 +
  14 +@Api(tags = "串口管理")
  15 +@RestController
  16 +@RequestMapping("/serialPort")
  17 +public class SerialPortController {
  18 + @Autowired
  19 + private SerialPortService serialPortService;
  20 + @ApiOperation("打开")
  21 + @PostMapping("/open")
  22 + public AjaxResult open(Integer baudrate)
  23 + {
  24 + return AjaxResult.success(serialPortService.open());
  25 + }
  26 +
  27 + @ApiOperation("发送16进制")
  28 + @GetMapping("/sendHexData")
  29 + public AjaxResult sendHexData(String hexStr)
  30 + {
  31 + return AjaxResult.success(serialPortService.sendHexData(hexStr));
  32 + }
  33 +
  34 + @ApiOperation("发送字符串")
  35 + @GetMapping("/sendStrData")
  36 + public AjaxResult sendStrData(String str)
  37 + {
  38 + return AjaxResult.success(serialPortService.sendStrData(str));
  39 + }
  40 +
  41 + @ApiOperation("读取")
  42 + @GetMapping("/read")
  43 + public AjaxResult read(Integer start_char,Integer char_lenth)
  44 + {
  45 + return AjaxResult.success(serialPortService.sendHexData(new FeederCommdDto(new FeederCommd03Response(start_char,char_lenth)).getHstr()));
  46 + }
  47 +
  48 + @ApiOperation("单独写入")
  49 + @GetMapping("/write")
  50 + public AjaxResult write(Integer register_address,Integer value)
  51 + {
  52 + return AjaxResult.success(serialPortService.sendHexData(new FeederCommdDto(new FeederCommd06Response(register_address,value)).getHstr()));
  53 + }
  54 +
  55 +}
@@ -20,6 +20,7 @@ public enum ConfigurationParameter { @@ -20,6 +20,7 @@ public enum ConfigurationParameter {
20 VeiwDto_isSize(false, Boolean.class,"sys_config","是否显示面积",true), //是否显示面积 20 VeiwDto_isSize(false, Boolean.class,"sys_config","是否显示面积",true), //是否显示面积
21 VeiwDto_isAbsValue(false, Boolean.class,"sys_config","是否显示斜率",true), //是否显示斜率 21 VeiwDto_isAbsValue(false, Boolean.class,"sys_config","是否显示斜率",true), //是否显示斜率
22 absValue(0.0, Double.class,"sys_config","显示斜率",false), //斜率 22 absValue(0.0, Double.class,"sys_config","显示斜率",false), //斜率
  23 + IdentificationFrequency(1000l, Long.class,"sys_config","鱼群图像识别的频率(单位秒)",true), //鱼群图像识别的频率
23 FishGroupImageRecognition(true, Boolean.class,"sys_config","鱼群图像识别是否开启",true), //鱼群图像识别是否开启 24 FishGroupImageRecognition(true, Boolean.class,"sys_config","鱼群图像识别是否开启",true), //鱼群图像识别是否开启
24 FeedingControl(true, Boolean.class,"sys_config","鱼群图像识别控制投料控制是否开启",true), //鱼群图像识别投料控制是否开启 25 FeedingControl(true, Boolean.class,"sys_config","鱼群图像识别控制投料控制是否开启",true), //鱼群图像识别投料控制是否开启
25 SerialPortConfig(new SerialPortConfig().defaultSerialPortConfig(),com.zhonglai.luhui.smart.feeder.dto.SerialPortConfig.class,"sys_config","串口配置",true),//串口配置 26 SerialPortConfig(new SerialPortConfig().defaultSerialPortConfig(),com.zhonglai.luhui.smart.feeder.dto.SerialPortConfig.class,"sys_config","串口配置",true),//串口配置
1 -package com.zhonglai.luhui.smart.feeder.dto;  
2 -  
3 -import org.ehcache.spi.serialization.Serializer;  
4 -import org.ehcache.spi.serialization.SerializerException;  
5 -  
6 -import java.io.*;  
7 -import java.nio.ByteBuffer;  
8 -  
9 -public class MyCustomSerializer implements Serializer<Object>{  
10 - private final ClassLoader classLoader;  
11 -  
12 - public MyCustomSerializer(ClassLoader classLoader) {  
13 - this.classLoader = classLoader;  
14 - }  
15 -  
16 - @Override  
17 - public ByteBuffer serialize(Object object) throws SerializerException {  
18 - try {  
19 - ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();  
20 - ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);  
21 - objectOutputStream.writeObject(object);  
22 - objectOutputStream.flush();  
23 - return ByteBuffer.wrap(byteArrayOutputStream.toByteArray());  
24 - } catch (IOException e) {  
25 - throw new SerializerException(e);  
26 - }  
27 - }  
28 -  
29 - @Override  
30 - public Object read(ByteBuffer byteBuffer) throws ClassNotFoundException, SerializerException {  
31 - try {  
32 - ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteBuffer.array());  
33 - ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);  
34 - return objectInputStream.readObject();  
35 - } catch (IOException e) {  
36 - throw new SerializerException(e);  
37 - }  
38 - }  
39 -  
40 - @Override  
41 - public boolean equals(Object o, ByteBuffer byteBuffer) throws ClassNotFoundException, SerializerException {  
42 - return o.equals(read(byteBuffer));  
43 - }  
44 -}  
@@ -9,14 +9,15 @@ import java.util.Map; @@ -9,14 +9,15 @@ import java.util.Map;
9 public class FeederCommd03Request implements FeederCommd { 9 public class FeederCommd03Request implements FeederCommd {
10 private static final long serialVersionUID = 200980498094314547L; 10 private static final long serialVersionUID = 200980498094314547L;
11 private Integer lenth; 11 private Integer lenth;
12 - private Map<Integer,byte[]> addressValue = new HashMap<>(); 12 + private Map<Integer,Long> addressValue = new HashMap<>();
13 public FeederCommd03Request(byte[] data) 13 public FeederCommd03Request(byte[] data)
14 { 14 {
15 lenth = new Long(ByteUtil.bytesToLongDESC(data,0,1)).intValue()/2; 15 lenth = new Long(ByteUtil.bytesToLongDESC(data,0,1)).intValue()/2;
16 for (int i=0;i<lenth;i++) 16 for (int i=0;i<lenth;i++)
17 { 17 {
18 byte[] bytes = ArrayUtils.subarray(data,1+2*i,1+2*i+2); 18 byte[] bytes = ArrayUtils.subarray(data,1+2*i,1+2*i+2);
19 - addressValue.put(i, bytes); 19 +
  20 + addressValue.put(i,ByteUtil.bytesToLongDESC(bytes,0,2));
20 } 21 }
21 } 22 }
22 23
@@ -28,11 +29,11 @@ public class FeederCommd03Request implements FeederCommd { @@ -28,11 +29,11 @@ public class FeederCommd03Request implements FeederCommd {
28 this.lenth = lenth; 29 this.lenth = lenth;
29 } 30 }
30 31
31 - public Map<Integer, byte[]> getAddressValue() { 32 + public Map<Integer, Long> getAddressValue() {
32 return addressValue; 33 return addressValue;
33 } 34 }
34 35
35 - public void setAddressValue(Map<Integer, byte[]> addressValue) { 36 + public void setAddressValue(Map<Integer, Long> addressValue) {
36 this.addressValue = addressValue; 37 this.addressValue = addressValue;
37 } 38 }
38 } 39 }
@@ -72,6 +72,28 @@ public class OpenCVUtil { @@ -72,6 +72,28 @@ public class OpenCVUtil {
72 return null; 72 return null;
73 } 73 }
74 74
  75 + public static VideoCapture openCapture()
  76 + {
  77 + for(int i=0;i<10;i++)
  78 + {
  79 + try {
  80 + Thread.sleep(3000);
  81 + } catch (InterruptedException e) {
  82 + throw new RuntimeException(e);
  83 + }
  84 + VideoCapture videoCapture = new VideoCapture();
  85 + boolean isopen = videoCapture.open(i);
  86 + if(isopen)
  87 + {
  88 + logger.info("打开化摄像头"+i+"成功");
  89 + return videoCapture;
  90 + }else {
  91 + logger.info("打开化摄像头"+i+"失败");
  92 + }
  93 + }
  94 + return null;
  95 + }
  96 +
75 public static VideoCapture readVideoCaptureForVideo(String videoPath ) 97 public static VideoCapture readVideoCaptureForVideo(String videoPath )
76 { 98 {
77 // 创建VideoCapture对象 99 // 创建VideoCapture对象
@@ -43,10 +43,10 @@ public class AnalysisDataService { @@ -43,10 +43,10 @@ public class AnalysisDataService {
43 Map<String,Object> valueMap = new HashMap<>(); 43 Map<String,Object> valueMap = new HashMap<>();
44 44
45 FeederCommd03Request feederCommd03Request = (FeederCommd03Request) feederCommd; 45 FeederCommd03Request feederCommd03Request = (FeederCommd03Request) feederCommd;
46 - Map<Integer, byte[]> map = feederCommd03Request.getAddressValue(); 46 + Map<Integer,Long> map = feederCommd03Request.getAddressValue();
47 for (Integer adrress:map.keySet()) 47 for (Integer adrress:map.keySet())
48 { 48 {
49 - byte[] bytes = map.get(adrress); 49 + Long bytes = map.get(adrress);
50 List<Register> registers = configMap.get(adrress); 50 List<Register> registers = configMap.get(adrress);
51 if(null != registers) 51 if(null != registers)
52 { 52 {
@@ -61,7 +61,7 @@ public class AnalysisDataService { @@ -61,7 +61,7 @@ public class AnalysisDataService {
61 61
62 } 62 }
63 }else{ 63 }else{
64 - logger.error("未读取到"+adrress+"的地址读取配置"); 64 + logger.debug("未读取到"+adrress+"的地址读取配置");
65 } 65 }
66 66
67 } 67 }
@@ -74,11 +74,11 @@ public class AnalysisDataService { @@ -74,11 +74,11 @@ public class AnalysisDataService {
74 } 74 }
75 75
76 76
77 - private void registerTo(Map<String,Object> valueMap,byte[] bytes,Register register) 77 + private void registerTo(Map<String,Object> valueMap,Long bytes,Register register)
78 { 78 {
79 String field = register.getField_name(); 79 String field = register.getField_name();
80 80
81 - long value = ByteUtil.readBits(ByteUtil.bytesToLongDESC(bytes,0,2),register.getStart_char(),register.getChar_lenth()); 81 + long value = ByteUtil.readBits(bytes,register.getStart_char(),register.getChar_lenth());
82 82
83 switch (register.getClas()) 83 switch (register.getClas())
84 { 84 {
@@ -37,7 +37,12 @@ public class CameraService { @@ -37,7 +37,12 @@ public class CameraService {
37 */ 37 */
38 private void openCapture() 38 private void openCapture()
39 { 39 {
40 - videoCapture = OpenCVUtil.readVideoCaptureForVideo((Integer) configurationParameterService.getConfig(ConfigurationParameter.captureNumber)); 40 +// videoCapture = OpenCVUtil.readVideoCaptureForVideo((Integer) configurationParameterService.getConfig(ConfigurationParameter.captureNumber));
  41 + videoCapture = OpenCVUtil.openCapture();
  42 + if(null == videoCapture)
  43 + {
  44 + return;
  45 + }
41 monitorCapture(); 46 monitorCapture();
42 47
43 // if (!videoIsOpen) 48 // if (!videoIsOpen)
@@ -5,7 +5,6 @@ import com.zhonglai.luhui.smart.feeder.domain.Register; @@ -5,7 +5,6 @@ import com.zhonglai.luhui.smart.feeder.domain.Register;
5 import com.zhonglai.luhui.smart.feeder.dto.ConfigurationParameter; 5 import com.zhonglai.luhui.smart.feeder.dto.ConfigurationParameter;
6 import com.zhonglai.luhui.smart.feeder.dto.FishCurveControlCondition; 6 import com.zhonglai.luhui.smart.feeder.dto.FishCurveControlCondition;
7 import com.zhonglai.luhui.smart.feeder.dto.StateData; 7 import com.zhonglai.luhui.smart.feeder.dto.StateData;
8 -import org.ehcache.Cache;  
9 import org.springframework.beans.factory.annotation.Autowired; 8 import org.springframework.beans.factory.annotation.Autowired;
10 import org.springframework.stereotype.Service; 9 import org.springframework.stereotype.Service;
11 10
@@ -21,7 +20,9 @@ import java.util.Map; @@ -21,7 +20,9 @@ import java.util.Map;
21 @Service 20 @Service
22 public class ConfigurationParameterService { 21 public class ConfigurationParameterService {
23 22
24 - private Map<Integer,List<Register>> registerMap = new HashMap<>(); 23 + private Map<Integer,List<Register>> registerMap = new HashMap<>(); //解析的数据字典
  24 +
  25 + private Map<String,Register> controlMap = new HashMap<>(); //控制的数据字典
25 26
26 @Autowired 27 @Autowired
27 private EhCacheService ehCacheService; 28 private EhCacheService ehCacheService;
@@ -67,10 +68,17 @@ public class ConfigurationParameterService { @@ -67,10 +68,17 @@ public class ConfigurationParameterService {
67 } 68 }
68 list.add(register); 69 list.add(register);
69 } 70 }
  71 +
  72 + for (Map<String,Object> map:registerList)
  73 + {
  74 + Register register = BeanUtil.mapToBean(map,Register.class,false,null);
  75 + controlMap.put(register.getField_name(),register);
70 } 76 }
71 } 77 }
72 78
73 - public Cache<String, Object> getAll() 79 + }
  80 +
  81 + public Map<String, Object> getAll()
74 { 82 {
75 return ehCacheService.getMyCache(); 83 return ehCacheService.getMyCache();
76 } 84 }
@@ -167,6 +175,10 @@ public class ConfigurationParameterService { @@ -167,6 +175,10 @@ public class ConfigurationParameterService {
167 return registerMap; 175 return registerMap;
168 } 176 }
169 177
  178 + public Map<String, Register> getControlMap() {
  179 + return controlMap;
  180 + }
  181 +
170 public StateData getStateData() { 182 public StateData getStateData() {
171 return stateData; 183 return stateData;
172 } 184 }
@@ -32,7 +32,7 @@ public class DateListenService { @@ -32,7 +32,7 @@ public class DateListenService {
32 private ScheduledExecutorService scheduledExecutorService; 32 private ScheduledExecutorService scheduledExecutorService;
33 33
34 @Autowired 34 @Autowired
35 - private DeviceService deviceService; 35 + private SerialPortService serialPortService;
36 36
37 @Autowired 37 @Autowired
38 private AnalysisDataService analysisDataService; 38 private AnalysisDataService analysisDataService;
@@ -47,18 +47,12 @@ public class DateListenService { @@ -47,18 +47,12 @@ public class DateListenService {
47 { 47 {
48 scheduledExecutorService.scheduleAtFixedRate(() -> { 48 scheduledExecutorService.scheduleAtFixedRate(() -> {
49 49
50 - if(!(Boolean) configurationParameterService.getConfig(ConfigurationParameter.ifUpLoadData)) 50 + if(null == configurationParameterService.getConfig(ConfigurationParameter.ifUpLoadData) || !(Boolean) configurationParameterService.getConfig(ConfigurationParameter.ifUpLoadData))
51 { 51 {
52 return; 52 return;
53 } 53 }
54 try { 54 try {
55 - deviceService.openDefaultSerialPort();  
56 - } catch (Exception e) {  
57 - logger.error("串口打开失败",e);  
58 - return;  
59 - }  
60 - try {  
61 - ModbusDto modbusDto = deviceService.sendData(FeederCommdUtil.readAll()); 55 + ModbusDto modbusDto = serialPortService.sendHexData(FeederCommdUtil.readAll());
62 Map<String,Object> data = analysisDataService.analysis(modbusDto); 56 Map<String,Object> data = analysisDataService.analysis(modbusDto);
63 if(null != data && data.size() != 0) 57 if(null != data && data.size() != 0)
64 { 58 {
1 package com.zhonglai.luhui.smart.feeder.service; 1 package com.zhonglai.luhui.smart.feeder.service;
2 2
3 import com.ruoyi.common.utils.GsonConstructor; 3 import com.ruoyi.common.utils.GsonConstructor;
4 -import com.ruoyi.common.utils.StringUtils;  
5 import com.zhonglai.luhui.smart.feeder.dto.*; 4 import com.zhonglai.luhui.smart.feeder.dto.*;
6 -import com.zhonglai.luhui.smart.feeder.dto.commd.FeederCommdDto;  
7 import com.zhonglai.luhui.smart.feeder.util.FeederCommd06ResponseType; 5 import com.zhonglai.luhui.smart.feeder.util.FeederCommd06ResponseType;
8 import com.zhonglai.luhui.smart.feeder.util.FeederCommdUtil; 6 import com.zhonglai.luhui.smart.feeder.util.FeederCommdUtil;
9 -import com.zhonglai.luhui.smart.feeder.util.serial.SerialTool;  
10 import org.slf4j.Logger; 7 import org.slf4j.Logger;
11 import org.slf4j.LoggerFactory; 8 import org.slf4j.LoggerFactory;
12 import org.springframework.beans.factory.annotation.Autowired; 9 import org.springframework.beans.factory.annotation.Autowired;
13 import org.springframework.stereotype.Service; 10 import org.springframework.stereotype.Service;
14 -import purejavacomm.SerialPort;  
15 11
16 -import javax.annotation.PostConstruct;  
17 -import java.io.IOException;  
18 -import java.io.OutputStream;  
19 import java.util.*; 12 import java.util.*;
20 -import java.util.concurrent.BlockingQueue;  
21 -import java.util.concurrent.LinkedBlockingQueue;  
22 import java.util.concurrent.ScheduledExecutorService; 13 import java.util.concurrent.ScheduledExecutorService;
23 import java.util.concurrent.TimeUnit; 14 import java.util.concurrent.TimeUnit;
24 15
@@ -29,11 +20,6 @@ import java.util.concurrent.TimeUnit; @@ -29,11 +20,6 @@ import java.util.concurrent.TimeUnit;
29 public class DeviceService { 20 public class DeviceService {
30 private static Logger logger = LoggerFactory.getLogger(DeviceService.class); 21 private static Logger logger = LoggerFactory.getLogger(DeviceService.class);
31 22
32 - // 锁对象  
33 - private final Object lock = new Object();  
34 - // 用于存储串口返回的数据,使用线程安全的队列  
35 - private BlockingQueue<ModbusDto> dataQueue = new LinkedBlockingQueue<>();  
36 -  
37 private Double backArea; //上一个大小 23 private Double backArea; //上一个大小
38 24
39 private Double slope; //斜率 25 private Double slope; //斜率
@@ -57,7 +43,8 @@ public class DeviceService { @@ -57,7 +43,8 @@ public class DeviceService {
57 @Autowired 43 @Autowired
58 private EhCacheService ehCacheService; 44 private EhCacheService ehCacheService;
59 45
60 - private SerialPort serialPort; 46 + @Autowired
  47 + private SerialPortService serialPortService;
61 48
62 public void run() 49 public void run()
63 { 50 {
@@ -72,22 +59,22 @@ public class DeviceService { @@ -72,22 +59,22 @@ public class DeviceService {
72 { 59 {
73 if(null !=configurationParameterService.getStateData() && 1==configurationParameterService.getStateData().getRunmode()) 60 if(null !=configurationParameterService.getStateData() && 1==configurationParameterService.getStateData().getRunmode())
74 { 61 {
75 - send485SerialData(FeederCommdUtil.controlData(FeederCommd06ResponseType.runmode,0)); //,运行模式改成手动 62 + serialPortService.sendHexData(FeederCommdUtil.controlData(FeederCommd06ResponseType.runmode,0)); //,运行模式改成手动
76 } 63 }
77 if(null !=configurationParameterService.getStateData() && 0==configurationParameterService.getStateData().getSwitch_status()) 64 if(null !=configurationParameterService.getStateData() && 0==configurationParameterService.getStateData().getSwitch_status())
78 { 65 {
79 - send485SerialData(FeederCommdUtil.controlData(FeederCommd06ResponseType.OnOroff,1)); //,开关是关的就先打开开关 66 + serialPortService.sendHexData(FeederCommdUtil.controlData(FeederCommd06ResponseType.OnOroff,1)); //,开关是关的就先打开开关
80 } 67 }
81 - send485SerialData(FeederCommdUtil.controlData(FeederCommd06ResponseType.runspeed,nowGear)); 68 + serialPortService.sendHexData(FeederCommdUtil.controlData(FeederCommd06ResponseType.runspeed,nowGear));
82 oldGear = nowGear; 69 oldGear = nowGear;
83 }else{ 70 }else{
84 if(null !=configurationParameterService.getStateData() && 0==configurationParameterService.getStateData().getRunmode()) 71 if(null !=configurationParameterService.getStateData() && 0==configurationParameterService.getStateData().getRunmode())
85 { 72 {
86 - send485SerialData(FeederCommdUtil.controlData(FeederCommd06ResponseType.runmode,1)); //,运行模式改成自动 73 + serialPortService.sendHexData(FeederCommdUtil.controlData(FeederCommd06ResponseType.runmode,1)); //,运行模式改成自动
87 } 74 }
88 if(null !=configurationParameterService.getStateData() && 1==configurationParameterService.getStateData().getSwitch_status()) 75 if(null !=configurationParameterService.getStateData() && 1==configurationParameterService.getStateData().getSwitch_status())
89 { 76 {
90 - send485SerialData(FeederCommdUtil.controlData(FeederCommd06ResponseType.OnOroff,0)); //,开关是关的就先打开开关 77 + serialPortService.sendHexData(FeederCommdUtil.controlData(FeederCommd06ResponseType.OnOroff,0)); //,开关是关的就先打开开关
91 } 78 }
92 } 79 }
93 80
@@ -137,20 +124,6 @@ public class DeviceService { @@ -137,20 +124,6 @@ public class DeviceService {
137 return absValue; 124 return absValue;
138 } 125 }
139 126
140 - private void send485SerialData(String commd)  
141 - {  
142 - if(null == serialPort)  
143 - {  
144 - openSerialPort();  
145 - }  
146 -  
147 - try {  
148 - sendData(commd);  
149 - } catch (IOException e) {  
150 - logger.error("串口指令发送错误",e);  
151 - }  
152 - }  
153 -  
154 /** 127 /**
155 * 根据斜率计算档位 128 * 根据斜率计算档位
156 * @return 129 * @return
@@ -174,107 +147,4 @@ public class DeviceService { @@ -174,107 +147,4 @@ public class DeviceService {
174 return gear; 147 return gear;
175 } 148 }
176 149
177 - public void openSerialPort()  
178 - {  
179 - SerialPortConfig serialPortConfig = (SerialPortConfig) configurationParameterService.getConfig(ConfigurationParameter.SerialPortConfig);  
180 - try {  
181 - openSerialPort(serialPortConfig.getPortName(),serialPortConfig.getBaudrate(),serialPortConfig.getDataBits(),serialPortConfig.getStopBits(),serialPortConfig.getParity());  
182 - } catch (Exception e) {  
183 - throw new RuntimeException(e);  
184 - }  
185 - }  
186 -  
187 -  
188 - /**  
189 - * 获取所有串口  
190 - * @return  
191 - */  
192 - public ArrayList<String> getAllSerial()  
193 - {  
194 - return SerialTool.findPorts();  
195 - }  
196 -  
197 - /**  
198 - * 打开串口  
199 - * @param portName 串口名称  
200 - * @param baudrate 波特率,用于指定每秒传输的位数。  
201 - * @param dataBits 数据位,表示每个字节的位数。常见的值为 5、6、7、8。  
202 - * @param stopBits 停止位,用于指定每个字节的停止位数。  
203 - * @param parity 校验位,用于验证数据的正确性。常见的值有 NONE(无校验)、ODD(奇校验)、EVEN(偶校验)等。  
204 - * @throws Exception  
205 - */  
206 - public void openSerialPort(String portName, Integer baudrate, Integer dataBits, Integer stopBits,  
207 - Integer parity) throws Exception {  
208 - if(null != serialPort)  
209 - {  
210 - return;  
211 - }  
212 - serialPort = SerialTool.openPort(portName,baudrate,dataBits,stopBits,parity);  
213 - SerialTool.addListener(serialPortEvent -> {  
214 - try {  
215 - Thread.sleep(500);  
216 - FeederCommdDto commdDto = new FeederCommdDto (SerialTool.readFromPort(serialPort));  
217 - dataQueue.offer(commdDto); // 将数据添加到队列中// 处理串口返回的数据  
218 - } catch (Exception e) {  
219 - logger.error("返回数据处理异常",e);  
220 - }  
221 - }, serialPort);  
222 - logger.info("打开串口成功");  
223 - }  
224 -  
225 - public void nowOpenSerial(String portName, Integer baudrate, Integer dataBits, Integer stopBits,  
226 - Integer parity) throws Exception {  
227 - if(null != serialPort)  
228 - {  
229 - serialPort.removeEventListener();  
230 - serialPort.close();  
231 - }  
232 - serialPort = SerialTool.openPort(portName,baudrate,dataBits,stopBits,parity);  
233 - SerialTool.addListener(serialPortEvent -> {  
234 - try {  
235 - Thread.sleep(500);  
236 - FeederCommdDto commdDto = new FeederCommdDto (SerialTool.readFromPort(serialPort));  
237 - dataQueue.offer(commdDto); // 将数据添加到队列中// 处理串口返回的数据  
238 - } catch (Exception e) {  
239 - logger.error("返回数据处理异常",e);  
240 - }  
241 - }, serialPort);  
242 -  
243 - }  
244 -  
245 - public void openDefaultSerialPort() throws Exception {  
246 - SerialPortConfig serialPortConfig = (SerialPortConfig) configurationParameterService.getConfig(ConfigurationParameter.SerialPortConfig);  
247 - openSerialPort(serialPortConfig.getPortName(),serialPortConfig.getBaudrate(),serialPortConfig.getDataBits(),serialPortConfig.getStopBits(),serialPortConfig.getParity());  
248 - }  
249 -  
250 - /**  
251 - * 发送数据  
252 - * @param hexStr  
253 - * @throws IOException  
254 - */  
255 - public ModbusDto sendData(String hexStr) throws IOException {  
256 - synchronized (lock)  
257 - {  
258 - SerialTool.sendToPort(SerialTool.HexString2Bytes(hexStr),serialPort);  
259 - try {  
260 - ModbusDto reStr = dataQueue.poll(15,TimeUnit.SECONDS);  
261 - return reStr;  
262 - } catch (InterruptedException e) {  
263 - logger.error("等待串口返回数据异常!" + e);  
264 - }  
265 - }  
266 - return null;  
267 - }  
268 -  
269 -  
270 - public void close()  
271 - {  
272 - dataQueue.clear();  
273 - if(null != serialPort)  
274 - {  
275 - serialPort.removeEventListener();  
276 - serialPort.close();  
277 - }  
278 - }  
279 -  
280 } 150 }
@@ -3,86 +3,43 @@ package com.zhonglai.luhui.smart.feeder.service; @@ -3,86 +3,43 @@ package com.zhonglai.luhui.smart.feeder.service;
3 import com.ruoyi.common.utils.GsonConstructor; 3 import com.ruoyi.common.utils.GsonConstructor;
4 import com.zhonglai.luhui.smart.feeder.dto.ConfigurationParameter; 4 import com.zhonglai.luhui.smart.feeder.dto.ConfigurationParameter;
5 import com.zhonglai.luhui.smart.feeder.dto.SerialPortConfig; 5 import com.zhonglai.luhui.smart.feeder.dto.SerialPortConfig;
6 -import org.ehcache.Cache;  
7 -import org.ehcache.CacheManager;  
8 -import org.ehcache.config.CacheConfiguration;  
9 -import org.ehcache.config.ResourcePools;  
10 -import org.ehcache.config.builders.CacheConfigurationBuilder;  
11 -import org.ehcache.config.builders.CacheManagerBuilder;  
12 -import org.ehcache.config.builders.ResourcePoolsBuilder;  
13 -import org.ehcache.config.units.MemoryUnit;  
14 -import org.ehcache.impl.serialization.PlainJavaSerializer;  
15 -import org.springframework.beans.factory.annotation.Value;  
16 import org.springframework.stereotype.Service; 6 import org.springframework.stereotype.Service;
17 7
18 -import javax.annotation.PostConstruct;  
19 -import java.io.File;  
20 -import java.time.Duration; 8 +import java.util.HashMap;
  9 +import java.util.Map;
21 10
22 /** 11 /**
23 * 缓存 12 * 缓存
24 */ 13 */
25 @Service 14 @Service
26 public class EhCacheService { 15 public class EhCacheService {
27 - private static Cache<String, Object> myCache; 16 + private static Map<String,Object> cacheMap = new HashMap<>();
28 17
29 - private static CacheManager cacheManager;  
30 -  
31 - public static final String MY_CACHE = "myCache";  
32 -  
33 - @Value("${sys.cacheFilePath}")  
34 - private String cacheFilePath;  
35 -  
36 - public void instance()  
37 - {  
38 - cacheManager = CacheManagerBuilder.newCacheManagerBuilder()  
39 - .with(CacheManagerBuilder.persistence(new File(cacheFilePath)))  
40 - .build(true);  
41 -  
42 - if (cacheManager.getRuntimeConfiguration().getCacheConfigurations().containsKey(MY_CACHE))  
43 - {  
44 - // 缓存对象存在,直接读取  
45 - myCache = cacheManager.getCache(MY_CACHE, String.class, Object.class);  
46 - }else {  
47 -  
48 - // 指定缓存的存储形式,采用多级缓存,并开启缓存持久化操作  
49 - ResourcePools resourcePools = ResourcePoolsBuilder.newResourcePoolsBuilder()  
50 - .heap(1, MemoryUnit.MB)  
51 - .disk(2, MemoryUnit.MB, true)  
52 - .build();  
53 - // 封装缓存配置对象,指定了键值类型、指定了使用TTL与TTI联合的过期淘汰策略  
54 - CacheConfiguration<String, Object> cacheConfiguration =  
55 - CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, Object.class, resourcePools)  
56 - .withValueSerializer(new PlainJavaSerializer<>(this.getClass().getClassLoader()))  
57 - .build();  
58 -  
59 - // 使用给定的配置参数,创建指定名称的缓存对象  
60 - myCache = cacheManager.createCache(MY_CACHE, cacheConfiguration);  
61 - }  
62 -  
63 - }  
64 18
65 public void writeToCache(ConfigurationParameter key, Object value) { 19 public void writeToCache(ConfigurationParameter key, Object value) {
66 Class cls = key.getValuType(); 20 Class cls = key.getValuType();
67 if(cls.isInstance(value)) 21 if(cls.isInstance(value))
68 { 22 {
69 - myCache.put(key.name(), cls.cast(value)); 23 + cacheMap.put(key.name(), cls.cast(value));
70 }else if(value instanceof String) 24 }else if(value instanceof String)
71 { 25 {
72 switch (cls.getName()) 26 switch (cls.getName())
73 { 27 {
74 case "java.lang.Boolean": 28 case "java.lang.Boolean":
75 - myCache.put(key.name(), Boolean.valueOf((String) value)); 29 + cacheMap.put(key.name(), Boolean.valueOf((String) value));
76 return; 30 return;
77 case "java.lang.Integer": 31 case "java.lang.Integer":
78 - myCache.put(key.name(), Integer.valueOf((String) value)); 32 + cacheMap.put(key.name(), Integer.valueOf((String) value));
79 return; 33 return;
80 case "java.lang.Double": 34 case "java.lang.Double":
81 - myCache.put(key.name(), Double.valueOf((String) value)); 35 + cacheMap.put(key.name(), Double.valueOf((String) value));
  36 + return;
  37 + case "java.lang.Long":
  38 + cacheMap.put(key.name(), Long.valueOf((String) value));
82 return; 39 return;
83 case "com.zhonglai.luhui.smart.feeder.dto.SerialPortConfig": 40 case "com.zhonglai.luhui.smart.feeder.dto.SerialPortConfig":
84 SerialPortConfig serialPortConfig = GsonConstructor.get().fromJson((String) value,SerialPortConfig.class); 41 SerialPortConfig serialPortConfig = GsonConstructor.get().fromJson((String) value,SerialPortConfig.class);
85 - myCache.put(key.name(), serialPortConfig); 42 + cacheMap.put(key.name(), serialPortConfig);
86 return; 43 return;
87 default: 44 default:
88 throw new RuntimeException("配置参数类型不正确"+key+value); 45 throw new RuntimeException("配置参数类型不正确"+key+value);
@@ -94,16 +51,16 @@ public class EhCacheService { @@ -94,16 +51,16 @@ public class EhCacheService {
94 } 51 }
95 52
96 public Object readFromCache(ConfigurationParameter key) { 53 public Object readFromCache(ConfigurationParameter key) {
97 - return myCache.get(key.name()); 54 + return cacheMap.get(key.name());
98 } 55 }
99 56
100 - public Cache<String, Object> getMyCache() {  
101 - return myCache; 57 + public Map<String, Object> getMyCache() {
  58 + return cacheMap;
102 } 59 }
103 60
104 public void shutdown() { 61 public void shutdown() {
105 - if (cacheManager != null) {  
106 - cacheManager.close(); 62 + if (cacheMap != null) {
  63 + cacheMap.clear();
107 } 64 }
108 } 65 }
109 } 66 }
1 -package com.zhonglai.luhui.smart.feeder.service;  
2 -  
3 -import org.springframework.stereotype.Service;  
4 -  
5 -@Service  
6 -public class FeederDeviceService {  
7 -  
8 -}  
1 package com.zhonglai.luhui.smart.feeder.service; 1 package com.zhonglai.luhui.smart.feeder.service;
2 2
  3 +import com.zhonglai.luhui.smart.feeder.config.WebSocketClien;
3 import com.zhonglai.luhui.smart.feeder.dto.ConfigurationParameter; 4 import com.zhonglai.luhui.smart.feeder.dto.ConfigurationParameter;
4 import com.zhonglai.luhui.smart.feeder.dto.VeiwDto; 5 import com.zhonglai.luhui.smart.feeder.dto.VeiwDto;
5 import com.zhonglai.luhui.smart.feeder.dto.VeiwType; 6 import com.zhonglai.luhui.smart.feeder.dto.VeiwType;
@@ -137,23 +138,27 @@ public class FishGroupImageRecognitionService { @@ -137,23 +138,27 @@ public class FishGroupImageRecognitionService {
137 logger.info("鱼群识别时检测摄像头"); 138 logger.info("鱼群识别时检测摄像头");
138 // 获取水域轮廓 139 // 获取水域轮廓
139 MatOfPoint largestContour = getDefaultMatOfPoint(previousFrame); 140 MatOfPoint largestContour = getDefaultMatOfPoint(previousFrame);
  141 +
  142 + Long time =1000l;
  143 + if(null != configurationParameterService.getConfig(ConfigurationParameter.IdentificationFrequency))
  144 + {
  145 + time = (Long) configurationParameterService.getConfig(ConfigurationParameter.IdentificationFrequency);
  146 + }
140 // 逐帧处理视频 147 // 逐帧处理视频
141 Mat frame = new Mat(); 148 Mat frame = new Mat();
142 scheduledExecutorService.scheduleWithFixedDelay(() -> { 149 scheduledExecutorService.scheduleWithFixedDelay(() -> {
143 - try { 150 + logger.info("逐帧处理视频");
144 if (((Boolean)configurationParameterService.getConfig(ConfigurationParameter.FishGroupImageRecognition)) && videoCapture.read(frame)) { 151 if (((Boolean)configurationParameterService.getConfig(ConfigurationParameter.FishGroupImageRecognition)) && videoCapture.read(frame)) {
  152 + logger.info("开始逐帧处理视频");
145 identify(frame,largestContour); 153 identify(frame,largestContour);
  154 + logger.info("结束逐帧处理视频");
146 } 155 }
147 - }catch (Exception e)  
148 - {  
149 - logger.error("检测摄像头异常",e);  
150 - }  
151 -  
152 - },0,1, TimeUnit.SECONDS); 156 + },0,time, TimeUnit.MILLISECONDS);
153 157
154 } 158 }
155 159
156 160
  161 +
157 /** 162 /**
158 * 识别 163 * 识别
159 * @param frame 164 * @param frame
@@ -190,12 +195,13 @@ public class FishGroupImageRecognitionService { @@ -190,12 +195,13 @@ public class FishGroupImageRecognitionService {
190 configurationParameterService.setConfig(ConfigurationParameter.absValue,absValue); 195 configurationParameterService.setConfig(ConfigurationParameter.absValue,absValue);
191 196
192 // 显示图像 197 // 显示图像
  198 + logger.info("是否显示{},客户端数量{}",configurationParameterService.getConfig(ConfigurationParameter.ifVeiw),WebSocketClien.webSocketSet.size());
193 // 在图像上显示结果 199 // 在图像上显示结果
194 - if((Boolean)configurationParameterService.getConfig(ConfigurationParameter.ifVeiw)) 200 + if((Boolean)configurationParameterService.getConfig(ConfigurationParameter.ifVeiw) && WebSocketClien.webSocketSet.size()>0)
195 { 201 {
  202 + logger.info("socket数量{}",WebSocketClien.webSocketSet.size());
196 dsplayVeiwService.veiw(new VeiwDto(frame,binaryImage,new Double(area).intValue(),absValue)); 203 dsplayVeiwService.veiw(new VeiwDto(frame,binaryImage,new Double(area).intValue(),absValue));
197 } 204 }
198 -  
199 } 205 }
200 206
201 /** 207 /**
@@ -220,8 +226,6 @@ public class FishGroupImageRecognitionService { @@ -220,8 +226,6 @@ public class FishGroupImageRecognitionService {
220 //删除最大 226 //删除最大
221 if(-1 != maxAreaIndex) 227 if(-1 != maxAreaIndex)
222 { 228 {
223 - double area = Imgproc.contourArea(contours.get(maxAreaIndex));  
224 -  
225 contours.remove(maxAreaIndex); 229 contours.remove(maxAreaIndex);
226 } 230 }
227 231
@@ -38,8 +38,6 @@ public class InitService { @@ -38,8 +38,6 @@ public class InitService {
38 */ 38 */
39 @PostConstruct 39 @PostConstruct
40 private void run() throws MqttException { 40 private void run() throws MqttException {
41 - //加载缓存  
42 - ehCacheService.instance();  
43 //持久化初始 41 //持久化初始
44 sqliteService.init(); 42 sqliteService.init();
45 //配置参数 43 //配置参数
@@ -51,7 +49,7 @@ public class InitService { @@ -51,7 +49,7 @@ public class InitService {
51 //鱼群图像识别控制投料控制 49 //鱼群图像识别控制投料控制
52 deviceService.run(); 50 deviceService.run();
53 //连接上报终端 51 //连接上报终端
54 - terminalService.init(); 52 + terminalService.startMqttListenerService();
55 //串口数据上报 53 //串口数据上报
56 dateListenService.run(); 54 dateListenService.run();
57 } 55 }
1 package com.zhonglai.luhui.smart.feeder.service; 1 package com.zhonglai.luhui.smart.feeder.service;
2 2
  3 +import com.google.gson.JsonObject;
  4 +import com.ruoyi.common.utils.GsonConstructor;
  5 +import com.zhonglai.luhui.smart.feeder.domain.Register;
  6 +import com.zhonglai.luhui.smart.feeder.dto.commd.FeederCommd06Response;
  7 +import com.zhonglai.luhui.smart.feeder.dto.commd.FeederCommdDto;
  8 +import com.zhonglai.luhui.smart.feeder.dto.commd.FeederTimer;
  9 +import com.zhonglai.luhui.smart.feeder.util.FeederCommdUtil;
3 import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; 10 import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
4 import org.eclipse.paho.client.mqttv3.MqttCallbackExtended; 11 import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
5 import org.eclipse.paho.client.mqttv3.MqttException; 12 import org.eclipse.paho.client.mqttv3.MqttException;
6 import org.eclipse.paho.client.mqttv3.MqttMessage; 13 import org.eclipse.paho.client.mqttv3.MqttMessage;
7 import org.slf4j.Logger; 14 import org.slf4j.Logger;
8 import org.slf4j.LoggerFactory; 15 import org.slf4j.LoggerFactory;
  16 +import org.springframework.beans.factory.annotation.Autowired;
9 import org.springframework.stereotype.Component; 17 import org.springframework.stereotype.Component;
10 18
  19 +import java.util.HashMap;
  20 +import java.util.List;
  21 +import java.util.Map;
  22 +
11 @Component 23 @Component
12 public class MqttCallback implements MqttCallbackExtended { 24 public class MqttCallback implements MqttCallbackExtended {
13 25
  26 + @Autowired
  27 + private ConfigurationParameterService configurationParameterService;
  28 +
  29 + @Autowired
  30 + private SerialPortService serialPortService;
  31 +
14 private static final Logger log = LoggerFactory.getLogger(MqttCallback.class); 32 private static final Logger log = LoggerFactory.getLogger(MqttCallback.class);
15 33
16 @Override 34 @Override
@@ -26,15 +44,53 @@ public class MqttCallback implements MqttCallbackExtended { @@ -26,15 +44,53 @@ public class MqttCallback implements MqttCallbackExtended {
26 @Override 44 @Override
27 public void messageArrived(String topic, MqttMessage message) throws Exception { 45 public void messageArrived(String topic, MqttMessage message) throws Exception {
28 log.info("收到消息 {}",message); 46 log.info("收到消息 {}",message);
  47 + if(topic.indexOf("PUT")>=0)
  48 + {
  49 + Map<String, Register> map = configurationParameterService.getControlMap();
  50 + byte[] bs = message.getPayload();
  51 + if(null != bs && bs.length!=0)
  52 + {
  53 + String str = new String(bs);
  54 + JsonObject jsonObject = GsonConstructor.get().fromJson(str, JsonObject.class);
  55 + if(jsonObject.has("1"))
  56 + {
  57 + JsonObject controlData = jsonObject.get("1").getAsJsonObject();
  58 +
  59 + Map<Integer, FeederTimer> timerMap = new HashMap<>();
  60 + for (String key:controlData.keySet())
  61 + {
  62 + if(key.startsWith("timer"))
  63 + {
  64 + Integer timerNumber = Integer.parseInt(key.split("_")[0].replace("timer",""));
  65 + FeederTimer feederTimer = timerMap.get(timerNumber);
  66 + if(null == feederTimer)
  67 + {
  68 + feederTimer = new FeederTimer();
  69 + timerMap.put(timerNumber,feederTimer);
  70 + }
  71 +
  72 + feederTimer.setObjectValue(key.replace(""+timerNumber+"",""),Long.valueOf(controlData.get(key).getAsString()));
  73 + }else {
  74 + Register register = map.get(key);
  75 + serialPortService.sendHexData(new FeederCommdDto(new FeederCommd06Response(register.getAddress(),controlData.get(key).getAsInt())).getHstr());
  76 + }
  77 + }
  78 +
  79 + if(null != timerMap && timerMap.size() != 0)
  80 + {
  81 + for (Integer timerNumber:timerMap.keySet())
  82 + {
  83 + serialPortService.sendHexData(FeederCommdUtil.controlTimer(timerNumber,timerMap.get(timerNumber)));
  84 + }
  85 + }
  86 + }
  87 + }
  88 + }
29 } 89 }
30 90
31 @Override 91 @Override
32 public void deliveryComplete(IMqttDeliveryToken token) { 92 public void deliveryComplete(IMqttDeliveryToken token) {
33 // 成功发出消息 93 // 成功发出消息
34 - try {  
35 - log.info("成功发出消息 messageid{}",token.getMessage());  
36 - } catch (MqttException e) {  
37 - e.printStackTrace();  
38 - } 94 + log.info("成功发出消息 messageid{}",token);
39 } 95 }
40 } 96 }
  1 +package com.zhonglai.luhui.smart.feeder.service;
  2 +
  3 +
  4 +import com.fazecast.jSerialComm.SerialPort;
  5 +import com.fazecast.jSerialComm.SerialPortDataListener;
  6 +import com.fazecast.jSerialComm.SerialPortEvent;
  7 +import com.ruoyi.common.utils.ByteUtil;
  8 +import com.zhonglai.luhui.smart.feeder.dto.ConfigurationParameter;
  9 +import com.zhonglai.luhui.smart.feeder.dto.ModbusDto;
  10 +import com.zhonglai.luhui.smart.feeder.dto.SerialPortConfig;
  11 +import com.zhonglai.luhui.smart.feeder.dto.commd.FeederCommdDto;
  12 +import org.slf4j.Logger;
  13 +import org.slf4j.LoggerFactory;
  14 +import org.springframework.beans.factory.annotation.Autowired;
  15 +import org.springframework.stereotype.Service;
  16 +
  17 +import java.io.IOException;
  18 +import java.io.InputStream;
  19 +import java.nio.charset.StandardCharsets;
  20 +import java.util.concurrent.BlockingQueue;
  21 +import java.util.concurrent.LinkedBlockingQueue;
  22 +import java.util.concurrent.TimeUnit;
  23 +
  24 +@Service
  25 +public class SerialPortService {
  26 + private static final Logger logger = LoggerFactory.getLogger(SerialPortService.class);
  27 + private SerialPort serialPort;
  28 +
  29 + // 锁对象
  30 + private final Object lock = new Object();
  31 + // 用于存储串口返回的数据,使用线程安全的队列
  32 + private BlockingQueue<ModbusDto> dataQueue = new LinkedBlockingQueue<>();
  33 + @Autowired
  34 + private ConfigurationParameterService configurationParameterService;
  35 +
  36 + public void init()
  37 + {
  38 + open();
  39 + }
  40 +
  41 + private SerialPort findSerialPort()
  42 + {
  43 + SerialPort serialPort = null;
  44 + SerialPort[] serialPorts = SerialPort.getCommPorts();//查找所有串口
  45 +
  46 + for(SerialPort port:serialPorts){
  47 + System.out.println("Port:"+port.getSystemPortName());//打印串口名称,如COM4
  48 + System.out.println("PortDesc:"+port.getPortDescription());//打印串口类型,如USB Serial
  49 + System.out.println("PortDesc:"+port.getDescriptivePortName());//打印串口的完整类型,如USB-SERIAL CH340(COM4)
  50 + if(port.getPortDescription().indexOf("USB")>=0)
  51 + {
  52 + serialPort = port;
  53 + break;
  54 + }
  55 + }
  56 +
  57 + return serialPort;
  58 + }
  59 +
  60 + private void setComPortParameters()
  61 + {
  62 + SerialPortConfig serialPortConfig = (SerialPortConfig)configurationParameterService.getConfig(ConfigurationParameter.SerialPortConfig);
  63 +
  64 + serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_BLOCKING | SerialPort.TIMEOUT_WRITE_BLOCKING, 1000, 1000);//设置超时
  65 + serialPort.setFlowControl(SerialPort.FLOW_CONTROL_DISABLED);//设置串口的控制流,可以设置为disabled,或者CTS, RTS/CTS, DSR, DTR/DSR, Xon, Xoff, Xon/Xoff等
  66 + serialPort.setComPortParameters(serialPortConfig.getBaudrate(), serialPortConfig.getDataBits(), serialPortConfig.getStopBits(), serialPortConfig.getParity());//一次性设置所有的串口参数,第一个参数为波特率,默认9600;第二个参数为每一位的大小,默认8,可以输入5到8之间的值;第三个参数为停止位大小,只接受内置常量,可以选择(ONE_STOP_BIT, ONE_POINT_FIVE_STOP_BITS, TWO_STOP_BITS);第四位为校验位,同样只接受内置常量,可以选择 NO_PARITY, EVEN_PARITY, ODD_PARITY, MARK_PARITY,SPACE_PARITY。
  67 + }
  68 +
  69 + public boolean open()
  70 + {
  71 + if(null == serialPort || !serialPort.isOpen())
  72 + {
  73 + serialPort = findSerialPort();
  74 + setComPortParameters();
  75 + }
  76 + if(null == serialPort)
  77 + {
  78 + logger.error("没有找到串口");
  79 + return false;
  80 + }
  81 + if(!serialPort.isOpen()){
  82 + boolean isCommOpeded = serialPort.openPort();//判断串口是否打开,如果没打开,就打开串口。打开串口的函数会返回一个boolean值,用于表明串口是否成功打开了
  83 + addLister();
  84 + return isCommOpeded;
  85 + }
  86 + return true;
  87 + }
  88 +
  89 + private void addLister()
  90 + {
  91 + if(serialPort.isOpen()){
  92 + serialPort.addDataListener(new SerialPortDataListener() {//添加监听器。由于该监听器有两个函数,无法使用Lambda表达式
  93 +
  94 + @Override
  95 + public int getListeningEvents() {
  96 + // TODO Auto-generated method stub
  97 + return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;//返回要监听的事件类型,以供回调函数使用。可发回的事件包括:SerialPort.LISTENING_EVENT_DATA_AVAILABLE,SerialPort.LISTENING_EVENT_DATA_WRITTEN,SerialPort.LISTENING_EVENT_DATA_RECEIVED。分别对应有数据在串口(不论是读的还是写的),有数据写入串口,从串口读取数据。如果AVAILABLE和RECEIVED同时被监听,优先触发RECEIVED
  98 + }
  99 +
  100 + @Override
  101 + public void serialEvent(SerialPortEvent event) {//事件处理函数
  102 + // TODO Auto-generated method stub
  103 + String data = "";
  104 + if (event.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE){
  105 + return;//判断事件的类型
  106 + }
  107 + SerialPort port = event.getSerialPort();
  108 +
  109 + try {
  110 + Thread.sleep(500);
  111 + FeederCommdDto commdDto = new FeederCommdDto(readFromPort(port));
  112 + dataQueue.offer(commdDto); // 将数据添加到队列中// 处理串口返回的数据
  113 + } catch (Exception e) {
  114 + logger.error("返回数据处理异常",e);
  115 + }
  116 + }
  117 +
  118 + });
  119 + }
  120 +
  121 + }
  122 + public boolean close()
  123 + {
  124 + dataQueue.clear();
  125 + if(null != serialPort)
  126 + {
  127 + return serialPort.closePort();//关闭串口。该函数同样会返回一个boolean值,表明串口是否成功关闭
  128 + }
  129 + return true;
  130 + }
  131 +
  132 +
  133 + /**
  134 + * 发送16进制数据
  135 + * @param hexStr
  136 + * @throws IOException
  137 + */
  138 + public ModbusDto sendHexData(String hexStr) {
  139 + byte[] bytes = ByteUtil.hexStringToByte(hexStr.replace(" ","").trim().toUpperCase());
  140 + return sendByte(bytes);
  141 + }
  142 +
  143 + /**
  144 + * 发送支持中文的字符串
  145 + * @param str
  146 + * @throws IOException
  147 + */
  148 + public ModbusDto sendStrData(String str) {
  149 + return sendByte(str.getBytes(StandardCharsets.UTF_8));
  150 + }
  151 +
  152 + /**
  153 + * 发送byte数组
  154 + * @param bytes
  155 + * @return
  156 + */
  157 + public ModbusDto sendByte(byte[] bytes)
  158 + {
  159 + synchronized (lock)
  160 + {
  161 + if(open())
  162 + {
  163 + serialPort.writeBytes(bytes,bytes.length);
  164 + try {
  165 + ModbusDto reStr = dataQueue.poll(15, TimeUnit.SECONDS);
  166 + return reStr;
  167 + } catch (InterruptedException e) {
  168 + logger.error("等待串口返回数据异常!" + e);
  169 + }
  170 + }else{
  171 + logger.error("串口未打开!" );
  172 + return null;
  173 + }
  174 +
  175 + }
  176 + return null;
  177 + }
  178 +
  179 + private static byte[] readFromPort(SerialPort serialPort) throws Exception {
  180 +
  181 + InputStream in = null;
  182 + byte[] bytes = null;
  183 +
  184 + try {
  185 + if (serialPort != null) {
  186 + in = serialPort.getInputStream();
  187 + } else {
  188 + return null;
  189 + }
  190 + int bufflenth = in.available(); // 获取buffer里的数据长度
  191 + while (bufflenth > 0) {
  192 + bytes = new byte[bufflenth]; // 初始化byte数组为buffer中数据的长度
  193 + in.read(bytes);
  194 + bufflenth = in.available();
  195 + }
  196 + } catch (Exception e) {
  197 + throw e;
  198 + } finally {
  199 + try {
  200 + if (in != null) {
  201 + in.close();
  202 + }
  203 + } catch (IOException e) {
  204 + throw e;
  205 + }
  206 +
  207 + }
  208 +
  209 + return bytes;
  210 +
  211 + }
  212 +
  213 +
  214 +}
@@ -49,7 +49,6 @@ public class TerminalService { @@ -49,7 +49,6 @@ public class TerminalService {
49 @Value("${mqtt.password}") 49 @Value("${mqtt.password}")
50 private String password; 50 private String password;
51 51
52 - @PostConstruct  
53 public void startMqttListenerService() throws MqttException{ 52 public void startMqttListenerService() throws MqttException{
54 log.info("-----------开始启动mqtt监听服务--------------------"); 53 log.info("-----------开始启动mqtt监听服务--------------------");
55 init(); 54 init();
@@ -108,7 +107,13 @@ public class TerminalService { @@ -108,7 +107,13 @@ public class TerminalService {
108 public void close() 107 public void close()
109 { 108 {
110 try { 109 try {
  110 + options.setAutomaticReconnect(false);
  111 + if(null != mqttclient && mqttclient.isConnected())
  112 + {
  113 + mqttclient.disconnect();
111 mqttclient.close(); 114 mqttclient.close();
  115 + }
  116 +
112 } catch (MqttException e) { 117 } catch (MqttException e) {
113 log.error("关闭失败",e); 118 log.error("关闭失败",e);
114 } 119 }
1 -package com.zhonglai.luhui.smart.feeder.util.serial;  
2 -  
3 -import purejavacomm.SerialPort;  
4 -  
5 -import java.util.HashMap;  
6 -import java.util.Map;  
7 -  
8 -public class GlobalCache {  
9 - public static Map<String,Boolean> bmap = new HashMap<>();  
10 - public static Map<String, byte[]> dmap = new HashMap<>();  
11 -  
12 - public static Map<String, SerialPort> smap = new HashMap<>();  
13 -}  
1 -package com.zhonglai.luhui.smart.feeder.util.serial;  
2 -  
3 -import org.slf4j.Logger;  
4 -import org.slf4j.LoggerFactory;  
5 -import purejavacomm.SerialPort;  
6 -import purejavacomm.SerialPortEvent;  
7 -import purejavacomm.SerialPortEventListener;  
8 -  
9 -import java.io.IOException;  
10 -  
11 -public class SerialResquest {  
12 - private static Logger logger = LoggerFactory.getLogger(SerialResquest.class);  
13 -  
14 -  
15 - public static void resquest(String portName, Integer baudrate, Integer dataBits, Integer stopBits,  
16 - Integer parity,byte[] data) throws Exception {  
17 - SerialPort serialPort;  
18 - if (!GlobalCache.smap.containsKey(portName)) {  
19 - GlobalCache.bmap.put(portName, false);  
20 - serialPort = SerialTool.openPort(portName, baudrate, dataBits, stopBits, parity);  
21 - GlobalCache.smap.put(portName, serialPort);  
22 - SerialTool.addListener(new SerialPortEventListener() {  
23 -  
24 - @Override  
25 - public void serialEvent(SerialPortEvent event) {  
26 - try {  
27 - Thread.sleep(50);  
28 - } catch (InterruptedException e1) {  
29 - logger.error("SerialResquest 监听异常!"+e1);  
30 - }  
31 - switch (event.getEventType()) {  
32 - case SerialPortEvent.DATA_AVAILABLE:  
33 - byte[] readBuffer = null;  
34 - int availableBytes = 0;  
35 - try {  
36 - availableBytes = serialPort.getInputStream().available();  
37 - if (availableBytes > 0) {  
38 - try {  
39 - readBuffer = SerialTool.readFromPort(serialPort);  
40 - GlobalCache.bmap.put(portName, true);  
41 - GlobalCache.dmap.put(portName, readBuffer);  
42 - } catch (Exception e) {  
43 - logger.error("读取推送信息异常!"+e);  
44 - }  
45 - }  
46 - } catch (IOException e) {  
47 - logger.error("读取流信息异常!"+e);  
48 - }  
49 - }  
50 - }  
51 -  
52 - }, serialPort);  
53 - }else {  
54 - serialPort = GlobalCache.smap.get(portName);  
55 - }  
56 - SerialTool.sendToPort(data, serialPort);  
57 - }  
58 -  
59 - public static byte[] response(String portName) throws InterruptedException {  
60 - /*if (!GlobalCache.dmap.containsKey(portName)) {  
61 - return null;  
62 - }*/  
63 - Thread.sleep(100);  
64 - int i =0;  
65 - while (!GlobalCache.bmap.get(portName)) {  
66 - Thread.sleep(100);  
67 - if (i++>30) {  
68 - return new byte[0];  
69 - }  
70 - }  
71 - GlobalCache.bmap.put(portName, false);  
72 - return GlobalCache.dmap.get(portName);  
73 - }  
74 -  
75 - public static void close(String portName) throws IOException {  
76 - SerialTool.closePort(GlobalCache.smap.get(portName));  
77 - GlobalCache.smap.remove(portName);  
78 - }  
79 -}  
1 -package com.zhonglai.luhui.smart.feeder.util.serial;  
2 -  
3 -import java.io.IOException;  
4 -import java.io.InputStream;  
5 -import java.io.OutputStream;  
6 -import java.util.ArrayList;  
7 -import java.util.Enumeration;  
8 -import java.util.TooManyListenersException;  
9 -  
10 -import org.slf4j.Logger;  
11 -import org.slf4j.LoggerFactory;  
12 -  
13 -import purejavacomm.CommPort;  
14 -import purejavacomm.CommPortIdentifier;  
15 -import purejavacomm.NoSuchPortException;  
16 -import purejavacomm.PortInUseException;  
17 -import purejavacomm.SerialPort;  
18 -import purejavacomm.SerialPortEventListener;  
19 -import purejavacomm.UnsupportedCommOperationException;  
20 -  
21 -public class SerialTool {  
22 - private static Logger logger = LoggerFactory.getLogger(SerialTool.class);  
23 -  
24 - public static final ArrayList<String> findPorts() {  
25 - // 获得当前所有可用串口  
26 - Enumeration<CommPortIdentifier> portList = CommPortIdentifier.getPortIdentifiers();  
27 - ArrayList<String> portNameList = new ArrayList<String>();  
28 - // 将可用串口名添加到List并返回该List  
29 - while (portList.hasMoreElements()) {  
30 - String portName = portList.nextElement().getName();  
31 - portNameList.add(portName);  
32 - }  
33 - return portNameList;  
34 - }  
35 -  
36 - /**  
37 - * 打开串口  
38 - *  
39 - * @param portName  
40 - * 端口名称  
41 - * @param baudrate  
42 - * 波特率  
43 - * @return 串口对象  
44 - * @throws Exception  
45 -// * @throws SerialPortParameterFailure  
46 -// * 设置串口参数失败  
47 -// * @throws NotASerialPort  
48 -// * 端口指向设备不是串口类型  
49 -// * @throws NoSuchPort  
50 -// * 没有该端口对应的串口设备  
51 -// * @throws PortInUse  
52 -// * 端口已被占用  
53 - */  
54 - public static SerialPort openPort(String portName, Integer baudrate, Integer dataBits, Integer stopBits,  
55 - Integer parity) throws Exception {  
56 -  
57 - try {  
58 -  
59 - // 通过端口名识别端口  
60 - CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);  
61 - if(portIdentifier.isCurrentlyOwned())  
62 - {  
63 - throw new RuntimeException("串口已被占用");  
64 - }  
65 - // 打开端口,并给端口名字和一个timeout(打开操作的超时时间)  
66 - CommPort commPort = portIdentifier.open(portName, 2000);  
67 -  
68 - // 判断是不是串口  
69 - if (commPort instanceof SerialPort) {  
70 - SerialPort serialPort = (SerialPort) commPort;  
71 - try {  
72 - // 设置一下串口的波特率等参数  
73 - serialPort.setSerialPortParams(baudrate, dataBits, stopBits, parity);  
74 - } catch (UnsupportedCommOperationException e) {  
75 - logger.error("设置串口" + portName + "参数失败:" + e.getMessage());  
76 - throw e;  
77 - }  
78 -  
79 - return serialPort;  
80 -  
81 - } else {  
82 - logger.error("不是串口" + portName);  
83 - // 不是串口  
84 - throw new Exception();  
85 - }  
86 - } catch (NoSuchPortException e1) {  
87 - logger.error("无此串口" + portName);  
88 - throw e1;  
89 - } catch (PortInUseException e2) {  
90 - logger.error("串口使用中" + portName);  
91 - throw e2;  
92 - } catch (Exception e) {  
93 - throw e;  
94 - }  
95 - }  
96 -  
97 - /**  
98 - * 将字节数组转换为16进制字符串,并在每个字符之间用空格分隔  
99 - * @param byteArray  
100 - * @return  
101 - */  
102 - public static String bytesToHexString(byte[] byteArray) {  
103 - StringBuilder sb = new StringBuilder();  
104 - for (byte b : byteArray) {  
105 - // 将每个字节转换为两位的16进制字符串  
106 - String hex = String.format("%02X", b);  
107 - sb.append(hex);  
108 -  
109 - // 在每个字符之间添加空格  
110 - sb.append(" ");  
111 - }  
112 - // 删除最后一个空格  
113 - sb.deleteCharAt(sb.length() - 1);  
114 - return sb.toString();  
115 - }  
116 - public static byte[] HexString2Bytes(String src) {  
117 - if (null == src || 0 == src.length()) {  
118 - return null;  
119 - }  
120 - byte[] ret = new byte[src.length() / 2];  
121 - byte[] tmp = src.getBytes();  
122 - for (int i = 0; i < (tmp.length / 2); i++) {  
123 - ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]);  
124 - }  
125 - return ret;  
126 - }  
127 -  
128 - // byte类型数据,转成十六进制形式;  
129 - public static byte uniteBytes(byte src0, byte src1) {  
130 - byte _b0 = Byte.decode("0x" + new String(new byte[] { src0 })).byteValue();  
131 - _b0 = (byte) (_b0 << 4);  
132 - byte _b1 = Byte.decode("0x" + new String(new byte[] { src1 })).byteValue();  
133 - byte ret = (byte) (_b0 ^ _b1);  
134 - return ret;  
135 - }  
136 -  
137 - /**  
138 - * 关闭串口  
139 - *  
140 - * @throws IOException  
141 - */  
142 - public static synchronized void closePort(SerialPort serialPort) throws IOException {  
143 - if (serialPort != null) {  
144 - serialPort.close();  
145 - logger.info("串口" + serialPort.getName() + "已关闭");  
146 - }  
147 - }  
148 -  
149 - public static OutputStream getSerialPortStream( SerialPort serialPort) throws IOException {  
150 - return serialPort.getOutputStream();  
151 - }  
152 -  
153 - public static void sendToPort(byte[] order, OutputStream out) throws IOException {  
154 - out.write(order);  
155 - out.flush();  
156 - }  
157 -  
158 - /**  
159 - * 往串口发送数据  
160 - *  
161 - * @param order  
162 - * 待发送数据  
163 -// * @throws SendDataToSerialPortFailure  
164 -// * 向串口发送数据失败  
165 -// * @throws SerialPortOutputStreamCloseFailure  
166 -// * 关闭串口对象的输出流出错  
167 - */  
168 - public static void sendToPort(byte[] order, SerialPort serialPort) throws IOException {  
169 -  
170 - OutputStream out = null;  
171 -  
172 - try {  
173 -  
174 - out = serialPort.getOutputStream();  
175 - if(null == out)  
176 - {  
177 - logger.error("窗口未打开" );  
178 - }  
179 - out.write(order);  
180 - out.flush();  
181 - logger.info("发送数据成功" + serialPort.getName());  
182 - } catch (IOException e) {  
183 - logger.error("发送数据失败" + serialPort.getName());  
184 - throw e;  
185 - } finally {  
186 - try {  
187 - if (out != null) {  
188 - out.close();  
189 - }  
190 - } catch (IOException e) {  
191 - logger.error("关闭串口对象的输出流出错");  
192 - throw e;  
193 - }  
194 - }  
195 -  
196 - }  
197 -  
198 - /**  
199 - * 从串口读取数据  
200 - *  
201 - * @param serialPort  
202 - * 当前已建立连接的SerialPort对象  
203 - * @return 读取到的数据  
204 -// * @throws ReadDataFromSerialPortFailure  
205 -// * 从串口读取数据时出错  
206 -// * @throws SerialPortInputStreamCloseFailure  
207 -// * 关闭串口对象输入流出错  
208 - */  
209 - public static byte[] readFromPort(SerialPort serialPort) throws Exception {  
210 -  
211 - InputStream in = null;  
212 - byte[] bytes = null;  
213 -  
214 - try {  
215 - if (serialPort != null) {  
216 - in = serialPort.getInputStream();  
217 - } else {  
218 - return null;  
219 - }  
220 - int bufflenth = in.available(); // 获取buffer里的数据长度  
221 - while (bufflenth != 0) {  
222 - bytes = new byte[bufflenth]; // 初始化byte数组为buffer中数据的长度  
223 - in.read(bytes);  
224 - bufflenth = in.available();  
225 - }  
226 - } catch (Exception e) {  
227 - throw e;  
228 - } finally {  
229 - try {  
230 - if (in != null) {  
231 - in.close();  
232 - in = null;  
233 - }  
234 - } catch (IOException e) {  
235 - throw e;  
236 - }  
237 -  
238 - }  
239 -  
240 - return bytes;  
241 -  
242 - }  
243 -  
244 - /**  
245 - * 添加监听器  
246 - *  
247 -// * @param port  
248 -// * 串口对象  
249 - * @param listener  
250 - * 串口监听器  
251 -// * @throws TooManyListeners  
252 -// * 监听类对象过多  
253 - */  
254 - public static void addListener(SerialPortEventListener listener, SerialPort serialPort) throws TooManyListenersException {  
255 -  
256 - try {  
257 - if(null == serialPort)  
258 - {  
259 - throw new RuntimeException("端口未初始化");  
260 - }  
261 - // 给串口添加监听器  
262 - serialPort.addEventListener(listener);  
263 - // 设置当有数据到达时唤醒监听接收线程  
264 - serialPort.notifyOnDataAvailable(true);  
265 - // 设置当通信中断时唤醒中断线程  
266 - serialPort.notifyOnBreakInterrupt(true);  
267 -  
268 - } catch (TooManyListenersException e) {  
269 - throw e;  
270 - }  
271 - }  
272 -}  
1 -# 开发环境配置 server: # 服务器的HTTP端口,默认为8080 port: 8064 servlet: # 应用的访问路径 context-path: / tomcat: # tomcat的URI编码 uri-encoding: UTF-8 # 连接数满后的排队数,默认为100 accept-count: 1000 threads: # tomcat最大线程数,默认为200 max: 800 # Tomcat启动初始化的线程数,默认值10 min-spare: 100 # 日志配置 logging: level: com.ruoyi: debug org.springframework: warn # Swagger配置 swagger: # 是否开启swagger enabled: true # 请求前缀 pathMapping: /dev-api # 防止XSS攻击 xss: # 过滤开关 enabled: true # 排除链接(多个用逗号分隔) excludes: /system/notice # 匹配链接 urlPatterns: /system/*,/monitor/*,/tool/* sys: staticPath: "file:/opt/lh-smart-feeder/lh-smart-feeder/html/" cacheFilePath: "E:/opt/lh-smart-feeder/lh-smart-feeder/cache/" # MyBatis配置 mybatis: # 搜索指定包别名 typeAliasesPackage: com.ruoyi.**.domain,com.zhonglai.**.domain # 配置mapper的扫描,找到所有的mapper.xml映射文件 mapperLocations: classpath*:mapper/**/*Mapper.xml # 加载全局的配置文件 configLocation: classpath:mybatis/mybatis-config.xml # 数据源配置 spring: # autoconfigure: # exclude: org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration datasource: type: com.alibaba.druid.pool.DruidDataSource driverClassName: org.sqlite.JDBC druid: # 主库数据源 master: url: jdbc:sqlite:db/my.db username: password: # 从库数据源 slave: # 从数据源开关/默认关闭 enabled: false url: username: password: # 初始连接数 initialSize: 5 # 最小连接池数量 minIdle: 10 # 最大连接池数量 maxActive: 20 # 配置获取连接等待超时的时间 maxWait: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 timeBetweenEvictionRunsMillis: 60000 # 配置一个连接在池中最小生存的时间,单位是毫秒 minEvictableIdleTimeMillis: 300000 # 配置一个连接在池中最大生存的时间,单位是毫秒 maxEvictableIdleTimeMillis: 900000 # 配置检测连接是否有效 validationQuery: SELECT 1 testWhileIdle: true testOnBorrow: false testOnReturn: false webStatFilter: enabled: true statViewServlet: enabled: true # 设置白名单,不填则允许所有访问 allow: url-pattern: /druid/* # 控制台管理用户名和密码 login-username: ruoyi login-password: 123456 filter: stat: enabled: true # 慢SQL记录 log-slow-sql: true slow-sql-millis: 1000 merge-sql: true wall: config: multi-statement-allow: true ## 数据源配置 #spring: # datasource: # type: com.alibaba.druid.pool.DruidDataSource # driverClassName: com.mysql.cj.jdbc.Driver # druid: # # 主库数据源 # master: # url: jdbc:mysql://rm-wz9740un21f09iokuao.mysql.rds.aliyuncs.com:3306/mqtt_broker?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 # username: luhui # password: Luhui586 # # 从库数据源 # slave: # # 从数据源开关/默认关闭 # enabled: true # url: jdbc:mysql://119.23.218.181:3306/lh-server-ops?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 # username: luhui # password: Luhui586 # # 初始连接数 # initialSize: 5 # # 最小连接池数量 # minIdle: 10 # # 最大连接池数量 # maxActive: 20 # # 配置获取连接等待超时的时间 # maxWait: 60000 # # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 # timeBetweenEvictionRunsMillis: 60000 # # 配置一个连接在池中最小生存的时间,单位是毫秒 # minEvictableIdleTimeMillis: 300000 # # 配置一个连接在池中最大生存的时间,单位是毫秒 # maxEvictableIdleTimeMillis: 900000 # # 配置检测连接是否有效 # validationQuery: SELECT 1 FROM DUAL # testWhileIdle: true # testOnBorrow: false # testOnReturn: false # webStatFilter: # enabled: true # statViewServlet: # enabled: true # # 设置白名单,不填则允许所有访问 # allow: # url-pattern: /druid/* # # 控制台管理用户名和密码 # login-username: ruoyi # login-password: 123456 # filter: # stat: # enabled: true # # 慢SQL记录 # log-slow-sql: true # slow-sql-millis: 1000 # merge-sql: true # wall: # config: # multi-statement-allow: true mqtt: #链接地址 broker: tcp://175.24.61.68:1883 #唯一标识 clientId: 70094a59d1d991d #公司id roleid: 2 mqtt_usernames: 12_ZNZY #订阅的topic topics: PUT/+,GET_REQ/+, READ/+,POST_REQ/+ sub_clientid: '70094a59d1d991d' username: 12_ZNZY password: Luhui586 client: #客户端操作时间 operationTime: 10  
  1 +# 开发环境配置 server: # 服务器的HTTP端口,默认为8080 port: 8064 servlet: # 应用的访问路径 context-path: / tomcat: # tomcat的URI编码 uri-encoding: UTF-8 # 连接数满后的排队数,默认为100 accept-count: 1000 threads: # tomcat最大线程数,默认为200 max: 800 # Tomcat启动初始化的线程数,默认值10 min-spare: 100 # 日志配置 logging: level: com.ruoyi: debug org.springframework: warn # Swagger配置 swagger: # 是否开启swagger enabled: true # 请求前缀 pathMapping: /dev-api # 防止XSS攻击 xss: # 过滤开关 enabled: true # 排除链接(多个用逗号分隔) excludes: /system/notice # 匹配链接 urlPatterns: /system/*,/monitor/*,/tool/* sys: staticPath: "file:/opt/lh-smart-feeder/lh-smart-feeder/html/" cacheFilePath: "E:/opt/lh-smart-feeder/lh-smart-feeder/cache/" # MyBatis配置 mybatis: # 搜索指定包别名 typeAliasesPackage: com.ruoyi.**.domain,com.zhonglai.**.domain # 配置mapper的扫描,找到所有的mapper.xml映射文件 mapperLocations: classpath*:mapper/**/*Mapper.xml # 加载全局的配置文件 configLocation: classpath:mybatis/mybatis-config.xml # 数据源配置 spring: # autoconfigure: # exclude: org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration datasource: type: com.alibaba.druid.pool.DruidDataSource driverClassName: org.sqlite.JDBC druid: # 主库数据源 master: url: jdbc:sqlite:db/my.db username: password: # 从库数据源 slave: # 从数据源开关/默认关闭 enabled: false url: username: password: # 初始连接数 initialSize: 5 # 最小连接池数量 minIdle: 10 # 最大连接池数量 maxActive: 20 # 配置获取连接等待超时的时间 maxWait: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 timeBetweenEvictionRunsMillis: 60000 # 配置一个连接在池中最小生存的时间,单位是毫秒 minEvictableIdleTimeMillis: 300000 # 配置一个连接在池中最大生存的时间,单位是毫秒 maxEvictableIdleTimeMillis: 900000 # 配置检测连接是否有效 validationQuery: SELECT 1 testWhileIdle: true testOnBorrow: false testOnReturn: false webStatFilter: enabled: true statViewServlet: enabled: true # 设置白名单,不填则允许所有访问 allow: url-pattern: /druid/* # 控制台管理用户名和密码 login-username: ruoyi login-password: 123456 filter: stat: enabled: true # 慢SQL记录 log-slow-sql: true slow-sql-millis: 1000 merge-sql: true wall: config: multi-statement-allow: true ## 数据源配置 #spring: # datasource: # type: com.alibaba.druid.pool.DruidDataSource # driverClassName: com.mysql.cj.jdbc.Driver # druid: # # 主库数据源 # master: # url: jdbc:mysql://rm-wz9740un21f09iokuao.mysql.rds.aliyuncs.com:3306/mqtt_broker?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 # username: luhui # password: Luhui586 # # 从库数据源 # slave: # # 从数据源开关/默认关闭 # enabled: true # url: jdbc:mysql://119.23.218.181:3306/lh-server-ops?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 # username: luhui # password: Luhui586 # # 初始连接数 # initialSize: 5 # # 最小连接池数量 # minIdle: 10 # # 最大连接池数量 # maxActive: 20 # # 配置获取连接等待超时的时间 # maxWait: 60000 # # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 # timeBetweenEvictionRunsMillis: 60000 # # 配置一个连接在池中最小生存的时间,单位是毫秒 # minEvictableIdleTimeMillis: 300000 # # 配置一个连接在池中最大生存的时间,单位是毫秒 # maxEvictableIdleTimeMillis: 900000 # # 配置检测连接是否有效 # validationQuery: SELECT 1 FROM DUAL # testWhileIdle: true # testOnBorrow: false # testOnReturn: false # webStatFilter: # enabled: true # statViewServlet: # enabled: true # # 设置白名单,不填则允许所有访问 # allow: # url-pattern: /druid/* # # 控制台管理用户名和密码 # login-username: ruoyi # login-password: 123456 # filter: # stat: # enabled: true # # 慢SQL记录 # log-slow-sql: true # slow-sql-millis: 1000 # merge-sql: true # wall: # config: # multi-statement-allow: true mqtt: #链接地址 broker: tcp://175.24.61.68:1883 #唯一标识 clientId: 70094a59d1d991d #公司id roleid: 2 mqtt_usernames: 12_ZNZY #订阅的topic topics: PUT/+,GET_REQ/+, READ/+,POST_REQ/+ username: 12_ZNZY password: Luhui586 client: #客户端操作时间 operationTime: 10