作者 钟来

模块整理

正在显示 58 个修改的文件 包含 1683 行增加2623 行删除

要显示太多修改。

为保证性能只显示 58 of 58+ 个文件。

@@ -20,26 +20,7 @@ @@ -20,26 +20,7 @@
20 20
21 <dependency> 21 <dependency>
22 <groupId>com.zhonglai.luhui</groupId> 22 <groupId>com.zhonglai.luhui</groupId>
23 - <artifactId>ruoyi-framework</artifactId>  
24 - <exclusions>  
25 - <exclusion>  
26 - <groupId>org.springframework.boot</groupId>  
27 - <artifactId>spring-boot-devtools</artifactId>  
28 - </exclusion>  
29 - </exclusions>  
30 - </dependency>  
31 - <dependency>  
32 - <groupId>org.aspectj</groupId>  
33 - <artifactId>aspectjweaver</artifactId>  
34 - </dependency>  
35 - <dependency>  
36 - <groupId>org.aspectj</groupId>  
37 - <artifactId>aspectjrt</artifactId>  
38 - </dependency>  
39 -  
40 - <dependency>  
41 - <groupId>com.zhonglai.luhui</groupId>  
42 - <artifactId>lh-common-swagger</artifactId> 23 + <artifactId>ruoyi-common</artifactId>
43 </dependency> 24 </dependency>
44 25
45 <!-- https://mvnrepository.com/artifact/org.bytedeco/opencv --> 26 <!-- https://mvnrepository.com/artifact/org.bytedeco/opencv -->
@@ -63,29 +44,10 @@ @@ -63,29 +44,10 @@
63 <artifactId>spring-boot-starter-websocket</artifactId> 44 <artifactId>spring-boot-starter-websocket</artifactId>
64 </dependency> 45 </dependency>
65 46
66 - <!-- sqlite -->  
67 - <dependency>  
68 - <groupId>com.zhonglai.luhui</groupId>  
69 - <artifactId>ruoyi-framework</artifactId>  
70 - </dependency>  
71 - <dependency>  
72 - <groupId>com.zhonglai.luhui</groupId>  
73 - <artifactId>lh-common-datasource</artifactId>  
74 - </dependency>  
75 - <dependency>  
76 - <groupId>com.zhonglai.luhui</groupId>  
77 - <artifactId>lh-public-dao</artifactId>  
78 - </dependency>  
79 - <dependency>  
80 - <groupId>org.xerial</groupId>  
81 - <artifactId>sqlite-jdbc</artifactId>  
82 - <version>3.21.0.1</version>  
83 - </dependency>  
84 -  
85 - <!-- mqtt --> 47 + <!-- nio -->
86 <dependency> 48 <dependency>
87 - <groupId>org.eclipse.paho</groupId>  
88 - <artifactId>org.eclipse.paho.client.mqttv3</artifactId> 49 + <groupId>io.netty</groupId>
  50 + <artifactId>netty-all</artifactId>
89 </dependency> 51 </dependency>
90 <dependency> 52 <dependency>
91 <groupId>cn.hutool</groupId> 53 <groupId>cn.hutool</groupId>
@@ -99,6 +61,10 @@ @@ -99,6 +61,10 @@
99 <artifactId>jSerialComm</artifactId> 61 <artifactId>jSerialComm</artifactId>
100 <version>2.10.3</version> 62 <version>2.10.3</version>
101 </dependency> 63 </dependency>
  64 + <dependency>
  65 + <groupId>jakarta.xml.bind</groupId>
  66 + <artifactId>jakarta.xml.bind-api</artifactId>
  67 + </dependency>
102 </dependencies> 68 </dependencies>
103 69
104 <build> 70 <build>
1 package com.zhonglai.luhui.smart.feeder; 1 package com.zhonglai.luhui.smart.feeder;
2 2
3 -import com.ruoyi.framework.config.ResourcesConfig;  
4 import com.zhonglai.luhui.smart.feeder.config.OpenCVConfig; 3 import com.zhonglai.luhui.smart.feeder.config.OpenCVConfig;
5 -import org.springframework.boot.SpringApplication;  
6 -import org.springframework.boot.autoconfigure.SpringBootApplication;  
7 4
  5 +import com.zhonglai.luhui.smart.feeder.service.InitService;
8 import org.slf4j.Logger; 6 import org.slf4j.Logger;
9 import org.slf4j.LoggerFactory; 7 import org.slf4j.LoggerFactory;
10 -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;  
11 -import org.springframework.context.annotation.ComponentScan;  
12 -import org.springframework.context.annotation.FilterType;  
13 -import org.springframework.scheduling.annotation.EnableScheduling;  
14 -  
15 -@ComponentScan(basePackages = {  
16 - "com.ruoyi.common",  
17 - "com.ruoyi.framework",  
18 - "com.zhonglai.luhui.datasource",  
19 - "com.zhonglai.luhui.dao",  
20 - "com.zhonglai.luhui.smart.feeder",  
21 -}  
22 - ,excludeFilters = {@ComponentScan.Filter(type= FilterType.ASSIGNABLE_TYPE,classes = {ResourcesConfig.class})}  
23 -)  
24 -@EnableScheduling  
25 -@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class}) 8 +
26 public class Main { 9 public class Main {
27 private static final Logger logger = LoggerFactory.getLogger(Main.class); 10 private static final Logger logger = LoggerFactory.getLogger(Main.class);
28 11
29 public static void main(String[] args) { 12 public static void main(String[] args) {
  13 + logger.info("开始启动服务器");
30 OpenCVConfig.loadOpenCv(args); 14 OpenCVConfig.loadOpenCv(args);
31 - SpringApplication.run(Main.class,args); 15 +
  16 + //配置参数
  17 + logger.info("配置参数");
  18 + InitService.initConfig();
  19 +
  20 + logger.info("启动服务");
  21 + InitService.startService();
  22 +
  23 + logger.info("启动服务器结束");
32 } 24 }
33 25
34 } 26 }
  1 +package com.zhonglai.luhui.smart.feeder.config;
  2 +
  3 +public interface IfOperatingDataValueIsNotNull {
  4 + public void exeValue(String fieldname,Object fieldObject);
  5 +}
1 package com.zhonglai.luhui.smart.feeder.config; 1 package com.zhonglai.luhui.smart.feeder.config;
2 2
  3 +import com.ruoyi.common.utils.GsonConstructor;
3 import com.zhonglai.luhui.smart.feeder.dto.*; 4 import com.zhonglai.luhui.smart.feeder.dto.*;
  5 +import com.zhonglai.luhui.smart.feeder.dto.commd.FeederBackstateTtpe;
  6 +import com.zhonglai.luhui.smart.feeder.dto.mqtt.DevicedatRequest;
  7 +import com.zhonglai.luhui.smart.feeder.service.InitService;
  8 +import com.zhonglai.luhui.smart.feeder.util.FeederCommd06ResponseType;
  9 +import com.zhonglai.luhui.smart.feeder.util.FeederCommdUtil;
  10 +import com.zhonglai.luhui.smart.feeder.util.MessageUtil;
  11 +
  12 +import java.lang.reflect.Field;
4 13
5 /** 14 /**
6 * 运行数据 15 * 运行数据
@@ -9,6 +18,48 @@ public class OperatingData { @@ -9,6 +18,48 @@ public class OperatingData {
9 public static SysConfig sysConfig = new SysConfig(); //系统配置 18 public static SysConfig sysConfig = new SysConfig(); //系统配置
10 public static CameraData cameraData = new CameraData(); //摄像头数据 19 public static CameraData cameraData = new CameraData(); //摄像头数据
11 public static CameraConfig cameraConfig = new CameraConfig() ; //摄像头配置 20 public static CameraConfig cameraConfig = new CameraConfig() ; //摄像头配置
12 - public static FeederData feederData = new FeederData() ; //投料机数据 21 + public static DevicedatRequest devicedat = new DevicedatRequest() ; //投料机数据
13 public static FeederConfig feederConfig = new FeederConfig() ; //投料机配置 22 public static FeederConfig feederConfig = new FeederConfig() ; //投料机配置
  23 + public static RegisterConfig registerConfig = new RegisterConfig(); //数据解析字典
  24 +
  25 + public static void setClassObjecValue(Object value,IfOperatingDataValueIsNotNull ifOperatingDataValueIsNotNull) throws IllegalAccessException {
  26 + if(null != value)
  27 + {
  28 + OperatingDataType operatingDataType = getOperatingDataType(value);
  29 +
  30 + Class cls = value.getClass();
  31 + Field[] fields = cls.getDeclaredFields();
  32 + for(Field field:fields)
  33 + {
  34 + field.setAccessible(true);
  35 + Object object = field.get(value);
  36 + if(null != object)
  37 + {
  38 + operatingDataType.setValue(field,object);
  39 + ifOperatingDataValueIsNotNull.exeValue(field.getName(),object);
  40 + }
  41 + }
  42 + }
  43 + }
  44 +
  45 + public static OperatingDataType getOperatingDataType(Object value)
  46 + {
  47 + if(value instanceof SysConfig)
  48 + {
  49 + return sysConfig;
  50 + }else
  51 + if(value instanceof CameraConfig)
  52 + {
  53 + return cameraConfig;
  54 + }else
  55 + if(value instanceof FeederConfig)
  56 + {
  57 + return feederConfig;
  58 + }else
  59 + if(value instanceof RegisterConfig)
  60 + {
  61 + return registerConfig;
  62 + }
  63 + return null;
  64 + }
14 } 65 }
1 -package com.zhonglai.luhui.smart.feeder.config;  
2 -  
3 -import com.ruoyi.common.config.RuoYiConfig;  
4 -import com.ruoyi.common.constant.Constants;  
5 -import org.springframework.beans.factory.annotation.Value;  
6 -import org.springframework.context.annotation.Bean;  
7 -import org.springframework.context.annotation.Configuration;  
8 -import org.springframework.web.cors.CorsConfiguration;  
9 -import org.springframework.web.cors.UrlBasedCorsConfigurationSource;  
10 -import org.springframework.web.filter.CorsFilter;  
11 -import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;  
12 -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;  
13 -  
14 -/**  
15 - * 通用配置  
16 - *  
17 - * @author ruoyi  
18 - */  
19 -@Configuration  
20 -public class ResourcesConfig implements WebMvcConfigurer  
21 -{  
22 - @Value("${sys.staticPath}")  
23 - private String staticPath;  
24 - @Override  
25 - public void addResourceHandlers(ResourceHandlerRegistry registry)  
26 - {  
27 - /** 本地文件上传路径 */  
28 - registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**")  
29 - .addResourceLocations("file:" + RuoYiConfig.getProfile() + "/");  
30 -  
31 - registry.addResourceHandler( "/camera/**")  
32 - .addResourceLocations(staticPath);  
33 -  
34 - /** swagger配置 */  
35 - registry.addResourceHandler("/swagger-ui/**")  
36 - .addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/");  
37 - }  
38 -  
39 -  
40 -  
41 - /**  
42 - * 跨域配置  
43 - */  
44 - @Bean  
45 - public CorsFilter corsFilter()  
46 - {  
47 - CorsConfiguration config = new CorsConfiguration();  
48 - config.setAllowCredentials(true);  
49 - // 设置访问源地址  
50 - config.addAllowedOriginPattern("*");  
51 - // 设置访问源请求头  
52 - config.addAllowedHeader("*");  
53 - // 设置访问源请求方法  
54 - config.addAllowedMethod("*");  
55 - // 有效期 1800秒  
56 - config.setMaxAge(1800L);  
57 - // 添加映射路径,拦截一切请求  
58 - UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();  
59 - source.registerCorsConfiguration("/**", config);  
60 - // 返回新的CorsFilter  
61 - return new CorsFilter(source);  
62 - }  
63 -}  
  1 +package com.zhonglai.luhui.smart.feeder.config;
  2 +
  3 +import java.util.concurrent.Executors;
  4 +import java.util.concurrent.ScheduledExecutorService;
  5 +
  6 +public class ScheduledConfig {
  7 +
  8 + public final static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(5);
  9 +
  10 +}
1 -package com.zhonglai.luhui.smart.feeder.config;  
2 -  
3 -import com.ruoyi.common.config.RuoYiConfig;  
4 -import com.zhonglai.luhui.smart.feeder.config.v2apibug.ResponseFilter;  
5 -import io.swagger.annotations.ApiOperation;  
6 -import org.springframework.beans.factory.annotation.Autowired;  
7 -import org.springframework.boot.web.servlet.FilterRegistrationBean;  
8 -import org.springframework.context.annotation.Bean;  
9 -import org.springframework.context.annotation.Configuration;  
10 -import springfox.documentation.builders.ApiInfoBuilder;  
11 -import springfox.documentation.builders.PathSelectors;  
12 -import springfox.documentation.builders.RequestHandlerSelectors;  
13 -import springfox.documentation.service.ApiInfo;  
14 -import springfox.documentation.service.Contact;  
15 -import springfox.documentation.spi.DocumentationType;  
16 -import springfox.documentation.spring.web.plugins.Docket;  
17 -import springfox.documentation.swagger2.annotations.EnableSwagger2;  
18 -  
19 -  
20 -@Configuration  
21 -@EnableSwagger2  
22 -public class SwaggerConfig {  
23 - /** 系统基础配置 */  
24 - @Autowired  
25 - private RuoYiConfig ruoyiConfig;  
26 - @Bean  
27 - public Docket createRestApi() {  
28 - return new Docket(DocumentationType.SWAGGER_2)  
29 - .apiInfo(apiInfo())  
30 - .select()  
31 - .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))  
32 - .paths(PathSelectors.any())  
33 - .build();  
34 - }  
35 -  
36 - /**  
37 - * 添加摘要信息  
38 - */  
39 - private ApiInfo apiInfo()  
40 - {  
41 - // 用ApiInfoBuilder进行定制  
42 - return new ApiInfoBuilder()  
43 - // 设置标题  
44 - .title("标题:智能投料机")  
45 - // 描述  
46 - .description("描述:智能投料机")  
47 - // 作者信息  
48 - .contact(new Contact(ruoyiConfig.getName(), null, null))  
49 - // 版本  
50 - .version("版本号:" + ruoyiConfig.getVersion())  
51 - .build();  
52 - }  
53 -  
54 - /**  
55 -// * 解决/v2/api-docs返回多了一层value的问题  
56 -// * @return  
57 -// */  
58 -// @Bean  
59 -// public FilterRegistrationBean someFilterRegistration() {  
60 -// FilterRegistrationBean registration = new FilterRegistrationBean();  
61 -// registration.setFilter(new ResponseFilter());  
62 -// // 过滤的地址  
63 -// registration.addUrlPatterns("/v2/api-docs");  
64 -// return registration;  
65 -// }  
66 -}  
1 -package com.zhonglai.luhui.smart.feeder.config;  
2 -  
3 -import com.zhonglai.luhui.smart.feeder.service.WebSocketSever;  
4 -import org.slf4j.Logger;  
5 -import org.slf4j.LoggerFactory;  
6 -  
7 -import javax.websocket.Session;  
8 -import java.io.IOException;  
9 -import java.util.concurrent.ConcurrentHashMap;  
10 -import java.util.concurrent.CopyOnWriteArraySet;  
11 -  
12 -public class WebSocketClien {  
13 - private static final Logger log = LoggerFactory.getLogger(WebSocketSever.class);  
14 - // session集合,存放对应的session  
15 - public static ConcurrentHashMap<Integer, Session> sessionPool = new ConcurrentHashMap<>();  
16 -  
17 - // concurrent包的线程安全Set,用来存放每个客户端对应的WebSocket对象。  
18 - public static CopyOnWriteArraySet<WebSocketSever> webSocketSet = new CopyOnWriteArraySet<>();  
19 -  
20 - public static boolean login(Integer userId)  
21 - {  
22 - try {  
23 - Session historySession = sessionPool.get(userId);  
24 - // historySession不为空,说明已经有人登陆账号,应该删除登陆的WebSocket对象  
25 - if (historySession != null) {  
26 - webSocketSet.remove(historySession);  
27 - historySession.close();  
28 - }  
29 - return true;  
30 - } catch (IOException e) {  
31 - log.error("重复登录异常,错误信息:" + e.getMessage(), e);  
32 - return false;  
33 - }  
34 - }  
35 -  
36 - public static void close(Integer userId)  
37 - {  
38 - try {  
39 - Session historySession = sessionPool.get(userId);  
40 - // historySession不为空,说明已经有人登陆账号,应该删除登陆的WebSocket对象  
41 - if (historySession != null) {  
42 - webSocketSet.remove(historySession);  
43 - historySession.close();  
44 - }  
45 - } catch (IOException e) {  
46 - log.error("关闭连接,错误信息:" + e.getMessage(), e);  
47 - }  
48 - }  
49 -}  
1 -package com.zhonglai.luhui.smart.feeder.config;  
2 -  
3 -import org.springframework.boot.web.servlet.ServletContextInitializer;  
4 -import org.springframework.context.annotation.Bean;  
5 -import org.springframework.context.annotation.Configuration;  
6 -import org.springframework.web.socket.server.standard.ServerEndpointExporter;  
7 -  
8 -import javax.servlet.ServletContext;  
9 -import javax.servlet.ServletException;  
10 -  
11 -@Configuration  
12 -public class WebSocketConfig implements ServletContextInitializer {  
13 - /**  
14 - * 这个bean的注册,用于扫描带有@ServerEndpoint的注解成为websocket,如果你使用外置的tomcat就不需要该配置文件  
15 - */  
16 - @Bean  
17 - public ServerEndpointExporter serverEndpointExporter() {  
18 - return new ServerEndpointExporter();  
19 - }  
20 -  
21 - @Override  
22 - public void onStartup(ServletContext servletContext) throws ServletException {  
23 -  
24 - }  
25 -}  
1 -package com.zhonglai.luhui.smart.feeder.config.manager;  
2 -  
3 -import com.ruoyi.common.utils.Threads;  
4 -import com.ruoyi.common.utils.spring.SpringUtils;  
5 -  
6 -import java.util.TimerTask;  
7 -import java.util.concurrent.ScheduledExecutorService;  
8 -import java.util.concurrent.TimeUnit;  
9 -  
10 -/**  
11 - * 异步任务管理器  
12 - *  
13 - * @author ruoyi  
14 - */  
15 -public class AsyncManager  
16 -{  
17 -  
18 - /**  
19 - * 异步操作任务调度线程池  
20 - */  
21 - private ScheduledExecutorService executor = SpringUtils.getBean("scheduledExecutorService");  
22 -  
23 - /**  
24 - * 单例模式  
25 - */  
26 - private AsyncManager(){}  
27 -  
28 - private static AsyncManager me = new AsyncManager();  
29 -  
30 - public static AsyncManager me()  
31 - {  
32 - return me;  
33 - }  
34 -  
35 - /**  
36 - * 停止任务线程池  
37 - */  
38 - public void shutdown()  
39 - {  
40 - Threads.shutdownAndAwaitTermination(executor);  
41 - }  
42 -}  
1 -package com.zhonglai.luhui.smart.feeder.config.manager;  
2 -  
3 -import com.zhonglai.luhui.smart.feeder.service.SrsService;  
4 -import com.zhonglai.luhui.smart.feeder.service.EhCacheService;  
5 -import com.zhonglai.luhui.smart.feeder.service.device.SerialPortService;  
6 -import com.zhonglai.luhui.smart.feeder.service.TerminalService;  
7 -import org.slf4j.Logger;  
8 -import org.slf4j.LoggerFactory;  
9 -import org.springframework.beans.factory.annotation.Autowired;  
10 -import org.springframework.stereotype.Component;  
11 -  
12 -import javax.annotation.PreDestroy;  
13 -  
14 -/**  
15 - * 确保应用退出时能关闭后台线程  
16 - *  
17 - * @author ruoyi  
18 - */  
19 -@Component  
20 -public class ShutdownManager  
21 -{  
22 - private static final Logger logger = LoggerFactory.getLogger(ShutdownManager.class);  
23 -  
24 - @Autowired  
25 - private EhCacheService ehCacheService;  
26 -  
27 - @Autowired  
28 - private SerialPortService serialPortService;  
29 -  
30 - @Autowired  
31 - private TerminalService terminalService;  
32 - @Autowired  
33 - private SrsService srsService;  
34 -  
35 -  
36 - @PreDestroy  
37 - public void destroy()  
38 - {  
39 - terminalService.close();  
40 - serialPortService.close();  
41 - ehCacheService.shutdown();  
42 - srsService.stop();  
43 - shutdownAsyncManager();  
44 - }  
45 -  
46 - /**  
47 - * 停止异步执行任务  
48 - */  
49 - private void shutdownAsyncManager()  
50 - {  
51 - try  
52 - {  
53 - logger.info("====关闭后台任务任务线程池111====");  
54 - AsyncManager.me().shutdown();  
55 - }  
56 - catch (Exception e)  
57 - {  
58 - logger.error(e.getMessage(), e);  
59 - }  
60 - }  
61 -}  
1 -package com.zhonglai.luhui.smart.feeder.config.v2apibug;  
2 -  
3 -import com.google.gson.Gson;  
4 -  
5 -import javax.servlet.*;  
6 -import javax.servlet.http.HttpServletResponse;  
7 -import java.io.IOException;  
8 -import java.util.HashMap;  
9 -import java.util.Map;  
10 -  
11 -public class ResponseFilter implements Filter {  
12 -  
13 - @Override  
14 - public void init(FilterConfig filterConfig) throws ServletException {  
15 - Filter.super.init(filterConfig);  
16 - }  
17 -  
18 - @Override  
19 - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {  
20 - // 这里需要重写ResponseWrapper,因为原方法是没有获取返回值的功能  
21 - ResponseWrapper wrapperResponse = new ResponseWrapper((HttpServletResponse) response);  
22 - // 这里只拦截返回,直接让请求过去,如果在请求前有处理,可以在这里处理  
23 - chain.doFilter(request, wrapperResponse);  
24 - byte[] content = wrapperResponse.getContent();//获取返回值  
25 - // 判断是否有值  
26 - if (content.length > 0) {  
27 - // 这里是返回的内容  
28 - String str = new String(content, "UTF-8");  
29 - System.out.println("拦截的返回值:" + str);  
30 - try {  
31 - if(str.startsWith("{\"value\""))  
32 - {  
33 - Gson gson = new Gson();  
34 - Map<String,Object> map = gson.fromJson(str, HashMap.class);  
35 - response.getWriter().println(map.get("value"));  
36 - }else{  
37 - response.getWriter().write(str);  
38 - }  
39 - } catch (Exception e) {  
40 - e.printStackTrace();  
41 - }finally {  
42 - response.getWriter().flush();  
43 - }  
44 -  
45 - }  
46 - }  
47 -  
48 - @Override  
49 - public void destroy() {  
50 - Filter.super.destroy();  
51 - }  
52 -}  
1 -package com.zhonglai.luhui.smart.feeder.config.v2apibug;  
2 -  
3 -import javax.servlet.ServletOutputStream;  
4 -import javax.servlet.WriteListener;  
5 -import javax.servlet.http.HttpServletResponse;  
6 -import javax.servlet.http.HttpServletResponseWrapper;  
7 -import java.io.ByteArrayOutputStream;  
8 -import java.io.IOException;  
9 -  
10 -public class ResponseWrapper extends HttpServletResponseWrapper {  
11 -  
12 - private ByteArrayOutputStream buffer;  
13 -  
14 - private ServletOutputStream out;  
15 -  
16 - public ResponseWrapper(HttpServletResponse httpServletResponse) {  
17 - super(httpServletResponse);  
18 - buffer = new ByteArrayOutputStream();  
19 - out = new WrapperOutputStream(buffer);  
20 - }  
21 -  
22 - @Override  
23 - public ServletOutputStream getOutputStream()  
24 - throws IOException {  
25 - return out;  
26 - }  
27 -  
28 - @Override  
29 - public void flushBuffer()  
30 - throws IOException {  
31 - if (out != null) {  
32 - out.flush();  
33 - }  
34 - }  
35 -  
36 - public byte[] getContent()  
37 - throws IOException {  
38 - flushBuffer();  
39 - return buffer.toByteArray();  
40 - }  
41 -  
42 - class WrapperOutputStream extends ServletOutputStream {  
43 - private ByteArrayOutputStream bos;  
44 -  
45 - public WrapperOutputStream(ByteArrayOutputStream bos) {  
46 - this.bos = bos;  
47 - }  
48 -  
49 - @Override  
50 - public void write(int b)  
51 - throws IOException {  
52 - bos.write(b);  
53 - }  
54 -  
55 - @Override  
56 - public boolean isReady() {  
57 -  
58 - // TODO Auto-generated method stub  
59 - return false;  
60 -  
61 - }  
62 -  
63 - @Override  
64 - public void setWriteListener(WriteListener arg0) {  
65 -  
66 - // TODO Auto-generated method stub  
67 -  
68 - }  
69 - }  
70 -}  
1 -package com.zhonglai.luhui.smart.feeder.controller;  
2 -  
3 -import com.ruoyi.common.core.domain.AjaxResult;  
4 -import com.zhonglai.luhui.smart.feeder.config.WebSocketClien;  
5 -import com.zhonglai.luhui.smart.feeder.dto.ModbusDto;  
6 -import com.zhonglai.luhui.smart.feeder.service.DeviceService;  
7 -import com.zhonglai.luhui.smart.feeder.util.FeederCommd06ResponseType;  
8 -import com.zhonglai.luhui.smart.feeder.util.FeederCommdUtil;  
9 -import io.swagger.annotations.Api;  
10 -import io.swagger.annotations.ApiImplicitParam;  
11 -import io.swagger.annotations.ApiImplicitParams;  
12 -import io.swagger.annotations.ApiOperation;  
13 -import org.springframework.beans.factory.annotation.Autowired;  
14 -import org.springframework.web.bind.annotation.GetMapping;  
15 -import org.springframework.web.bind.annotation.PathVariable;  
16 -import org.springframework.web.bind.annotation.RequestMapping;  
17 -import org.springframework.web.bind.annotation.RestController;  
18 -  
19 -import java.io.IOException;  
20 -  
21 -@Api(tags = "摄像头功能")  
22 -@RestController  
23 -@RequestMapping("/camera")  
24 -public class CameraController {  
25 -  
26 - @Autowired  
27 - private DeviceService deviceService;  
28 -  
29 - @ApiOperation("关闭连接")  
30 - @GetMapping("/discon/{userId}")  
31 - public AjaxResult discon( @PathVariable(value = "userId") Integer userId)  
32 - {  
33 - WebSocketClien.close(userId);  
34 - return AjaxResult.success();  
35 - }  
36 -  
37 -}  
1 -package com.zhonglai.luhui.smart.feeder.controller;  
2 -  
3 -import com.ruoyi.common.core.domain.AjaxResult;  
4 -import com.zhonglai.luhui.dao.service.PublicService;  
5 -import com.zhonglai.luhui.smart.feeder.dto.ConfigDto;  
6 -import com.zhonglai.luhui.smart.feeder.service.ConfigurationParameterService;  
7 -import io.swagger.annotations.Api;  
8 -import io.swagger.annotations.ApiOperation;  
9 -import org.springframework.beans.factory.annotation.Autowired;  
10 -import org.springframework.web.bind.annotation.*;  
11 -  
12 -import java.util.List;  
13 -import java.util.Map;  
14 -  
15 -@Api(tags = "配置")  
16 -@RestController  
17 -@RequestMapping("/config")  
18 -public class ConfigController {  
19 - @Autowired  
20 - private PublicService publicService;  
21 - @Autowired  
22 - private ConfigurationParameterService configurationParameterService;  
23 - @ApiOperation("获取配置所有参数")  
24 - @GetMapping("/all")  
25 - public AjaxResult all()  
26 - {  
27 - AjaxResult ajaxResult = AjaxResult.success();  
28 - Map<String, Object> cache = configurationParameterService.getAll();  
29 - for (String key:cache.keySet()) {  
30 - // Process the key and value as needed.  
31 - ajaxResult.put(key,cache.get(key));  
32 - }  
33 - return ajaxResult;  
34 - }  
35 -  
36 - @ApiOperation("参数配置")  
37 - @PostMapping("/set")  
38 - public AjaxResult set(@RequestBody ConfigDto configDto)  
39 - {  
40 - configurationParameterService.setConfig(configDto.getConfigurationParameter(),configDto.getValue());  
41 - return AjaxResult.success();  
42 - }  
43 -  
44 - @ApiOperation("执行sqlite")  
45 - @PostMapping("/extsql")  
46 - public AjaxResult extsql(String sql)  
47 - {  
48 - List<Map<String,Object>> list = publicService.getObjectListBySQL(sql);  
49 - return AjaxResult.success(list);  
50 - }  
51 -}  
1 -package com.zhonglai.luhui.smart.feeder.controller;  
2 -  
3 -import com.ruoyi.common.core.domain.AjaxResult;  
4 -import com.zhonglai.luhui.smart.feeder.dto.commd.*;  
5 -import com.zhonglai.luhui.smart.feeder.service.device.SerialPortService;  
6 -import io.swagger.annotations.Api;  
7 -import io.swagger.annotations.ApiOperation;  
8 -import org.springframework.beans.factory.annotation.Autowired;  
9 -import org.springframework.web.bind.annotation.*;  
10 -  
11 -@Api(tags = "串口管理")  
12 -@RestController  
13 -@RequestMapping("/serialPort")  
14 -public class SerialPortController {  
15 - @Autowired  
16 - private SerialPortService serialPortService;  
17 - @ApiOperation("打开")  
18 - @PostMapping("/open")  
19 - public AjaxResult open(Integer baudrate)  
20 - {  
21 - return AjaxResult.success(serialPortService.open());  
22 - }  
23 -  
24 - @ApiOperation("发送16进制")  
25 - @GetMapping("/sendHexData")  
26 - public AjaxResult sendHexData(String hexStr)  
27 - {  
28 - return AjaxResult.success(serialPortService.sendHexData(hexStr));  
29 - }  
30 -  
31 - @ApiOperation("发送字符串")  
32 - @GetMapping("/sendStrData")  
33 - public AjaxResult sendStrData(String str)  
34 - {  
35 - return AjaxResult.success(serialPortService.sendStrData(str));  
36 - }  
37 -  
38 - @ApiOperation("读取")  
39 - @GetMapping("/read")  
40 - public AjaxResult read(Integer start_char,Integer char_lenth)  
41 - {  
42 - return AjaxResult.success(serialPortService.sendHexData(new FeederCommdDto(new FeederCommd03Response(start_char,char_lenth)).getHstr()));  
43 - }  
44 -  
45 - @ApiOperation("单独写入")  
46 - @GetMapping("/write")  
47 - public AjaxResult write(Integer register_address,Integer value)  
48 - {  
49 - return AjaxResult.success(serialPortService.sendHexData(new FeederCommdDto(new FeederCommd06Response(register_address,value)).getHstr()));  
50 - }  
51 -  
52 -}  
@@ -13,4 +13,18 @@ public class Register { @@ -13,4 +13,18 @@ public class Register {
13 public Integer char_lenth; 13 public Integer char_lenth;
14 public String field_name; 14 public String field_name;
15 public String clas; 15 public String clas;
  16 +
  17 + public Register()
  18 + {
  19 +
  20 + }
  21 +
  22 + public Register(Integer address, String name, Integer start_char, Integer char_lenth, String field_name, String clas) {
  23 + this.address = address;
  24 + this.name = name;
  25 + this.start_char = start_char;
  26 + this.char_lenth = char_lenth;
  27 + this.field_name = field_name;
  28 + this.clas = clas;
  29 + }
16 } 30 }
@@ -3,15 +3,12 @@ package com.zhonglai.luhui.smart.feeder.dto; @@ -3,15 +3,12 @@ package com.zhonglai.luhui.smart.feeder.dto;
3 import lombok.Data; 3 import lombok.Data;
4 import lombok.experimental.Accessors; 4 import lombok.experimental.Accessors;
5 5
  6 +import java.lang.reflect.Field;
6 import java.util.ArrayList; 7 import java.util.ArrayList;
7 8
8 @Data 9 @Data
9 @Accessors(chain = true) //链式写法 10 @Accessors(chain = true) //链式写法
10 -public class CameraConfig {  
11 - /**  
12 - * 摄像头编号  
13 - */  
14 - private Integer captureNumber; 11 +public class CameraConfig implements OperatingDataType{
15 12
16 /** 13 /**
17 * 摄像头接口类型 14 * 摄像头接口类型
@@ -21,25 +18,77 @@ public class CameraConfig { @@ -21,25 +18,77 @@ public class CameraConfig {
21 private String cameraInterfaceType; 18 private String cameraInterfaceType;
22 19
23 /** 20 /**
24 - * 反光阈值 21 + * 动态像素的最小值
  22 + * 阈值,函数根据这个阈值将输入图像的像素分为两类。所有强度大于或等于该阈值的像素都设置为最大值(在本例中为255),所有其他像素都设置为0。
25 */ 23 */
26 - private Integer reflectionThreshold; 24 + private Integer trendsPixelMin;
  25 +
27 /** 26 /**
28 - * 去噪调整内核大小,用来消除小的物体或噪声 27 + * 动态像素的最大值
  28 + * 用于阈值化的最大值。当阈值类型为THRESH_BINARY或THRESH_BINARY_INV时,这个值对应于超过阈值的强度。
29 */ 29 */
30 - private Integer kernelSize; 30 + private Integer trendsPixelMax;
  31 +
  32 + /**
  33 + * 标注框的最小宽度
  34 + */
  35 + private Integer calloutBoxWidthMin;
  36 +
  37 + /**
  38 + * 过滤反光的最小值
  39 + */
  40 + private Integer reflectionMin;
  41 +
  42 + /**
  43 + * 过滤反光的最大值
  44 + */
  45 + private Integer reflectionMax;
  46 +
  47 + /**
  48 + * 过滤亮度的最小值
  49 + */
  50 + private Integer brightnessMin;
  51 +
  52 + /**
  53 + * 过滤亮度的最大值
  54 + */
  55 + private Integer brightnessMax;
  56 +
31 /** 57 /**
32 - * 最大反光阈 58 + * 过滤透明度的最小
33 */ 59 */
34 - private Integer maxValue; 60 + private Integer transparencyMeasureMin;
  61 +
  62 + /**
  63 + * 过滤透明度的最大值
  64 + */
  65 + private Integer transparencyMeasureMax;
  66 +
  67 + /**
  68 + * 过滤面积的最小值
  69 + */
  70 + private Integer areaMin;
  71 +
  72 + /**
  73 + * 过滤面积的最大值
  74 + */
  75 + private Integer areaMax;
  76 +
  77 + /**
  78 + * 去噪调整内核大小,用来消除小的物体或噪声
  79 + */
  80 + private Integer kernelSize;
  81 +
35 /** 82 /**
36 * 斜率范围对应的档位 83 * 斜率范围对应的档位
37 */ 84 */
38 private ArrayList<FishCurveControlCondition> absValue_command; 85 private ArrayList<FishCurveControlCondition> absValue_command;
  86 +
39 /** 87 /**
40 * 是否显示原图 88 * 是否显示原图
41 */ 89 */
42 private Boolean veiwDto_isFrame; 90 private Boolean veiwDto_isFrame;
  91 +
43 /** 92 /**
44 * 是否显示临时图 93 * 是否显示临时图
45 */ 94 */
@@ -67,4 +116,41 @@ public class CameraConfig { @@ -67,4 +116,41 @@ public class CameraConfig {
67 * 鱼群图像识别投料控制是否开启 116 * 鱼群图像识别投料控制是否开启
68 */ 117 */
69 private Boolean feedingControl; 118 private Boolean feedingControl;
  119 +
  120 +
  121 + public CameraConfig creteDefault()
  122 + {
  123 + this.cameraInterfaceType = "RTSP";
  124 + this.trendsPixelMin = 150;
  125 + this.trendsPixelMax = 200;
  126 + this.calloutBoxWidthMin = 5;
  127 + this.reflectionMin = 150;
  128 + this.reflectionMax = 200;
  129 + this.brightnessMin = 100;
  130 + this.brightnessMax = 150;
  131 + this.transparencyMeasureMin = 100;
  132 + this.transparencyMeasureMax = 150;
  133 + this.areaMin = 25;
  134 + this.areaMax = 100;
  135 + this.kernelSize = 3;
  136 + absValue_command = new ArrayList<>();
  137 + absValue_command.add(new FishCurveControlCondition(8590,1));
  138 + absValue_command.add(new FishCurveControlCondition(9590,2));
  139 + absValue_command.add(new FishCurveControlCondition(10590,3));
  140 + absValue_command.add(new FishCurveControlCondition(11590,4));
  141 + this.veiwDto_isFrame = false;
  142 + this.veiwDto_isBinaryImage = false;
  143 + this.veiwDto_isSize = false;
  144 + this.veiwDto_isAbsValue = false;
  145 + this.identificationFrequency = 1000l;
  146 + this.fishGroupImageRecognition = true;
  147 + this.feedingControl = true;
  148 +
  149 + return this;
  150 + }
  151 +
  152 + @Override
  153 + public void setValue(Field field, Object value) throws IllegalAccessException {
  154 + field.set(this,value);
  155 + }
70 } 156 }
@@ -3,22 +3,75 @@ package com.zhonglai.luhui.smart.feeder.dto; @@ -3,22 +3,75 @@ package com.zhonglai.luhui.smart.feeder.dto;
3 import lombok.Data; 3 import lombok.Data;
4 import lombok.experimental.Accessors; 4 import lombok.experimental.Accessors;
5 5
  6 +/**
  7 + * 摄像头数据
  8 + */
6 @Data 9 @Data
7 @Accessors(chain = true) //链式写法 10 @Accessors(chain = true) //链式写法
8 public class CameraData { 11 public class CameraData {
  12 +
  13 + /**
  14 + * 当前画面的亮度
  15 + */
  16 + private Double brightness;
  17 +
  18 + /**
  19 + * 当前画面的反光
  20 + */
  21 + private Double reflection;
  22 +
  23 + /**
  24 + * 当前画面的透明度
  25 + */
  26 + private Double transparencyMeasure;
  27 +
  28 + /**
  29 + * 当前画面的面积
  30 + */
  31 + private Double area;
  32 +
  33 +
9 /** 34 /**
10 - * 斜率 35 + * 当前的斜率
11 */ 36 */
12 - private Double absValue; 37 + private Double slope;
  38 +
13 39
14 /** 40 /**
15 - * 面积大小 41 + * 当前斜率的差值
16 */ 42 */
17 - private Integer size; 43 + private Double slopeDifference;
  44 +
  45 + /**
  46 + * 斜率差值的绝对值
  47 + */
  48 + private Double absValue;
  49 +
  50 + /**
  51 + * 当前档位
  52 + */
  53 + private Integer nowGear;
18 54
19 /** 55 /**
20 * 视频是否打开 56 * 视频是否打开
21 */ 57 */
22 private boolean videoIsOpen; 58 private boolean videoIsOpen;
23 59
  60 + /**
  61 + * 是否摄像头推流
  62 + */
  63 + private boolean is_push_camera;
  64 +
  65 + /**
  66 + * 是否显示数字
  67 + */
  68 + private Boolean isText;
  69 +
  70 + private Boolean displaySrc;
  71 +
  72 + /**
  73 + * 鱼群图像识别运行状态
  74 + */
  75 + private Boolean fishGroupImageRecognIsRun = false;
  76 +
24 } 77 }
1 -package com.zhonglai.luhui.smart.feeder.dto;  
2 -  
3 -import lombok.Data;  
4 -  
5 -import java.io.Serializable;  
6 -  
7 -@Data  
8 -public class ConfigDto implements Serializable {  
9 - private static final long serialVersionUID = 4437689065039524585L;  
10 - private ConfigurationParameter configurationParameter;  
11 - private Object value;  
12 -}  
1 -package com.zhonglai.luhui.smart.feeder.dto;  
2 -  
3 -  
4 -import com.alibaba.fastjson.JSONObject;  
5 -  
6 -import java.util.ArrayList;  
7 -import java.util.HashMap;  
8 -  
9 -  
10 -public enum ConfigurationParameter {  
11 - ifUpLoadData(false, Boolean.class,"sys_config","是否上报数据",true),//是否上报数据  
12 - ifVeiw(false, Boolean.class,"sys_config","是否显示",true),//是否显示  
13 - captureNumber(0, Integer.class,"sys_config","摄像头编号",true),//摄像头编号  
14 - reflectionThreshold(100, Integer.class,"sys_config","反光阈值",true),//反光阈值  
15 - kernelSize(3, Integer.class,"sys_config","去噪调整内核大小,用来消除小的物体或噪声",true),//去噪调整内核大小,用来消除小的物体或噪声  
16 - maxValue(255, Integer.class,"sys_config","最大反光阈值",true), //最大反光阈值  
17 - absValue_command (new ArrayList<FishCurveControlCondition>(),ArrayList.class,"absValue_command","斜率范围对应的档位",true), //斜率范围对应的档位  
18 - VeiwDto_isFrame(false, Boolean.class,"sys_config","是否显示原图",true), //是否显示原图  
19 - VeiwDto_isBinaryImage(false, Boolean.class,"sys_config","是否显示临时图",true), //是否显示临时图  
20 - VeiwDto_isSize(false, Boolean.class,"sys_config","是否显示面积",true), //是否显示面积  
21 - VeiwDto_isAbsValue(false, Boolean.class,"sys_config","是否显示斜率",true), //是否显示斜率  
22 - absValue(0.0, Double.class,"sys_config","显示斜率",false), //斜率  
23 - IdentificationFrequency(1000l, Long.class,"sys_config","鱼群图像识别的频率(单位秒)",true), //鱼群图像识别的频率  
24 - FishGroupImageRecognition(true, Boolean.class,"sys_config","鱼群图像识别是否开启",true), //鱼群图像识别是否开启  
25 - FeedingControl(true, Boolean.class,"sys_config","鱼群图像识别控制投料控制是否开启",true), //鱼群图像识别投料控制是否开启  
26 - SerialPortConfig(new SerialPortConfig().defaultSerialPortConfig(),com.zhonglai.luhui.smart.feeder.dto.SerialPortConfig.class,"sys_config","串口配置",true),//串口配置  
27 - ;  
28 -  
29 - private Object value; //值  
30 - private Class<?> valuType; //数据类型  
31 - private String tableName; //表名  
32 -  
33 - private String describe; //描述  
34 -  
35 - private Boolean persistence; //是否需要持久化  
36 -  
37 - ConfigurationParameter(Object value,Class valuType,String tableName,String describe,Boolean persistence) {  
38 - this.value = value;  
39 - this.valuType = valuType;  
40 - this.tableName = tableName;  
41 - this.describe = describe;  
42 - this.persistence = persistence;  
43 - }  
44 -  
45 - public Object getValue()  
46 - {  
47 - return value;  
48 - }  
49 -  
50 - public Class<?> getValuType() {  
51 - return valuType;  
52 - }  
53 -  
54 - public String getTableName() {  
55 - return tableName;  
56 - }  
57 -  
58 - public String getDescribe() {  
59 - return describe;  
60 - }  
61 -  
62 - public Boolean getPersistence() {  
63 - return persistence;  
64 - }  
65 -  
66 - public String valueToString(Object o)  
67 - {  
68 - switch (getValuType().getName()) {  
69 - case "java.lang.Boolean":  
70 - return ((Boolean)o).toString();  
71 - case "java.lang.Integer":  
72 - return o+"";  
73 - case "java.lang.Double":  
74 - return o+"";  
75 - case "com.zhonglai.luhui.smart.feeder.dto.SerialPortConfig":  
76 - if(o instanceof String)  
77 - {  
78 - return (String) o;  
79 - }  
80 - return JSONObject.toJSONString(o);  
81 - default:  
82 - throw new RuntimeException("配置参数类型不正确" + name() + o);  
83 - }  
84 - }  
85 -  
86 -}  
@@ -3,8 +3,21 @@ package com.zhonglai.luhui.smart.feeder.dto; @@ -3,8 +3,21 @@ package com.zhonglai.luhui.smart.feeder.dto;
3 import lombok.Data; 3 import lombok.Data;
4 import lombok.experimental.Accessors; 4 import lombok.experimental.Accessors;
5 5
  6 +import java.lang.reflect.Field;
  7 +
6 @Data 8 @Data
7 @Accessors(chain = true) //链式写法 9 @Accessors(chain = true) //链式写法
8 -public class FeederConfig { 10 +public class FeederConfig implements OperatingDataType{
9 private SerialPortConfig serialPortConfig; 11 private SerialPortConfig serialPortConfig;
  12 +
  13 + public FeederConfig creteDefault()
  14 + {
  15 + serialPortConfig = new SerialPortConfig().defaultSerialPortConfig();
  16 + return this;
  17 + }
  18 +
  19 + @Override
  20 + public void setValue(Field field, Object value) throws IllegalAccessException {
  21 + field.set(this,value);
  22 + }
10 } 23 }
@@ -6,4 +6,5 @@ import lombok.experimental.Accessors; @@ -6,4 +6,5 @@ import lombok.experimental.Accessors;
6 @Data 6 @Data
7 @Accessors(chain = true) //链式写法 7 @Accessors(chain = true) //链式写法
8 public class FeederData { 8 public class FeederData {
  9 +
9 } 10 }
@@ -10,6 +10,15 @@ public class FishCurveControlCondition implements Serializable { @@ -10,6 +10,15 @@ public class FishCurveControlCondition implements Serializable {
10 private Integer sartAbsValue; //开始斜率 10 private Integer sartAbsValue; //开始斜率
11 private Integer gear; //档位 11 private Integer gear; //档位
12 12
  13 + public FishCurveControlCondition()
  14 + {
  15 +
  16 + }
  17 + public FishCurveControlCondition(Integer sartAbsValue,Integer gear)
  18 + {
  19 + this.sartAbsValue = sartAbsValue;
  20 + this.gear = gear;
  21 + }
13 public Integer getGear() { 22 public Integer getGear() {
14 return gear; 23 return gear;
15 } 24 }
  1 +package com.zhonglai.luhui.smart.feeder.dto;
  2 +
  3 +import lombok.Data;
  4 +
  5 +import javax.xml.bind.annotation.XmlRootElement;
  6 +
  7 +@XmlRootElement(name="xml")
  8 +@Data
  9 +public class HCCameraRepose {
  10 + private String Uuid;
  11 + private String Types;
  12 + private String DeviceType;
  13 + private String DeviceDescription;
  14 + private String DeviceSN;
  15 + private String CommandPort;
  16 + private String HttpPort;
  17 + private String MAC;
  18 + private String IPv4Address;
  19 + private String IPv4SubnetMask;
  20 + private String IPv4Gateway;
  21 + private String DHCP;
  22 + private String AnalogChannelNum;
  23 + private String DigitalChannelNum;
  24 + private String SoftwareVersion;
  25 + private String DSPVersion;
  26 + private String BootTime;
  27 + private String OEMInfo;
  28 + private String EZVIZCode;
  29 + private String manufacturer;
  30 + private String Activated;
  31 + private String ResetAbility;
  32 + private String PasswordResetAbility;
  33 + private String PasswordResetModeSecond;
  34 +}
  1 +package com.zhonglai.luhui.smart.feeder.dto;
  2 +
  3 +import lombok.Data;
  4 +import lombok.experimental.Accessors;
  5 +
  6 +import java.util.List;
  7 +
  8 +@Data
  9 +@Accessors(chain = true) //链式写法
  10 +public class NettyConfig {
  11 + private String host = "127.0.0.1";
  12 + private Integer port = 4722;
  13 + private String clientId = "202310271543";
  14 +}
  1 +package com.zhonglai.luhui.smart.feeder.dto;
  2 +
  3 +import java.lang.reflect.Field;
  4 +
  5 +public interface OperatingDataType {
  6 + public void setValue(Field field,Object value) throws IllegalAccessException;
  7 +}
1 -package com.zhonglai.luhui.smart.feeder.controller; 1 +package com.zhonglai.luhui.smart.feeder.dto;
2 2
3 -import com.ruoyi.common.core.domain.AjaxResult;  
4 -import com.zhonglai.luhui.dao.service.PublicService;  
5 import com.zhonglai.luhui.smart.feeder.domain.Register; 3 import com.zhonglai.luhui.smart.feeder.domain.Register;
6 -import io.swagger.annotations.Api;  
7 -import io.swagger.annotations.ApiOperation;  
8 -import org.springframework.beans.factory.annotation.Autowired;  
9 -import org.springframework.web.bind.annotation.GetMapping;  
10 -import org.springframework.web.bind.annotation.RequestMapping;  
11 -import org.springframework.web.bind.annotation.RestController; 4 +import lombok.Data;
  5 +import lombok.experimental.Accessors;
12 6
  7 +import java.lang.reflect.Field;
13 import java.util.ArrayList; 8 import java.util.ArrayList;
14 import java.util.List; 9 import java.util.List;
15 10
16 -@Api(tags = "寄存器管理")  
17 -@RestController  
18 -@RequestMapping("/register")  
19 -public class RegisterConreoller {  
20 - @Autowired  
21 - private PublicService publicService; 11 +@Data
  12 +@Accessors(chain = true) //链式写法
  13 +public class RegisterConfig implements OperatingDataType{
  14 + private List<Register> registerList;
22 15
23 - @ApiOperation("初始化定时器解析规则")  
24 - @GetMapping("/iniTimer")  
25 - public AjaxResult iniTimer() 16 + public RegisterConfig creteDefault()
26 { 17 {
27 - List<Register> list = new ArrayList<>(); 18 + registerList = new ArrayList<>();
  19 + registerList.add(new Register(0,"机器状态",0,16,"machstate","java.lang.Integer"));
  20 + registerList.add(new Register(1,"电池电量",0,16,"battlevel","java.lang.Integer"));
  21 + registerList.add(new Register(3,"厂家码",0,2,"mfrs","java.lang.Integer"));
  22 + registerList.add(new Register(3,"设备类型",2,2,"equitype","java.lang.Integer"));
  23 + registerList.add(new Register(3,"设备模式",4,1,"equimode","java.lang.Integer"));
  24 + registerList.add(new Register(4,"故障代码",0,16,"faultcode","java.lang.Integer"));
  25 + registerList.add(new Register(5,"饲料状态",0,16,"fodderstate","java.lang.Boolean"));
  26 + registerList.add(new Register(6,"饲料重量",0,16,"fodderweight","java.lang.Float"));
  27 + registerList.add(new Register(7,"投料次数",0,16,"feednum","java.lang.Integer"));
  28 + registerList.add(new Register(8,"本次投料量",0,16,"feedweight","java.lang.Float"));
  29 + registerList.add(new Register(13,"运行模式",0,16,"runmode","java.lang.Boolean"));
  30 + registerList.add(new Register(14,"投料量",0,16,"runspeed","java.lang.Integer"));
  31 + registerList.add(new Register(15,"投料时间",0,16,"worktime","java.lang.Integer"));
  32 + registerList.add(new Register(16,"间隔时间",0,16,"interval","java.lang.Integer"));
  33 + registerList.add(new Register(17,"开/关",0,16,"runstate","java.lang.Integer"));
  34 + registerList.add(new Register(18,"停投料倒计时",0,16,"stopfeedcnt","java.lang.Integer"));
28 int startaddress = 23; 35 int startaddress = 23;
29 for(int i=0;i<48;i+=2) 36 for(int i=0;i<48;i+=2)
30 { 37 {
@@ -93,16 +100,21 @@ public class RegisterConreoller { @@ -93,16 +100,21 @@ public class RegisterConreoller {
93 register7.setChar_lenth(1); 100 register7.setChar_lenth(1);
94 register7.setField_name("timer"+timerNumber+"_is_close"); 101 register7.setField_name("timer"+timerNumber+"_is_close");
95 102
96 - list.add(register);  
97 - list.add(register1);  
98 - list.add(register2);  
99 - list.add(register3);  
100 - list.add(register4);  
101 - list.add(register5);  
102 - list.add(register6);  
103 - list.add(register7); 103 + registerList.add(register);
  104 + registerList.add(register1);
  105 + registerList.add(register2);
  106 + registerList.add(register3);
  107 + registerList.add(register4);
  108 + registerList.add(register5);
  109 + registerList.add(register6);
  110 + registerList.add(register7);
104 111
105 } 112 }
106 - return AjaxResult.success(publicService.insertAll(list)); 113 + return this;
  114 + }
  115 +
  116 + @Override
  117 + public void setValue(Field field, Object value) throws IllegalAccessException {
  118 + field.set(this,value);
107 } 119 }
108 } 120 }
@@ -3,17 +3,38 @@ package com.zhonglai.luhui.smart.feeder.dto; @@ -3,17 +3,38 @@ package com.zhonglai.luhui.smart.feeder.dto;
3 import lombok.Data; 3 import lombok.Data;
4 import lombok.experimental.Accessors; 4 import lombok.experimental.Accessors;
5 5
  6 +import java.lang.reflect.Field;
  7 +
  8 +/**
  9 + * 系统配置
  10 + */
6 @Data 11 @Data
7 @Accessors(chain = true) //链式写法 12 @Accessors(chain = true) //链式写法
8 -public class SysConfig { 13 +public class SysConfig implements OperatingDataType{
9 /** 14 /**
10 * 是否上报数据 15 * 是否上报数据
11 */ 16 */
12 - private Boolean ifUpLoadData; 17 + private Boolean ifUpLoadData = true;
13 18
14 /** 19 /**
15 * 是否显示 20 * 是否显示
16 */ 21 */
17 - private Boolean ifVeiw; 22 + private Boolean ifVeiw = false;
  23 +
  24 + private NettyConfig nettyConfig;
  25 +
  26 + private Boolean ifRegisterConfig = false;
  27 +
  28 + public SysConfig creteDefault()
  29 + {
  30 + ifUpLoadData = false;
  31 + ifVeiw = false;
  32 + nettyConfig = new NettyConfig();
  33 + return this;
  34 + }
18 35
  36 + @Override
  37 + public void setValue(Field field, Object value) throws IllegalAccessException {
  38 + field.set(this,value);
  39 + }
19 } 40 }
  1 +package com.zhonglai.luhui.smart.feeder.dto.commd;
  2 +
  3 +public class FeederBackstateTtpe {
  4 + /**
  5 + * 成功
  6 + */
  7 + public static int success = 0x37;
  8 + /**
  9 + * 串口没有找到
  10 + */
  11 + public static int serialPortErr = 0x90;
  12 + /**
  13 + * 程序运行时错误
  14 + */
  15 + public static int runErr = 0x91;
  16 + /**
  17 + * 串口没有找到
  18 + */
  19 + public static int serialPortCommandSendErr = 0x92;
  20 + /**
  21 + * 摄像头没有找到
  22 + */
  23 + public static int cameraErr = 0x93;
  24 +
  25 +}
  1 +package com.zhonglai.luhui.smart.feeder.dto.mqtt;
  2 +
  3 +import com.zhonglai.luhui.smart.feeder.dto.CameraConfig;
  4 +import lombok.Data;
  5 +import lombok.experimental.Accessors;
  6 +
  7 +@Data
  8 +@Accessors(chain = true) //链式写法
  9 +public class CameracontrolRequest {
  10 + private String cmd; //操作指令 devicedata
  11 + private String type; //设备网络型号 字符串("4G.hs")
  12 +
  13 + private CameraConfig cameraConfig;
  14 +}
1 package com.zhonglai.luhui.smart.feeder.dto.mqtt; 1 package com.zhonglai.luhui.smart.feeder.dto.mqtt;
2 2
3 -import io.swagger.models.auth.In;  
4 import lombok.Data; 3 import lombok.Data;
5 import lombok.experimental.Accessors; 4 import lombok.experimental.Accessors;
6 5
  1 +package com.zhonglai.luhui.smart.feeder.dto.mqtt;
  2 +
  3 +import com.google.gson.FieldNamingPolicy;
  4 +import com.google.gson.GsonBuilder;
  5 +import com.google.gson.JsonObject;
  6 +import com.ruoyi.common.utils.ByteUtil;
  7 +import com.ruoyi.common.utils.GsonConstructor;
  8 +import lombok.Data;
  9 +import lombok.experimental.Accessors;
  10 +
  11 +import java.io.UnsupportedEncodingException;
  12 +import java.util.regex.Matcher;
  13 +import java.util.regex.Pattern;
  14 +
  15 +@Data
  16 +@Accessors(chain = true) //链式写法
  17 +public class CmdDto {
  18 + private String start = "^";
  19 + private String imei;
  20 + private JsonObject jsonObject;
  21 + private String lrc;
  22 + private String end = "~";
  23 +
  24 + public CmdDto()
  25 + {
  26 +
  27 + }
  28 +
  29 + public CmdDto(String data)
  30 + {
  31 + String regEx = "(?:\\^)\\d+";
  32 + Matcher matcher = Pattern.compile(regEx).matcher(data);
  33 + if(matcher.find())
  34 + {
  35 + imei = matcher.group().replace("^","");
  36 + }
  37 + regEx = "\\w+(?:~)";
  38 + matcher = Pattern.compile(regEx).matcher(data);
  39 + if(matcher.find())
  40 + {
  41 + lrc = matcher.group().replace("~","");
  42 + }
  43 +
  44 + jsonObject = GsonConstructor.get().fromJson(getJsonData(data),JsonObject.class);
  45 + }
  46 +
  47 + public boolean checkLRC()
  48 + {
  49 + return lrc.toUpperCase().equals(generateLRC().toUpperCase());
  50 + }
  51 +
  52 + public String generateCmd()
  53 + {
  54 + return start+imei+new GsonBuilder().setVersion(1.0D).disableInnerClassSerialization().setFieldNamingPolicy(FieldNamingPolicy.IDENTITY).create().toJson(jsonObject)+generateLRC()+end;
  55 + }
  56 +
  57 + public String generateLRC()
  58 + {
  59 + String str = imei+new GsonBuilder().setVersion(1.0D).disableInnerClassSerialization().setFieldNamingPolicy(FieldNamingPolicy.IDENTITY).create().toJson(jsonObject);
  60 + try {
  61 + return ByteUtil.toHexString(ByteUtil.intToBytesASC(getLRC(str.getBytes("gb2312")),1));
  62 + } catch (UnsupportedEncodingException e) {
  63 + e.printStackTrace();
  64 + }
  65 + return null;
  66 + }
  67 +
  68 + private static String getJsonData(String data)
  69 + {
  70 + String regEx = "(?:\\{).*(?:})";
  71 + Matcher matcher = Pattern.compile(regEx).matcher(data);
  72 + if(matcher.find())
  73 + {
  74 + return matcher.group();
  75 + }
  76 + return null;
  77 + }
  78 +
  79 + /*
  80 + * 输入byte[] data , 返回LRC校验byte
  81 + */
  82 + private byte getLRC(byte[] data) {
  83 + int tmp = 0;
  84 + for (int i = 0; i < data.length; i++) {
  85 + tmp = tmp + (byte) data[i];
  86 + }
  87 + tmp = ~tmp;
  88 + tmp = (tmp & (0xff));
  89 + tmp += 1;
  90 + return (byte) tmp;
  91 + }
  92 +
  93 + public static void main(String[] args) {
  94 + String str = "5e 38 36 35 30 36 31 30 35 33 32 35 32 38 36 38 7b 22 63 6d 64 22 3a 22 6d 61 6e 75 61 6c 63 6f 6e 74 72 6f 6c 22 2c 22 74 79 70 65 22 3a 22 34 47 2e 68 73 22 2c 22 63 6f 6e 64 61 74 61 22 3a 7b 22 6f 6e 6f 66 66 22 3a 31 7d 7d 62 7e";
  95 + byte[] ss = ByteUtil.hexStringToByte(str.replace(" ","").toUpperCase());
  96 + CmdDto cmdDto = new CmdDto("^865061053252868{\"cmd\":\"manualcontrol\",\"type\":\"4G.hs\",\"condata\":{\"onoff\":1}}b~");
  97 + System.out.println(cmdDto.generateLRC());
  98 + System.out.println(cmdDto.generateCmd());
  99 +// CmdDto cmdDto = new CmdDto("^869537052982171{\"cmd\":\"devicedata\",\"type\":\"4G.hs\",\"signal\":3,\"machstate\":1,\"battlevel\":4,\"condata\":{\"runmode\":0,\"runspeed\":9,\"worktime\":6,\"interval\":4,\"runstate\":3,\"stopfeedcnt\":0},\"info\":{\"mfrs\":\"中渔科技\",\"equitype\":0,\"equimode\":0,\"faultcode\":0,\"fodderstate\":1,\"fodderweight\":65535,\"feednum\":65535,\"feedweight\":65535},\"timer\":[]}1F~");
  100 +// System.out.println(cmdDto.getLrc());
  101 +// System.out.println(cmdDto.generateLRC());
  102 + }
  103 +}
1 package com.zhonglai.luhui.smart.feeder.dto.mqtt; 1 package com.zhonglai.luhui.smart.feeder.dto.mqtt;
2 2
  3 +import com.zhonglai.luhui.smart.feeder.dto.*;
3 import lombok.Data; 4 import lombok.Data;
4 import lombok.experimental.Accessors; 5 import lombok.experimental.Accessors;
5 6
@@ -10,10 +11,16 @@ import java.util.List; @@ -10,10 +11,16 @@ import java.util.List;
10 public class DevicedatRequest { 11 public class DevicedatRequest {
11 private String cmd; //操作指令 devicedata 12 private String cmd; //操作指令 devicedata
12 private String type; //设备网络型号 字符串("4G.hs") 13 private String type; //设备网络型号 字符串("4G.hs")
13 - private String signal; //信号量  
14 - private String machstate; //机器状态  
15 - private String battlevel; //电池电量 14 + private Integer signal; //信号量
  15 + private Integer machstate; //机器状态
  16 + private Integer battlevel; //电池电量
16 private Condata condata; 17 private Condata condata;
17 private Info info; 18 private Info info;
18 private List<Integer[]> timer; //开启、关闭、使能 8:00开启-9:00关闭,状态:启用 19 private List<Integer[]> timer; //开启、关闭、使能 8:00开启-9:00关闭,状态:启用
  20 +
  21 + private SysConfig sysConfig;
  22 + private CameraData cameraData;
  23 + private CameraConfig cameraConfig;
  24 + private FeederConfig feederConfig;
  25 + private RegisterConfig registerConfig;
19 } 26 }
  1 +package com.zhonglai.luhui.smart.feeder.dto.mqtt;
  2 +
  3 +import lombok.Data;
  4 +
  5 +@Data
  6 +public class HeadDto
  7 +{
  8 + private String cmd;
  9 + private String type;
  10 +
  11 + private String errorcode;
  12 +}
  1 +package com.zhonglai.luhui.smart.feeder.dto.mqtt;
  2 +
  3 +import lombok.Data;
  4 +import lombok.experimental.Accessors;
  5 +
  6 +@Data
  7 +@Accessors(chain = true) //链式写法
  8 +public class ReturnOkDto {
  9 + private String cmd; //操作指令
  10 + private String type; //设备网络型号
  11 + private Integer backstate; //返回状态 正确返回0x36,其余错误
  12 + private Integer errorcode; //错误代码 0xE0:IMEI错误,0xE1:LRC错误,0xE2:指令错误,0xE4无效数据,0xE5不支持的指令
  13 +}
1 -package com.zhonglai.luhui.smart.feeder.mapper;  
2 -  
3 -  
4 -import com.zhonglai.luhui.dao.dto.PublicSQL;  
5 -import com.zhonglai.luhui.smart.feeder.dto.FishCurveControlCondition;  
6 -import org.apache.ibatis.annotations.Param;  
7 -import org.apache.ibatis.annotations.SelectProvider;  
8 -import org.springframework.stereotype.Component;  
9 -import tk.mybatis.mapper.common.BaseMapper;  
10 -  
11 -import java.util.List;  
12 -  
13 -@Component(value = "AbsValueCommandMapper")  
14 -public interface AbsValueCommandMapper extends BaseMapper<FishCurveControlCondition> {  
15 - @SelectProvider(type = PublicSQL.class, method = "getObjectListBySQL")  
16 - List<FishCurveControlCondition> getFishCurveControlConditionList(@Param("sql") String sql);  
17 -}  
1 package com.zhonglai.luhui.smart.feeder.service; 1 package com.zhonglai.luhui.smart.feeder.service;
2 2
3 -import cn.hutool.core.bean.BeanUtil;  
4 -import com.google.gson.JsonObject;  
5 import com.ruoyi.common.utils.ByteUtil; 3 import com.ruoyi.common.utils.ByteUtil;
6 -import com.zhonglai.luhui.smart.feeder.Main;  
7 import com.zhonglai.luhui.smart.feeder.domain.Register; 4 import com.zhonglai.luhui.smart.feeder.domain.Register;
8 import com.zhonglai.luhui.smart.feeder.dto.ModbusDto; 5 import com.zhonglai.luhui.smart.feeder.dto.ModbusDto;
9 import com.zhonglai.luhui.smart.feeder.dto.commd.FeederCommd; 6 import com.zhonglai.luhui.smart.feeder.dto.commd.FeederCommd;
@@ -22,13 +19,9 @@ import java.util.Map; @@ -22,13 +19,9 @@ import java.util.Map;
22 /** 19 /**
23 * 数据解析服务 20 * 数据解析服务
24 */ 21 */
25 -@Service  
26 public class AnalysisDataService { 22 public class AnalysisDataService {
27 private static final Logger logger = LoggerFactory.getLogger(AnalysisDataService.class); 23 private static final Logger logger = LoggerFactory.getLogger(AnalysisDataService.class);
28 24
29 - @Autowired  
30 - private ConfigurationParameterService configurationParameterService;  
31 -  
32 public Map<String,Object> analysis(ModbusDto modbusDto) 25 public Map<String,Object> analysis(ModbusDto modbusDto)
33 { 26 {
34 if(modbusDto instanceof FeederCommdDto) 27 if(modbusDto instanceof FeederCommdDto)
@@ -38,7 +31,7 @@ public class AnalysisDataService { @@ -38,7 +31,7 @@ public class AnalysisDataService {
38 FeederCommd feederCommd = feederCommdDto.getFeederCommd(); 31 FeederCommd feederCommd = feederCommdDto.getFeederCommd();
39 if (feederCommd instanceof FeederCommd03Request) 32 if (feederCommd instanceof FeederCommd03Request)
40 { 33 {
41 - Map<Integer, List<Register>> configMap = configurationParameterService.getRegisterMap(); 34 + Map<Integer, List<Register>> configMap = ConfigurationParameterService.registerMap;
42 35
43 Map<String,Object> valueMap = new HashMap<>(); 36 Map<String,Object> valueMap = new HashMap<>();
44 37
1 package com.zhonglai.luhui.smart.feeder.service; 1 package com.zhonglai.luhui.smart.feeder.service;
2 2
3 import cn.hutool.core.bean.BeanUtil; 3 import cn.hutool.core.bean.BeanUtil;
  4 +import cn.hutool.core.io.FileUtil;
  5 +import com.ruoyi.common.utils.GsonConstructor;
  6 +import com.zhonglai.luhui.smart.feeder.config.OperatingData;
4 import com.zhonglai.luhui.smart.feeder.domain.Register; 7 import com.zhonglai.luhui.smart.feeder.domain.Register;
5 -import com.zhonglai.luhui.smart.feeder.dto.ConfigurationParameter;  
6 -import com.zhonglai.luhui.smart.feeder.dto.FishCurveControlCondition;  
7 -import com.zhonglai.luhui.smart.feeder.dto.StateData;  
8 -import org.springframework.beans.factory.annotation.Autowired;  
9 -import org.springframework.stereotype.Service; 8 +import com.zhonglai.luhui.smart.feeder.dto.*;
10 9
11 -import javax.annotation.PostConstruct; 10 +import java.io.File;
  11 +import java.io.FileNotFoundException;
  12 +import java.io.IOException;
12 import java.util.ArrayList; 13 import java.util.ArrayList;
13 import java.util.HashMap; 14 import java.util.HashMap;
14 import java.util.List; 15 import java.util.List;
@@ -17,49 +18,76 @@ import java.util.Map; @@ -17,49 +18,76 @@ import java.util.Map;
17 /** 18 /**
18 * 配置参数 19 * 配置参数
19 */ 20 */
20 -@Service  
21 public class ConfigurationParameterService { 21 public class ConfigurationParameterService {
22 22
23 - private Map<Integer,List<Register>> registerMap = new HashMap<>(); //解析的数据字典 23 + public static Map<Integer,List<Register>> registerMap = new HashMap<>(); //解析的数据字典
24 24
25 - private Map<String,Register> controlMap = new HashMap<>(); //控制的数据字典 25 + public static Map<String,Register> controlMap = new HashMap<>(); //控制的数据字典
26 26
27 - @Autowired  
28 - private EhCacheService ehCacheService; 27 + public static void initConfigurationParameter()
  28 + {
  29 + try {
  30 + File sysConfigFile = new File("sysConfig");
  31 + if(!sysConfigFile.exists())
  32 + {
  33 + sysConfigFile.createNewFile();
  34 + SysConfig sysConfig = new SysConfig().creteDefault();
  35 + FileUtil.writeString(GsonConstructor.get().toJson(sysConfig),sysConfigFile,"UTF-8");
  36 + BeanUtil.copyProperties(sysConfig,OperatingData.sysConfig);
  37 + }else{
  38 + String str = FileUtil.readUtf8String(sysConfigFile);
  39 + SysConfig sysConfig = GsonConstructor.get().fromJson(str,SysConfig.class);
  40 + BeanUtil.copyProperties(sysConfig,OperatingData.sysConfig);
  41 + }
29 42
30 - @Autowired  
31 - private SqliteService sqliteService; 43 + File cameraConfigFile = new File("cameraConfig");
  44 + if(!cameraConfigFile.exists())
  45 + {
  46 + cameraConfigFile.createNewFile();
  47 + CameraConfig cameraConfig = new CameraConfig().creteDefault();
  48 + FileUtil.writeString(GsonConstructor.get().toJson(cameraConfig),cameraConfigFile,"UTF-8");
  49 + BeanUtil.copyProperties(cameraConfig,OperatingData.cameraConfig);
  50 + }else{
  51 + CameraConfig cameraConfig = GsonConstructor.get().fromJson(FileUtil.readUtf8String(cameraConfigFile),CameraConfig.class);
  52 + BeanUtil.copyProperties(cameraConfig,OperatingData.cameraConfig);
  53 + }
32 54
33 - private StateData stateData; 55 + File feederConfigFile = new File("feederConfig");
  56 + if(!feederConfigFile.exists())
  57 + {
  58 + feederConfigFile.createNewFile();
  59 + FeederConfig feederConfig = new FeederConfig().creteDefault();
  60 + FileUtil.writeString(GsonConstructor.get().toJson(feederConfig),feederConfigFile,"UTF-8");
  61 + BeanUtil.copyProperties(feederConfig,OperatingData.feederConfig);
  62 + }else{
  63 + FeederConfig feederConfig = GsonConstructor.get().fromJson(FileUtil.readUtf8String(feederConfigFile),FeederConfig.class);
  64 + BeanUtil.copyProperties(feederConfig,OperatingData.feederConfig);
  65 + }
34 66
35 - public void initConfigurationParameter()  
36 - {  
37 - //系统配置  
38 - List<Map<String,Object>> sysConfigList = sqliteService.getAllSysConfig();  
39 - if(null != sysConfigList && sysConfigList.size() != 0)  
40 - {  
41 - for(Map<String,Object> map:sysConfigList) 67 + File registerFile = new File("register");
  68 + if(!registerFile.exists())
42 { 69 {
43 - ConfigurationParameter configurationParameter = ConfigurationParameter.valueOf((String) map.get("parameter_name"));  
44 - ehCacheService.writeToCache(configurationParameter,map.get("parameter_value")); 70 + registerFile.createNewFile();
  71 + RegisterConfig registerConfig = new RegisterConfig().creteDefault();
  72 + FileUtil.writeString(GsonConstructor.get().toJson(registerConfig),registerFile,"UTF-8");
  73 + BeanUtil.copyProperties(registerConfig,OperatingData.registerConfig);
  74 + }else{
  75 + RegisterConfig registerConfig = GsonConstructor.get().fromJson(FileUtil.readUtf8String(registerFile),RegisterConfig.class);
  76 + BeanUtil.copyProperties(registerConfig,OperatingData.registerConfig);
45 } 77 }
46 - }  
47 78
48 - //斜率对应的档位  
49 - List<FishCurveControlCondition> absValueCommandList = sqliteService.getAllAbsValueCommand();  
50 - ehCacheService.writeToCache(ConfigurationParameter.absValue_command,new ArrayList<>());  
51 - if(null != absValueCommandList && absValueCommandList.size() != 0)  
52 - {  
53 - ehCacheService.writeToCache(ConfigurationParameter.absValue_command,absValueCommandList); 79 + } catch (FileNotFoundException e) {
  80 + throw new RuntimeException(e);
  81 + } catch (IOException e) {
  82 + throw new RuntimeException(e);
54 } 83 }
55 84
56 //数据解析字典 85 //数据解析字典
57 - List<Map<String,Object>> registerList = sqliteService.getAllRegister(); 86 + List<Register> registerList = OperatingData.registerConfig.getRegisterList();
58 if(null != registerList && registerList.size() != 0) 87 if(null != registerList && registerList.size() != 0)
59 { 88 {
60 - for (Map<String,Object> map:registerList) 89 + for (Register register:registerList)
61 { 90 {
62 - Register register = BeanUtil.mapToBean(map,Register.class,false,null);  
63 List<Register> list = registerMap.get(register.getAddress()); 91 List<Register> list = registerMap.get(register.getAddress());
64 if(null == list) 92 if(null == list)
65 { 93 {
@@ -69,121 +97,11 @@ public class ConfigurationParameterService { @@ -69,121 +97,11 @@ public class ConfigurationParameterService {
69 list.add(register); 97 list.add(register);
70 } 98 }
71 99
72 - for (Map<String,Object> map:registerList) 100 + for (Register register:registerList)
73 { 101 {
74 - Register register = BeanUtil.mapToBean(map,Register.class,false,null);  
75 controlMap.put(register.getField_name(),register); 102 controlMap.put(register.getField_name(),register);
76 } 103 }
77 } 104 }
78 105
79 } 106 }
80 -  
81 - public Map<String, Object> getAll()  
82 - {  
83 - return ehCacheService.getMyCache();  
84 - }  
85 -  
86 - public synchronized void setConfig(ConfigurationParameter configurationParameter,Object value)  
87 - {  
88 - switch (configurationParameter)  
89 - {  
90 - case absValue_command:  
91 - if(value instanceof ArrayList)  
92 - {  
93 - List<FishCurveControlCondition> slist = new ArrayList<>();  
94 - for(Object object:(List) value)  
95 - {  
96 - if(object instanceof FishCurveControlCondition)  
97 - {  
98 - slist = (List) value;  
99 - break;  
100 - }else if (object instanceof HashMap)  
101 - {  
102 - FishCurveControlCondition fishCurveControlCondition = BeanUtil.mapToBean((HashMap)object,FishCurveControlCondition.class,false,null);  
103 - slist.add(fishCurveControlCondition);  
104 - }  
105 - }  
106 -  
107 - setabsValueCommandList(slist);  
108 - }else if(value instanceof FishCurveControlCondition)  
109 - {  
110 - setabsValueCommand((FishCurveControlCondition) value);  
111 - }else {  
112 - throw new RuntimeException("配置参数类型不正确");  
113 - }  
114 - break;  
115 - default:  
116 - if(configurationParameter.getPersistence())  
117 - {  
118 - setDefaultCommandMap(configurationParameter,value);  
119 - }else{  
120 - setNotPersistenceCommandMap(configurationParameter,value);  
121 - }  
122 -  
123 - }  
124 -  
125 - }  
126 -  
127 -  
128 - public Object getConfig(ConfigurationParameter configurationParameter)  
129 - {  
130 - return ehCacheService.readFromCache(configurationParameter);  
131 - }  
132 -  
133 - private void setNotPersistenceCommandMap(ConfigurationParameter configurationParameter,Object value)  
134 - {  
135 - ehCacheService.writeToCache(configurationParameter,value);  
136 - }  
137 -  
138 - private void setDefaultCommandMap(ConfigurationParameter configurationParameter,Object value)  
139 - {  
140 - ehCacheService.writeToCache(configurationParameter,value);  
141 - sqliteService.updateConfigurationParameter(configurationParameter,value);  
142 - }  
143 -  
144 -  
145 - private void setabsValueCommandList(List<FishCurveControlCondition> absValueCommandList)  
146 - {  
147 -  
148 - sqliteService.deleteabsValueCommandAll();  
149 - ehCacheService.readFromCache(ConfigurationParameter.absValue_command);  
150 -  
151 - for (FishCurveControlCondition fishCurveControlCondition:absValueCommandList)  
152 - {  
153 - sqliteService.updateabsValueCommand(fishCurveControlCondition.getGear(),fishCurveControlCondition.getSartAbsValue());  
154 - }  
155 -  
156 - ehCacheService.writeToCache(ConfigurationParameter.absValue_command,absValueCommandList);  
157 - }  
158 -  
159 - private void setabsValueCommand(FishCurveControlCondition absValueCommand)  
160 - {  
161 - List<FishCurveControlCondition> old = (List<FishCurveControlCondition>) ehCacheService.readFromCache(ConfigurationParameter.absValue_command);  
162 - if(null == old)  
163 - {  
164 - old = new ArrayList<>();  
165 - }  
166 - old.removeIf(condition -> condition.getGear().equals(absValueCommand.getGear()));  
167 -  
168 - ehCacheService.writeToCache(ConfigurationParameter.absValue_command,old);  
169 -  
170 - sqliteService.updateabsValueCommand(absValueCommand.getGear(),absValueCommand.getSartAbsValue());  
171 -  
172 - }  
173 -  
174 - public Map<Integer, List<Register>> getRegisterMap() {  
175 - return registerMap;  
176 - }  
177 -  
178 - public Map<String, Register> getControlMap() {  
179 - return controlMap;  
180 - }  
181 -  
182 - public StateData getStateData() {  
183 - return stateData;  
184 - }  
185 -  
186 - public void setStateData(StateData stateData) {  
187 - this.stateData = stateData;  
188 - }  
189 } 107 }
@@ -2,126 +2,180 @@ package com.zhonglai.luhui.smart.feeder.service; @@ -2,126 +2,180 @@ package com.zhonglai.luhui.smart.feeder.service;
2 2
3 import cn.hutool.core.bean.BeanUtil; 3 import cn.hutool.core.bean.BeanUtil;
4 import com.alibaba.fastjson.JSONObject; 4 import com.alibaba.fastjson.JSONObject;
5 -import com.zhonglai.luhui.smart.feeder.dto.ConfigurationParameter;  
6 -import com.zhonglai.luhui.smart.feeder.dto.ModbusDto;  
7 -import com.zhonglai.luhui.smart.feeder.dto.StateData;  
8 -import com.zhonglai.luhui.smart.feeder.dto.VeiwDto; 5 +import com.google.gson.Gson;
  6 +import com.google.gson.JsonObject;
  7 +import com.ruoyi.common.utils.GsonConstructor;
  8 +import com.zhonglai.luhui.smart.feeder.config.OperatingData;
  9 +import com.zhonglai.luhui.smart.feeder.config.ScheduledConfig;
  10 +import com.zhonglai.luhui.smart.feeder.dto.*;
  11 +import com.zhonglai.luhui.smart.feeder.dto.commd.FeederTimer;
  12 +import com.zhonglai.luhui.smart.feeder.dto.mqtt.CmdDto;
  13 +import com.zhonglai.luhui.smart.feeder.dto.mqtt.Condata;
  14 +import com.zhonglai.luhui.smart.feeder.dto.mqtt.DevicedatRequest;
  15 +import com.zhonglai.luhui.smart.feeder.dto.mqtt.Info;
9 import com.zhonglai.luhui.smart.feeder.service.device.SerialPortService; 16 import com.zhonglai.luhui.smart.feeder.service.device.SerialPortService;
10 import com.zhonglai.luhui.smart.feeder.util.FeederCommdUtil; 17 import com.zhonglai.luhui.smart.feeder.util.FeederCommdUtil;
11 -import org.eclipse.paho.client.mqttv3.MqttException; 18 +import com.zhonglai.luhui.smart.feeder.util.MessageUtil;
12 import org.slf4j.Logger; 19 import org.slf4j.Logger;
13 import org.slf4j.LoggerFactory; 20 import org.slf4j.LoggerFactory;
14 -import org.springframework.beans.factory.annotation.Autowired;  
15 -import org.springframework.stereotype.Service;  
16 21
  22 +import java.util.ArrayList;
  23 +import java.util.List;
17 import java.util.Map; 24 import java.util.Map;
18 -import java.util.concurrent.ScheduledExecutorService;  
19 import java.util.concurrent.TimeUnit; 25 import java.util.concurrent.TimeUnit;
20 26
21 /** 27 /**
22 * 数据监听服务 28 * 数据监听服务
23 */ 29 */
24 -@Service  
25 public class DateListenService { 30 public class DateListenService {
26 private static final Logger logger = LoggerFactory.getLogger(DateListenService.class); 31 private static final Logger logger = LoggerFactory.getLogger(DateListenService.class);
27 - @Autowired  
28 - private ScheduledExecutorService scheduledExecutorService;  
29 32
30 - @Autowired  
31 - private SerialPortService serialPortService;  
32 -  
33 - @Autowired  
34 - private AnalysisDataService analysisDataService;  
35 -  
36 - @Autowired  
37 - private TerminalService terminalService; 33 + private AnalysisDataService analysisDataService = new AnalysisDataService();
38 34
39 - @Autowired  
40 - private ConfigurationParameterService configurationParameterService; 35 + private SerialPortService serialPortService;
41 36
42 - @Autowired  
43 - private FishGroupImageRecognitionService fishGroupImageRecognitionService; 37 + public DateListenService(SerialPortService serialPortService)
  38 + {
  39 + this.serialPortService = serialPortService;
  40 + }
44 41
45 public void run() 42 public void run()
46 { 43 {
47 - scheduledExecutorService.scheduleAtFixedRate(() -> {  
48 -  
49 - try {  
50 - gatherDevice0();  
51 - Thread.sleep(1000);  
52 - } catch (MqttException e) {  
53 - logger.error("采集主机信息失败",e);  
54 - } catch (InterruptedException e) {  
55 - throw new RuntimeException(e); 44 + //更新投料机数据
  45 + ScheduledConfig.scheduler.scheduleAtFixedRate(() -> {
  46 + ModbusDto modbusDto = serialPortService.sendHexData(FeederCommdUtil.readAll());
  47 + Map<String,Object> data = analysisDataService.analysis(modbusDto);
  48 + if(null != data && data.size() != 0)
  49 + {
  50 + Condata condata = BeanUtil.mapToBean(data, Condata.class,false,null);
  51 + Info info = BeanUtil.mapToBean(data, Info.class,false,null);
  52 + OperatingData.devicedat.setCondata(condata);
  53 + OperatingData.devicedat.setInfo(info);
  54 +
  55 + List<Integer[]> timerList = new ArrayList<>();
  56 + for(String key:data.keySet())
  57 + {
  58 + if(key.startsWith("timer"))
  59 + {
  60 + FeederTimer feederTimer = (FeederTimer) data.get(key);
  61 + timerList.add(new Integer[]{feederTimer.getTimer_start_h(),feederTimer.getTimer_start_m(),feederTimer.getTimer_close_h(),feederTimer.getTimer_start_m(),feederTimer.getTimer_if_start()});
  62 + }
  63 + }
  64 +
  65 + if(null != timerList && timerList.size() != 0)
  66 + {
  67 + OperatingData.devicedat.setTimer(timerList);
  68 + }
56 } 69 }
57 - try {  
58 - gatherDevice1();  
59 - Thread.sleep(1000);  
60 - } catch (MqttException e) {  
61 - logger.error("采集投料机数据失败",e);  
62 - }catch (InterruptedException e) {  
63 - throw new RuntimeException(e); 70 + },1,10, TimeUnit.SECONDS);
  71 +
  72 + //上报数据
  73 + ScheduledConfig.scheduler.scheduleAtFixedRate(() -> {
  74 + if(OperatingData.sysConfig.getIfUpLoadData())
  75 + {
  76 + try {
  77 + if(InitService.nettyClient.getCtx().channel().isOpen())
  78 + {
  79 + DevicedatRequest devicedatRequest = new DevicedatRequest();
  80 + devicedatRequest.setCmd("devicedata");
  81 + devicedatRequest.setType("4G.hs");
  82 + devicedatRequest.setSignal(4);
  83 + devicedatRequest.setMachstate(1);
  84 + devicedatRequest.setBattlevel(4);
  85 + devicedatRequest.setCondata(OperatingData.devicedat.getCondata());
  86 + devicedatRequest.setInfo(OperatingData.devicedat.getInfo());
  87 + devicedatRequest.setTimer(OperatingData.devicedat.getTimer());
  88 + String str = GsonConstructor.get().toJson(devicedatRequest);
  89 + System.out.println(str);
  90 + if(str.length()>=1024)
  91 + {
  92 + System.out.println("超标了");
  93 + }
  94 + CmdDto cmdDto = new CmdDto().setImei(OperatingData.sysConfig.getNettyConfig().getClientId()).setJsonObject( GsonConstructor.get().fromJson( str, JsonObject.class));
  95 + MessageUtil.sendMessage(InitService.nettyClient.getCtx(), cmdDto.generateCmd(),true);
  96 +
  97 + Thread.sleep(10000);
  98 +
  99 + devicedatRequest = new DevicedatRequest();
  100 + devicedatRequest.setCmd("devicedata");
  101 + devicedatRequest.setType("4G.hs");
  102 + devicedatRequest.setSignal(4);
  103 + devicedatRequest.setMachstate(1);
  104 + devicedatRequest.setBattlevel(4);
  105 + devicedatRequest.setSysConfig(OperatingData.sysConfig);
  106 + devicedatRequest.setFeederConfig(OperatingData.feederConfig);
  107 + str = GsonConstructor.get().toJson(devicedatRequest);
  108 + System.out.println(str);
  109 + if(str.length()>=1024)
  110 + {
  111 + System.out.println("超标了");
  112 + }
  113 + cmdDto = new CmdDto().setImei(OperatingData.sysConfig.getNettyConfig().getClientId()).setJsonObject( GsonConstructor.get().fromJson( str, JsonObject.class));
  114 + MessageUtil.sendMessage(InitService.nettyClient.getCtx(), cmdDto.generateCmd(),true);
  115 +
  116 + Thread.sleep(10000);
  117 +
  118 + devicedatRequest = new DevicedatRequest();
  119 + devicedatRequest.setCmd("devicedata");
  120 + devicedatRequest.setType("4G.hs");
  121 + devicedatRequest.setSignal(4);
  122 + devicedatRequest.setMachstate(1);
  123 + devicedatRequest.setBattlevel(4);
  124 + devicedatRequest.setCameraData(OperatingData.cameraData);
  125 + devicedatRequest.setCameraConfig(OperatingData.cameraConfig);
  126 + str = GsonConstructor.get().toJson(devicedatRequest);
  127 + System.out.println(str);
  128 + if(str.length()>=1024)
  129 + {
  130 + System.out.println("超标了");
  131 + }
  132 + cmdDto = new CmdDto().setImei(OperatingData.sysConfig.getNettyConfig().getClientId()).setJsonObject( GsonConstructor.get().fromJson( str, JsonObject.class));
  133 + MessageUtil.sendMessage(InitService.nettyClient.getCtx(), cmdDto.generateCmd(),true);
  134 +
  135 + if(OperatingData.sysConfig.getIfRegisterConfig())
  136 + {
  137 + Thread.sleep(10000);
  138 +
  139 + devicedatRequest = new DevicedatRequest();
  140 + devicedatRequest.setCmd("devicedata");
  141 + devicedatRequest.setType("4G.hs");
  142 + devicedatRequest.setSignal(4);
  143 + devicedatRequest.setMachstate(1);
  144 + devicedatRequest.setBattlevel(4);
  145 + devicedatRequest.setRegisterConfig(OperatingData.registerConfig);
  146 + str = GsonConstructor.get().toJson(devicedatRequest);
  147 + cmdDto = new CmdDto().setImei(OperatingData.sysConfig.getNettyConfig().getClientId()).setJsonObject( GsonConstructor.get().fromJson( str, JsonObject.class));
  148 + MessageUtil.sendMessage(InitService.nettyClient.getCtx(), cmdDto.generateCmd(),true);
  149 + }
  150 + }
  151 + }catch (Exception e)
  152 + {
  153 + logger.error("上传数据异常",e);
  154 + }
64 } 155 }
65 - try {  
66 - gatherDevice2();  
67 - } catch (MqttException e) {  
68 - logger.error("采集摄像头信息失败",e);  
69 - }  
70 -  
71 - },1,60, TimeUnit.SECONDS);  
72 - }  
73 156
74 - /**  
75 - * 采集投料机数据  
76 - */  
77 - private void gatherDevice1() throws MqttException {  
78 - if(null == configurationParameterService.getConfig(ConfigurationParameter.ifUpLoadData) || !(Boolean) configurationParameterService.getConfig(ConfigurationParameter.ifUpLoadData))  
79 - {  
80 - return;  
81 - }  
82 - ModbusDto modbusDto = serialPortService.sendHexData(FeederCommdUtil.readAll());  
83 - Map<String,Object> data = analysisDataService.analysis(modbusDto);  
84 - if(null != data && data.size() != 0)  
85 - {  
86 - StateData stateData = BeanUtil.mapToBean(data, StateData.class,false,null);  
87 - configurationParameterService.setStateData(stateData);  
88 -  
89 - JSONObject jsonObject = new JSONObject();  
90 - jsonObject.put("10_1",data);  
91 - String topic = "ALL_POST";  
92 - terminalService.publish(topic,jsonObject.toJSONString());  
93 - } 157 + },1,10, TimeUnit.SECONDS);
94 } 158 }
95 159
96 - /**  
97 - * 采集主机信息  
98 - */  
99 - private void gatherDevice0() throws MqttException {  
100 - Map<String, Object> map = configurationParameterService.getAll();  
101 -  
102 - if(null != map && map.size() !=0)  
103 - {  
104 - JSONObject jsonObject = new JSONObject();  
105 - jsonObject.put("0",map);  
106 - String topic = "ADD_POST";  
107 - terminalService.publish(topic,jsonObject.toJSONString());  
108 - } 160 + public static void main(String[] args) {
  161 + ConfigurationParameterService.initConfigurationParameter();
  162 + DevicedatRequest devicedatRequest = new DevicedatRequest();
  163 + devicedatRequest.setCmd("devicedata");
  164 + devicedatRequest.setType("4G.hs");
  165 + devicedatRequest.setSignal(4);
  166 + devicedatRequest.setMachstate(1);
  167 + devicedatRequest.setBattlevel(4);
  168 +
  169 + devicedatRequest.setCondata(OperatingData.devicedat.getCondata());
  170 + devicedatRequest.setInfo(OperatingData.devicedat.getInfo());
  171 + devicedatRequest.setTimer(OperatingData.devicedat.getTimer());
  172 +
  173 + devicedatRequest.setSysConfig(OperatingData.sysConfig);
  174 + devicedatRequest.setCameraData(OperatingData.cameraData);
  175 + devicedatRequest.setCameraConfig(OperatingData.cameraConfig);
  176 + devicedatRequest.setFeederConfig(OperatingData.feederConfig);
  177 +
  178 + System.out.println(GsonConstructor.get().toJson(devicedatRequest));
109 } 179 }
110 180
111 - /**  
112 - * 采集摄像头信息  
113 - */  
114 - private void gatherDevice2() throws MqttException {  
115 - VeiwDto veiwDto = fishGroupImageRecognitionService.getVeiwDto();  
116 - if(null != veiwDto && BeanUtil.isNotEmpty(veiwDto,"size","absValue"))  
117 - {  
118 - veiwDto = BeanUtil.copyProperties(veiwDto,VeiwDto.class,"frame","binaryImage");  
119 -  
120 - JSONObject jsonObject = new JSONObject();  
121 - jsonObject.put("1_1",veiwDto);  
122 - String topic = "ALL_POST";  
123 - terminalService.publish(topic,jsonObject.toJSONString());  
124 - }  
125 -  
126 - }  
127 } 181 }
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.zhonglai.luhui.smart.feeder.config.OperatingData;
  4 +import com.zhonglai.luhui.smart.feeder.config.ScheduledConfig;
4 import com.zhonglai.luhui.smart.feeder.dto.*; 5 import com.zhonglai.luhui.smart.feeder.dto.*;
  6 +import com.zhonglai.luhui.smart.feeder.dto.mqtt.Condata;
5 import com.zhonglai.luhui.smart.feeder.service.device.SerialPortService; 7 import com.zhonglai.luhui.smart.feeder.service.device.SerialPortService;
6 import com.zhonglai.luhui.smart.feeder.util.FeederCommd06ResponseType; 8 import com.zhonglai.luhui.smart.feeder.util.FeederCommd06ResponseType;
7 import com.zhonglai.luhui.smart.feeder.util.FeederCommdUtil; 9 import com.zhonglai.luhui.smart.feeder.util.FeederCommdUtil;
8 import org.slf4j.Logger; 10 import org.slf4j.Logger;
9 import org.slf4j.LoggerFactory; 11 import org.slf4j.LoggerFactory;
10 -import org.springframework.beans.factory.annotation.Autowired;  
11 -import org.springframework.stereotype.Service;  
12 12
13 import java.util.*; 13 import java.util.*;
14 -import java.util.concurrent.ScheduledExecutorService;  
15 import java.util.concurrent.TimeUnit; 14 import java.util.concurrent.TimeUnit;
16 15
17 /** 16 /**
18 * 设备管理 17 * 设备管理
19 */ 18 */
20 -@Service  
21 public class DeviceService { 19 public class DeviceService {
22 private static Logger logger = LoggerFactory.getLogger(DeviceService.class); 20 private static Logger logger = LoggerFactory.getLogger(DeviceService.class);
23 -  
24 - private Double backArea; //上一个大小  
25 -  
26 - private Double slope; //斜率  
27 - private Double backSlope; //斜率  
28 - private Double slopeDifference; //斜率差值  
29 -  
30 - private Double absValue; //斜率差值的绝对值  
31 -  
32 - private Integer nowGear; //当前档位  
33 -  
34 - private Integer oldGear; //老的档位  
35 -  
36 - private Double area; //面积  
37 -  
38 - @Autowired  
39 - private ConfigurationParameterService configurationParameterService;  
40 -  
41 - @Autowired  
42 - private ScheduledExecutorService scheduledExecutorService;  
43 -  
44 - @Autowired  
45 - private EhCacheService ehCacheService;  
46 -  
47 - @Autowired  
48 private SerialPortService serialPortService; 21 private SerialPortService serialPortService;
49 22
  23 + public DeviceService(SerialPortService serialPortService)
  24 + {
  25 + this.serialPortService = serialPortService;
  26 + }
  27 +
50 public void run() 28 public void run()
51 { 29 {
52 //投料控制 30 //投料控制
53 - scheduledExecutorService.scheduleWithFixedDelay(() -> {  
54 - if (((Boolean)ehCacheService.readFromCache(ConfigurationParameter.FeedingControl))) {  
55 - logger.info("当前档位{},以前的档位{},斜率{},斜率差值{},面积{},开关是否打开{}",nowGear,oldGear,slope,absValue,area,null == configurationParameterService.getStateData()?"未知":configurationParameterService.getStateData().getSwitch_status()); 31 + ScheduledConfig.scheduler.scheduleWithFixedDelay(() -> {
  32 + if (OperatingData.cameraConfig.getFeedingControl()) {
  33 + Condata condata = OperatingData.devicedat.getCondata();
  34 + CameraData cameraData = OperatingData.cameraData;
  35 + logger.info("摄像头识别档位{},投料机的档位{},斜率{},斜率差值{},面积{},开关是否打开{}",cameraData.getNowGear(),condata.getRunspeed(),cameraData.getSlope(),cameraData.getAbsValue(),cameraData.getArea(),null == condata.getRunstate()?"未知":condata.getRunstate());
  36 +
  37 + getGearFromAbsValue();
56 38
57 - if(null != nowGear && oldGear != nowGear) 39 + if(null !=condata && 1==condata.getRunstate()) //数据状态出来了,并且设备已经启动
58 { 40 {
59 - if(nowGear>0 ) //如果档位有值 41 + if(1==condata.getRunmode()) //只有手动模式才能控制
60 { 42 {
61 - if(null !=configurationParameterService.getStateData() && 1==configurationParameterService.getStateData().getRunmode())  
62 - {  
63 - serialPortService.sendHexData(FeederCommdUtil.controlData(FeederCommd06ResponseType.runmode,0)); //,运行模式改成手动  
64 - }  
65 - if(null !=configurationParameterService.getStateData() && 0==configurationParameterService.getStateData().getSwitch_status()) 43 + ModbusDto modbusDto = serialPortService.sendHexData(FeederCommdUtil.controlData(FeederCommd06ResponseType.runmode,0)); //,运行模式改成手动
  44 + if(null!=modbusDto)
66 { 45 {
67 - serialPortService.sendHexData(FeederCommdUtil.controlData(FeederCommd06ResponseType.OnOroff,1)); //,开关是关的就先打开开关 46 + condata.setRunmode(1);
68 } 47 }
69 - serialPortService.sendHexData(FeederCommdUtil.controlData(FeederCommd06ResponseType.runspeed,nowGear));  
70 - oldGear = nowGear;  
71 - }else{  
72 - if(null !=configurationParameterService.getStateData() && 0==configurationParameterService.getStateData().getRunmode())  
73 - {  
74 - serialPortService.sendHexData(FeederCommdUtil.controlData(FeederCommd06ResponseType.runmode,1)); //,运行模式改成自动  
75 - }  
76 - if(null !=configurationParameterService.getStateData() && 1==configurationParameterService.getStateData().getSwitch_status()) 48 + }
  49 +
  50 + if( cameraData.getNowGear() != condata.getRunspeed())
  51 + {
  52 + ModbusDto modbusDto = serialPortService.sendHexData(FeederCommdUtil.controlData(FeederCommd06ResponseType.runspeed,cameraData.getNowGear())); //较准档位
  53 + if(null!=modbusDto)
77 { 54 {
78 - serialPortService.sendHexData(FeederCommdUtil.controlData(FeederCommd06ResponseType.OnOroff,0)); //,开关是关的就先打开开关 55 + condata.setRunspeed(cameraData.getNowGear());
79 } 56 }
80 } 57 }
81 -  
82 -  
83 } 58 }
84 } 59 }
85 },1,1, TimeUnit.SECONDS); 60 },1,1, TimeUnit.SECONDS);
86 } 61 }
87 62
88 - public String getState()  
89 - {  
90 - Map<String,Object> map = new HashMap<>();  
91 - map.put("backArea",backArea);  
92 - map.put("slope",slope);  
93 - map.put("backSlope",backSlope);  
94 - map.put("slopeDifference",slopeDifference);  
95 - map.put("absValue",absValue);  
96 - map.put("nowGear",nowGear);  
97 - return GsonConstructor.get().toJson(map);  
98 - }  
99 -  
100 - /**  
101 - * 根据面积计算斜率  
102 - * @param area  
103 - * @return  
104 - */  
105 - public double controlDevice(double area)  
106 - {  
107 - this.area = area;  
108 - if(null == backArea )  
109 - {  
110 - backArea = area;  
111 - return 0;  
112 - }  
113 -  
114 - slope = area-backArea;  
115 - if(null == backSlope)  
116 - {  
117 - backSlope = slope;  
118 - }  
119 -  
120 - slopeDifference = slope-backSlope;  
121 -  
122 - absValue = Math.abs(slopeDifference);  
123 -  
124 - nowGear = getGearFromAbsValue();  
125 - return absValue;  
126 - }  
127 -  
128 /** 63 /**
129 * 根据斜率计算档位 64 * 根据斜率计算档位
130 * @return 65 * @return
131 */ 66 */
132 private Integer getGearFromAbsValue() 67 private Integer getGearFromAbsValue()
133 { 68 {
  69 + Double absValue = OperatingData.cameraData.getAbsValue();
134 Integer gear = null; 70 Integer gear = null;
135 - List<FishCurveControlCondition> list = (List<FishCurveControlCondition>) ehCacheService.readFromCache(ConfigurationParameter.absValue_command); 71 +
  72 + List<FishCurveControlCondition> list = OperatingData.cameraConfig.getAbsValue_command();
136 if(null != list && list.size() != 0) 73 if(null != list && list.size() != 0)
137 { 74 {
138 list.sort(Comparator.comparing(FishCurveControlCondition::getSartAbsValue));//以 sartAbsValue 升序排序 75 list.sort(Comparator.comparing(FishCurveControlCondition::getSartAbsValue));//以 sartAbsValue 升序排序
@@ -145,6 +82,7 @@ public class DeviceService { @@ -145,6 +82,7 @@ public class DeviceService {
145 } 82 }
146 } 83 }
147 } 84 }
  85 + OperatingData.cameraData.setNowGear(gear);
148 return gear; 86 return gear;
149 } 87 }
150 88
1 -package com.zhonglai.luhui.smart.feeder.service;  
2 -  
3 -import com.ruoyi.common.utils.GsonConstructor;  
4 -import com.zhonglai.luhui.smart.feeder.dto.ConfigurationParameter;  
5 -import com.zhonglai.luhui.smart.feeder.dto.SerialPortConfig;  
6 -import org.springframework.stereotype.Service;  
7 -  
8 -import java.util.HashMap;  
9 -import java.util.Map;  
10 -  
11 -/**  
12 - * 缓存  
13 - */  
14 -@Service  
15 -public class EhCacheService {  
16 - private static Map<String,Object> cacheMap = new HashMap<>();  
17 -  
18 -  
19 - public void writeToCache(ConfigurationParameter key, Object value) {  
20 - Class cls = key.getValuType();  
21 - if(cls.isInstance(value))  
22 - {  
23 - cacheMap.put(key.name(), cls.cast(value));  
24 - }else if(value instanceof String)  
25 - {  
26 - switch (cls.getName())  
27 - {  
28 - case "java.lang.Boolean":  
29 - cacheMap.put(key.name(), Boolean.valueOf((String) value));  
30 - return;  
31 - case "java.lang.Integer":  
32 - cacheMap.put(key.name(), Integer.valueOf((String) value));  
33 - return;  
34 - case "java.lang.Double":  
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));  
39 - return;  
40 - case "com.zhonglai.luhui.smart.feeder.dto.SerialPortConfig":  
41 - SerialPortConfig serialPortConfig = GsonConstructor.get().fromJson((String) value,SerialPortConfig.class);  
42 - cacheMap.put(key.name(), serialPortConfig);  
43 - return;  
44 - default:  
45 - throw new RuntimeException("配置参数类型不正确"+key+value);  
46 - }  
47 - }else{  
48 - throw new RuntimeException("配置参数类型不正确");  
49 - }  
50 -  
51 - }  
52 -  
53 - public Object readFromCache(ConfigurationParameter key) {  
54 - return cacheMap.get(key.name());  
55 - }  
56 -  
57 - public Map<String, Object> getMyCache() {  
58 - return cacheMap;  
59 - }  
60 -  
61 - public void shutdown() {  
62 - if (cacheMap != null) {  
63 - cacheMap.clear();  
64 - }  
65 - }  
66 -}  
1 -package com.zhonglai.luhui.smart.feeder.service;  
2 -  
3 -import cn.hutool.core.util.ArrayUtil;  
4 -import com.ruoyi.common.utils.StringUtils;  
5 -import org.bytedeco.ffmpeg.global.avcodec;  
6 -import org.bytedeco.ffmpeg.global.avutil;  
7 -import org.bytedeco.javacv.*;  
8 -import org.bytedeco.javacv.Frame;  
9 -import org.slf4j.Logger;  
10 -import org.slf4j.LoggerFactory;  
11 -import org.springframework.beans.factory.annotation.Autowired;  
12 -import org.springframework.stereotype.Service;  
13 -  
14 -import java.awt.*;  
15 -import java.awt.image.BufferedImage;  
16 -import java.time.LocalDateTime;  
17 -import java.time.format.DateTimeFormatter;  
18 -import java.util.ArrayList;  
19 -import java.util.concurrent.ScheduledExecutorService;  
20 -import java.util.concurrent.TimeUnit;  
21 -  
22 -@Service  
23 -public class FFmCameraService {  
24 - private static final Logger logger = LoggerFactory.getLogger(FFmCameraService.class);  
25 -  
26 - private FFmpegFrameGrabber grabber;  
27 -  
28 - private OpenCVFrameConverter.ToOrgOpenCvCoreMat converter2 = new OpenCVFrameConverter.ToOrgOpenCvCoreMat();  
29 -  
30 - @Autowired  
31 - private ScheduledExecutorService scheduledExecutorService;  
32 -  
33 - @Autowired  
34 - private SrsService srsService;  
35 -  
36 - private static String MAC = "78-a6-a0-d2-bd-e1";  
37 -  
38 -  
39 - public boolean getVideoIsOpen()  
40 - {  
41 - return !grabber.isDeinterlace();  
42 - }  
43 -  
44 - public void start()  
45 - {  
46 - loadCamera();  
47 - }  
48 -  
49 - public static void main(String[] args) {  
50 - pushCamera();  
51 - }  
52 -  
53 - public static void pushCamera()  
54 - {  
55 - String ip = "192.168.0.198";  
56 - String inputUrl = "rtsp://admin:Luhui586@" + ip + ":554/h264/ch1/main/av_stream";  
57 - String outputUrl = "rtmp://119.23.218.181:21935/live/70094a59d1d991d";  
58 -  
59 - try {  
60 - FFmpegFrameGrabber.tryLoad();  
61 - } catch (Exception e) {  
62 - throw new RuntimeException("Failed to load FFmpeg", e);  
63 - }  
64 -  
65 - FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputUrl);  
66 - grabber.setVideoOption("fflags", "nobuffer");  
67 - grabber.setVideoOption("rtsp_transport", "tcp");  
68 - grabber.setOption("stimeout", "2000000");  
69 - avutil.av_log_set_level(avutil.AV_LOG_ERROR);  
70 -  
71 - try {  
72 - grabber.start();  
73 - Frame frame = grabber.grabImage();  
74 - while (0 == frame.imageWidth)  
75 - {  
76 - Thread.sleep(1000);  
77 - }  
78 - FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputUrl, frame.imageWidth, frame.imageHeight);  
79 - recorder.setFormat("flv");  
80 - recorder.setFrameRate(30);  
81 - recorder.setVideoBitrate(2000000);  
82 - recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);  
83 - recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);  
84 -  
85 - recorder.start();  
86 -  
87 - Frame capturedFrame;  
88 - while ((capturedFrame = grabber.grabImage()) != null) {  
89 - recorder.record(capturedFrame);  
90 - }  
91 -  
92 - grabber.stop();  
93 - recorder.stop();  
94 -  
95 - System.out.println("摄像头流推送完成");  
96 - } catch (Exception e) {  
97 - e.printStackTrace();  
98 - }  
99 - }  
100 -  
101 - /**  
102 - * 加载摄像头  
103 - */  
104 - public void loadCamera()  
105 - {  
106 - String ip = "192.168.0.198";  
107 - if(StringUtils.isEmpty(ip))  
108 - {  
109 - System.out.println("没有找到摄像头:"+MAC);  
110 - return;  
111 - }  
112 - String rtspUrl = "rtsp://admin:Luhui586@"+ip+":554/h264/ch1/main/av_stream";  
113 -  
114 - try {  
115 - FFmpegFrameGrabber.tryLoad();  
116 - } catch (Exception e) {  
117 - throw new RuntimeException("Failed to load FFmpeg", e);  
118 - }  
119 -  
120 - grabber = new FFmpegFrameGrabber(rtspUrl);  
121 - grabber.setVideoOption("fflags", "nobuffer"); // 禁用缓冲  
122 - grabber.setVideoOption("rtsp_transport", "tcp"); // 使用TCP传输  
123 - grabber.setOption("stimeout", "2000000");  
124 - avutil.av_log_set_level(avutil.AV_LOG_ERROR); // 设置日志级别  
125 -  
126 - try {  
127 - grabber.start();  
128 - } catch (Exception e) {  
129 - close();  
130 - e.printStackTrace();  
131 - }  
132 -// scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {  
133 -// @Override  
134 -// public void run() {  
135 -// if()  
136 -// {  
137 -// srsService.push(getFrame());  
138 -// }  
139 -//  
140 -// }  
141 -// },0,0, TimeUnit.MILLISECONDS);  
142 -  
143 -  
144 - }  
145 -  
146 - public Boolean isOk()  
147 - {  
148 - try {  
149 - return null!=grabber && grabber.grab() != null;  
150 - } catch (FrameGrabber.Exception e) {  
151 - return false;  
152 - }  
153 - }  
154 -  
155 - public void close()  
156 - {  
157 - if(null != grabber)  
158 - {  
159 - try {  
160 - grabber.stop();  
161 - grabber.close();  
162 - } catch (Exception e) {  
163 - e.printStackTrace();  
164 - }  
165 - }  
166 -  
167 - }  
168 -  
169 - private void display(Frame frame) throws FrameGrabber.Exception {  
170 - CanvasFrame canvasFrame = new CanvasFrame("Key Frame Capture", CanvasFrame.getDefaultGamma() / grabber.getGamma());  
171 - canvasFrame.dispose();  
172 - while (true) {  
173 - canvasFrame.showImage(dream(getFrame()));  
174 - LocalDateTime now = LocalDateTime.now();  
175 - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");  
176 - String formattedDateTime = now.format(formatter);  
177 -  
178 - System.out.println("当前时间: " + formattedDateTime);  
179 - }  
180 - }  
181 -  
182 - public org.opencv.core.Mat getMat()  
183 - {  
184 - Frame frame = getFrame();  
185 - if(null == frame)  
186 - {  
187 - return null;  
188 - }  
189 - return converter2.convert(frame);  
190 - }  
191 -  
192 - public Frame getFrame() {  
193 - Frame frame = null;  
194 - try {  
195 - frame = grabber.grabImage();  
196 - if (frame == null || frame.imageHeight==0) {  
197 - //TODO:连续n次为null,进行重连  
198 - logger.info("读取不到画面,当前grabber状态:hasAudio {},hasVideo {},isCloseInputStream {},isDeinterlace {},isTriggerMode {}",grabber.hasAudio(),grabber.hasVideo(),grabber.isCloseInputStream(),grabber.isDeinterlace(),grabber.isTriggerMode());  
199 - return null;  
200 - }  
201 - else{  
202 - return frame;  
203 - }  
204 - } catch (FrameGrabber.Exception e) {  
205 - return null;  
206 - }  
207 -  
208 - }  
209 -  
210 -  
211 - private int maxX = 200;  
212 - private int POINT_RADIUS = 3;  
213 - private int quHeight = 200;  
214 - private java.util.List<Double> points = new ArrayList<>();  
215 - private BufferedImage dream(Frame frame)  
216 - {  
217 - BufferedImage image = Java2DFrameUtils.toBufferedImage(frame);  
218 -  
219 - double point = Math.random();  
220 - points.add(point);  
221 - if (points.size() > maxX) {  
222 - points.remove(0);  
223 - }  
224 -  
225 - BufferedImage curveImage = new BufferedImage(image.getWidth(), image.getHeight()+quHeight,image.getType());  
226 - Graphics2D g2d = curveImage.createGraphics();  
227 -  
228 - // 在图像上绘制曲线  
229 - g2d.setColor(Color.RED);  
230 - g2d.setStroke(new BasicStroke(POINT_RADIUS));  
231 -  
232 - Double maxY = ArrayUtil.max(points.toArray(new Double[0]));  
233 -  
234 - int vx = image.getWidth()/maxX;  
235 - Double vy = quHeight/maxY;  
236 - // 绘制动态曲线  
237 - for(int i=0;i<points.size()-1;i++)  
238 - {  
239 - int x = i*vx;  
240 - int y = new Double(points.get(i)*vy).intValue();  
241 - g2d.drawLine(x, y+image.getHeight(), x+vx, new Double(points.get(i+1)*vy).intValue()+image.getHeight());  
242 - }  
243 -  
244 - // 将第一个帧绘制到合并图像的上方  
245 - curveImage.createGraphics().drawImage(image, 0, 0, null);  
246 -  
247 - g2d.dispose();  
248 - return curveImage;  
249 - }  
250 -}  
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;  
4 -import com.zhonglai.luhui.smart.feeder.dto.ConfigurationParameter;  
5 -import com.zhonglai.luhui.smart.feeder.dto.VeiwDto; 3 +import com.zhonglai.luhui.smart.feeder.config.OpenCVConfig;
  4 +import com.zhonglai.luhui.smart.feeder.config.OperatingData;
  5 +import com.zhonglai.luhui.smart.feeder.config.ScheduledConfig;
  6 +import com.zhonglai.luhui.smart.feeder.dto.CameraConfig;
6 import com.zhonglai.luhui.smart.feeder.opencv.OpenCVUtil; 7 import com.zhonglai.luhui.smart.feeder.opencv.OpenCVUtil;
7 -import com.zhonglai.luhui.smart.feeder.service.impl.HtmllVeiwServiceImpl;  
8 -import org.opencv.core.Mat;  
9 -import org.opencv.core.MatOfPoint;  
10 -import org.opencv.core.Scalar;  
11 -import org.opencv.core.Size; 8 +import com.zhonglai.luhui.smart.feeder.service.device.CameraHandle;
  9 +import com.zhonglai.luhui.smart.feeder.service.device.handle.CameraRtspHandle;
  10 +import org.bytedeco.opencv.opencv_core.Point2f;
  11 +import org.opencv.core.*;
  12 +import org.opencv.highgui.HighGui;
  13 +import org.opencv.imgcodecs.Imgcodecs;
12 import org.opencv.imgproc.Imgproc; 14 import org.opencv.imgproc.Imgproc;
  15 +import org.opencv.video.BackgroundSubtractorMOG2;
  16 +import org.opencv.video.Video;
  17 +import org.opencv.videoio.VideoCapture;
13 import org.slf4j.Logger; 18 import org.slf4j.Logger;
14 import org.slf4j.LoggerFactory; 19 import org.slf4j.LoggerFactory;
15 -import org.springframework.beans.factory.annotation.Autowired;  
16 import org.springframework.stereotype.Service; 20 import org.springframework.stereotype.Service;
17 21
18 import java.util.ArrayList; 22 import java.util.ArrayList;
19 import java.util.Arrays; 23 import java.util.Arrays;
  24 +import java.util.Collections;
20 import java.util.List; 25 import java.util.List;
21 -import java.util.concurrent.ScheduledExecutorService;  
22 import java.util.concurrent.TimeUnit; 26 import java.util.concurrent.TimeUnit;
  27 +import java.util.function.Predicate;
  28 +
  29 +import static com.zhonglai.luhui.smart.feeder.service.InitService.*;
  30 +
  31 +
23 32
24 /** 33 /**
25 * 鱼群图像识别 34 * 鱼群图像识别
26 */ 35 */
27 -@Service  
28 public class FishGroupImageRecognitionService { 36 public class FishGroupImageRecognitionService {
29 private static final Logger logger = LoggerFactory.getLogger(FishGroupImageRecognitionService.class); 37 private static final Logger logger = LoggerFactory.getLogger(FishGroupImageRecognitionService.class);
30 38
31 - @Autowired  
32 - private FFmCameraService fFmCameraService;  
33 -  
34 - @Autowired  
35 - private ScheduledExecutorService scheduledExecutorService;  
36 -  
37 - @Autowired  
38 - private ConfigurationParameterService configurationParameterService; 39 + private static BackgroundSubtractorMOG2 backgroundSubtractor;
39 40
40 - @Autowired  
41 - private DeviceService deviceService; 41 + private static Mat frame = new Mat(); //原图
42 42
  43 + private static Mat diff = new Mat(); //移动的图片
43 44
44 - private static Boolean isRun = false; 45 + private static Mat thresh = new Mat(); //二值化图片
45 46
46 - private VeiwDto veiwDto;  
47 47
48 - private Boolean isText = false;  
49 -  
50 - private MatOfPoint largestContour; 48 + public FishGroupImageRecognitionService()
  49 + {
  50 + backgroundSubtractor = Video.createBackgroundSubtractorMOG2();
  51 + }
51 52
52 public void run() 53 public void run()
53 { 54 {
54 - scheduledExecutorService.scheduleWithFixedDelay(() -> {  
55 - if (!isRun) 55 + ScheduledConfig.scheduler.scheduleWithFixedDelay(() -> {
  56 + if (!OperatingData.cameraData.getFishGroupImageRecognIsRun())
56 { 57 {
57 start(); 58 start();
  59 + OperatingData.cameraData.setFishGroupImageRecognIsRun(false);
58 } 60 }
59 },1,1,TimeUnit.SECONDS); 61 },1,1,TimeUnit.SECONDS);
60 62
61 } 63 }
62 // 创建FrameConverter对象 64 // 创建FrameConverter对象
63 - public void start()  
64 - {  
65 - if(fFmCameraService.getVideoIsOpen()) //摄像头打开才能识别  
66 - {  
67 - isRun = true;  
68 - configurationParameterService.setConfig(ConfigurationParameter.FishGroupImageRecognition,true);  
69 - brightnessIdentifyFishRegion();  
70 - }  
71 - }  
72 -  
73 - public void stop() 65 + private void start()
74 { 66 {
75 - configurationParameterService.setConfig(ConfigurationParameter.FishGroupImageRecognition,false);  
76 - fFmCameraService.close();  
77 - isRun = false;  
78 - } 67 + CameraHandle cameraHandle = InitService.cameraHandle;
79 68
80 - /**  
81 - * 获取标准水域轮廓  
82 - * @param previousFrame  
83 - * @return  
84 - */  
85 - private MatOfPoint getDefaultMatOfPoint(Mat previousFrame)  
86 - {  
87 - Mat firstBinaryImage = waterBybinary(previousFrame,(Integer) configurationParameterService.getConfig(ConfigurationParameter.reflectionThreshold));  
88 - // 绘制白色区域的轮廓  
89 - List<MatOfPoint> contours = new ArrayList<>();  
90 - Mat hierarchy = new Mat();  
91 - Imgproc.findContours(firstBinaryImage, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);  
92 - // 找到最大区域  
93 - double maxArea = 0;  
94 - int maxAreaIndex = -1;  
95 - for (int i = 0; i < contours.size(); i++) {  
96 - MatOfPoint matOfPoint = contours.get(i);  
97 - double area = Imgproc.contourArea(matOfPoint);  
98 - if (area > maxArea) {  
99 - maxArea = area;  
100 - maxAreaIndex = i;  
101 - }  
102 - }  
103 - // 获取最大区域的轮廓  
104 - MatOfPoint largestContour = contours.get(maxAreaIndex);  
105 - contours.remove(maxAreaIndex);  
106 - for(MatOfPoint matOfPoint:contours) 69 + if(!cameraHandle.isOpen())
107 { 70 {
108 - matOfPoint.release(); 71 + cameraHandle.init();
109 } 72 }
110 - firstBinaryImage.release();  
111 - hierarchy.release();  
112 -  
113 - return largestContour; 73 + OperatingData.cameraData.setFishGroupImageRecognIsRun(true);
  74 + brightnessIdentifyFishRegion();
114 } 75 }
115 76
  77 +
116 /** 78 /**
117 * 亮度查找水面,透明度过滤鱼群 79 * 亮度查找水面,透明度过滤鱼群
118 */ 80 */
119 private void brightnessIdentifyFishRegion() 81 private void brightnessIdentifyFishRegion()
120 { 82 {
121 logger.info("启动鱼群识别"); 83 logger.info("启动鱼群识别");
122 - // 读取第一帧并获取视频大小  
123 - org.opencv.core.Mat previousFrame = fFmCameraService.getMat();  
124 84
125 - if (null == previousFrame) {  
126 - System.out.println("无法读取视频帧");  
127 - return;  
128 - }  
129 -  
130 - logger.info("鱼群识别时检测摄像头");  
131 - // 获取水域轮廓  
132 - if(null != largestContour) 85 + Long time =1000l;
  86 + if(null != OperatingData.cameraConfig.getIdentificationFrequency())
133 { 87 {
134 - largestContour.release(); 88 + time = OperatingData.cameraConfig.getIdentificationFrequency();
135 } 89 }
136 - largestContour = getDefaultMatOfPoint(previousFrame);  
137 -  
138 - Long time =66l;  
139 - if(null != configurationParameterService.getConfig(ConfigurationParameter.IdentificationFrequency)) 90 + while (cameraHandle.isOpen())
140 { 91 {
141 - time = (Long) configurationParameterService.getConfig(ConfigurationParameter.IdentificationFrequency);  
142 - }  
143 - // 逐帧处理视频  
144 - scheduledExecutorService.scheduleWithFixedDelay(() -> {  
145 try { 92 try {
146 - Boolean fishGroupImageRecognition = ((Boolean)configurationParameterService.getConfig(ConfigurationParameter.FishGroupImageRecognition));  
147 - Mat frame = fFmCameraService.getMat(); 93 + Boolean fishGroupImageRecognition = OperatingData.cameraConfig.getFishGroupImageRecognition();
  94 + frame = CameraRtspHandle.mat.clone();
  95 +
148 Boolean isread = false; 96 Boolean isread = false;
149 if(null != frame) 97 if(null != frame)
150 { 98 {
@@ -158,140 +106,133 @@ public class FishGroupImageRecognitionService { @@ -158,140 +106,133 @@ public class FishGroupImageRecognitionService {
158 return; 106 return;
159 } 107 }
160 if (fishGroupImageRecognition && isread) { 108 if (fishGroupImageRecognition && isread) {
161 - identify(frame); 109 + yidong(frame);
162 } 110 }
163 - frame.release();  
164 }catch (Exception e) 111 }catch (Exception e)
165 { 112 {
166 logger.error("识别错误",e); 113 logger.error("识别错误",e);
  114 + }finally {
  115 + if(null != frame)
  116 + {
  117 + frame.release();
  118 + }
  119 + try {
  120 + Thread.sleep(time);
  121 + } catch (InterruptedException e) {
  122 + throw new RuntimeException(e);
  123 + }
167 } 124 }
168 -  
169 - },0,time, TimeUnit.MILLISECONDS);  
170 -  
171 - previousFrame.release();  
172 -  
173 - }  
174 -  
175 - public void setText(Boolean text) {  
176 - isText = text; 125 + }
177 } 126 }
178 127
179 /** 128 /**
180 - * 识别 129 + * 检测移动
  130 + * @return
181 */ 131 */
182 - private void identify(Mat frame) 132 + private void yidong(Mat image)
183 { 133 {
184 - //抠图  
185 - Mat shuiyu = OpenCVUtil.matting(frame,largestContour);  
186 -  
187 - // 2. 转换为灰度图像  
188 - Mat gray = new Mat();  
189 - Imgproc.cvtColor(shuiyu, gray, Imgproc.COLOR_BGR2GRAY);  
190 -  
191 - // 3. 进行阈值分割以得到二值图像  
192 - Mat binaryImage = new Mat();  
193 - Imgproc.threshold(gray, binaryImage, 100, 255, Imgproc.THRESH_BINARY);  
194 -  
195 - List<MatOfPoint> contours = new ArrayList<>(); // 用于存储找到的轮廓  
196 - Mat hierarchy = new Mat(); // 轮廓的层次结构  
197 -  
198 - // 在水域二值图像中找所有轮廓  
199 - Imgproc.findContours(binaryImage, contours, hierarchy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);  
200 -  
201 - if(null != isText && isText) 134 + if(!image.empty())
202 { 135 {
203 - //标注识别对象  
204 - Imgproc.drawContours(frame, contours, -1, new Scalar(0, 0, 255), 2);  
205 - Imgproc.drawContours(frame, Arrays.asList(new MatOfPoint[]{largestContour}), 0, new Scalar(0, 255, 0), 2);  
206 - } 136 + backgroundSubtractor.apply(image, diff); // 应用背景减法获取运动部件
207 137
208 - //计算大小  
209 - double area = getArea(contours); 138 + // 执行阈值和形态学操作
  139 + Imgproc.threshold(diff, thresh, OperatingData.cameraConfig.getTrendsPixelMin(), OperatingData.cameraConfig.getTrendsPixelMax(), Imgproc.THRESH_BINARY);
  140 + Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(OperatingData.cameraConfig.getKernelSize(), OperatingData.cameraConfig.getKernelSize()));
  141 + Imgproc.dilate(thresh, thresh, kernel, new Point(-1, -1), 2);
210 142
211 - //计算斜率  
212 - double absValue = deviceService.controlDevice(area);  
213 - configurationParameterService.setConfig(ConfigurationParameter.absValue,absValue); 143 + //找到动作的轮廓
  144 + List<MatOfPoint> contours = new ArrayList<>();
  145 + Mat hierarchy = new Mat();
  146 + Imgproc.findContours(thresh, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
214 147
215 - veiwDto = new VeiwDto(new Double(area).intValue(),absValue); 148 + double[] dsTotal = new double[5];
216 149
217 - // 显示图像  
218 - logger.info("是否显示{},客户端数量{}",configurationParameterService.getConfig(ConfigurationParameter.ifVeiw),WebSocketClien.webSocketSet.size());  
219 - // 在图像上显示结果  
220 - logger.info("socket数量{}",WebSocketClien.webSocketSet.size());  
221 - if((Boolean)configurationParameterService.getConfig(ConfigurationParameter.ifVeiw) && WebSocketClien.webSocketSet.size()>0)  
222 - {  
223 - new HtmllVeiwServiceImpl(configurationParameterService).veiw(veiwDto);  
224 - }  
225 -  
226 - shuiyu.release();  
227 - gray.release();  
228 - hierarchy.release();  
229 - binaryImage.release();  
230 - } 150 + contours.removeIf(matOfPoint -> {
  151 + Rect rect = Imgproc.boundingRect(matOfPoint);
  152 + matOfPoint.release();
  153 + if(rect.width!=image.width() && rect.width>OperatingData.cameraConfig.getCalloutBoxWidthMin())
  154 + {
  155 + double[] ds = count(image,rect);
  156 + if(filterate(ds))
  157 + {
  158 + dsTotal[0]+=ds[0];
  159 + dsTotal[1]+=ds[1];
  160 + dsTotal[2]+=ds[2];
  161 + dsTotal[3]+=ds[3];
  162 + dsTotal[4]++;
  163 + Imgproc.rectangle(image, rect.tl(), rect.br(), new Scalar(0, 255, 0), 2);
  164 + return false;
  165 + }
  166 + }
  167 + return true;
  168 + });
231 169
232 - /**  
233 - * 计算鱼群面积  
234 - * @param contours  
235 - * @return  
236 - */  
237 - private double getArea(List<MatOfPoint> contours) {  
238 - // 找到最大区域  
239 - double maxArea = 0;  
240 - int maxAreaIndex = -1;  
241 - double allArea = 0;  
242 - for (int i = 0; i < contours.size(); i++) {  
243 - MatOfPoint matOfPoint = contours.get(i);  
244 - double area = Imgproc.contourArea(matOfPoint);  
245 - if (area > maxArea) {  
246 - maxArea = area;  
247 - maxAreaIndex = i; 170 + if(0!=dsTotal[4])
  171 + {
  172 + double brightness = dsTotal[0]/dsTotal[4];
  173 + double reflection= dsTotal[1]/dsTotal[4];
  174 + double transparencyMeasure= dsTotal[2]/dsTotal[4];
  175 + double area= dsTotal[3]/dsTotal[4];
  176 +
  177 + //计算斜率
  178 + double slope = area - (null==OperatingData.cameraData.getArea()?area:OperatingData.cameraData.getArea());
  179 + //当前斜率的差值
  180 + double slopeDifference = slope-(null==OperatingData.cameraData.getSlope()?slope:OperatingData.cameraData.getSlope());
  181 + //计算斜率差值的绝对值
  182 + double absValue = Math.abs(slopeDifference);
  183 +
  184 + OperatingData.cameraData.setBrightness(brightness);
  185 + OperatingData.cameraData.setReflection(reflection);
  186 + OperatingData.cameraData.setTransparencyMeasure(transparencyMeasure);
  187 + OperatingData.cameraData.setArea(area);
  188 + OperatingData.cameraData.setSlope(slope);
  189 + OperatingData.cameraData.setSlopeDifference(slopeDifference);
  190 + OperatingData.cameraData.setAbsValue(absValue);
248 } 191 }
249 - allArea += area;  
250 -  
251 - matOfPoint.release();  
252 - }  
253 -  
254 - //删除最大  
255 - if(-1 != maxAreaIndex)  
256 - {  
257 - contours.remove(maxAreaIndex);  
258 } 192 }
259 -  
260 - // 返回总面积  
261 - return allArea;  
262 } 193 }
263 194
264 - 195 + private static Mat hsvImage = new Mat();
  196 + private static Mat grayImage = new Mat();
  197 + private static Scalar meanGray = Core.mean(grayImage);
265 /** 198 /**
266 - * 根据反光查找水面  
267 - * @param frame  
268 - * @return 199 + * 运算
  200 + * @param image
  201 + * @param rect
269 */ 202 */
270 - public Mat waterBybinary(Mat frame,int reflectionThreshold) {  
271 - // 将加载的图像转换为灰度图像,以便进行亮度或反光的分析  
272 - Mat grayImage = new Mat();  
273 - Imgproc.cvtColor(frame, grayImage, Imgproc.COLOR_BGR2GRAY);  
274 -  
275 - // 检测反光  
276 - Mat binaryImage = new Mat();  
277 -  
278 - Imgproc.threshold(grayImage, binaryImage, reflectionThreshold, (Integer) configurationParameterService.getConfig(ConfigurationParameter.maxValue), Imgproc.THRESH_BINARY);  
279 -  
280 - // 进行形态学操作,去除噪点  
281 - Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size((Integer) configurationParameterService.getConfig(ConfigurationParameter.kernelSize),(Integer) configurationParameterService.getConfig(ConfigurationParameter.kernelSize)));  
282 - Imgproc.morphologyEx(binaryImage, binaryImage, Imgproc.MORPH_OPEN, kernel);  
283 -  
284 - grayImage.release();  
285 - kernel.release();  
286 -  
287 - return binaryImage;  
288 - }  
289 -  
290 - public VeiwDto getVeiwDto() {  
291 - return veiwDto; 203 + private double[] count(Mat image,Rect rect)
  204 + {
  205 + // 计算轮廓区域内的反光、亮度和透明度值
  206 + Mat roi = new Mat(image, rect);
  207 + // 计算亮度
  208 + Imgproc.cvtColor(roi, hsvImage, Imgproc.COLOR_BGR2HSV);
  209 + Scalar mean = Core.mean(hsvImage);
  210 + double brightness = mean.val[2];
  211 +
  212 + // 计算反光
  213 + Imgproc.cvtColor(roi, grayImage, Imgproc.COLOR_BGR2GRAY);
  214 + Core.MinMaxLocResult minMaxLocResult = Core.minMaxLoc(grayImage);
  215 + double reflection = minMaxLocResult.maxVal;
  216 +
  217 + // 计算灰度均值
  218 + double meanGrayValue = meanGray.val[0];
  219 + // 将灰度均值映射到0到255范围内作为透明度度量(较低的灰度值表示较高的透明度,反之亦然)
  220 + double transparencyMeasure = 255 - meanGrayValue;
  221 +
  222 + //计算面积
  223 + Size roiSize = roi.size();
  224 + double area = roiSize.width * roiSize.height;
  225 +
  226 + roi.release();
  227 +
  228 + return new double[]{brightness,reflection,transparencyMeasure,area};
292 } 229 }
293 230
294 - public void setVeiwDto(VeiwDto veiwDto) {  
295 - this.veiwDto = veiwDto; 231 + private boolean filterate(double[] ds)
  232 + {
  233 + return OperatingData.cameraConfig.getReflectionMax()>ds[1] && ds[1]>OperatingData.cameraConfig.getReflectionMin()
  234 + && OperatingData.cameraConfig.getBrightnessMax()>ds[0] && ds[0]>OperatingData.cameraConfig.getBrightnessMin()
  235 + && ds[2]>OperatingData.cameraConfig.getTransparencyMeasureMin() && ds[2]<OperatingData.cameraConfig.getTransparencyMeasureMax()
  236 + && ds[3]>OperatingData.cameraConfig.getAreaMin() && ds[3]<OperatingData.cameraConfig.getAreaMax();
296 } 237 }
297 } 238 }
1 package com.zhonglai.luhui.smart.feeder.service; 1 package com.zhonglai.luhui.smart.feeder.service;
2 2
3 -import org.eclipse.paho.client.mqttv3.MqttException;  
4 -import org.springframework.beans.factory.annotation.Autowired;  
5 -import org.springframework.context.annotation.Configuration;  
6 3
7 -import javax.annotation.PostConstruct;  
8 -import java.util.concurrent.ScheduledExecutorService; 4 +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;
  7 +import com.zhonglai.luhui.smart.feeder.service.netty.NettyClient;
9 8
10 -@Configuration  
11 public class InitService { 9 public class InitService {
12 - @Autowired  
13 - private FFmCameraService fFmCameraService; 10 + public static SerialPortService serialPortService;
14 11
15 - @Autowired  
16 - private ConfigurationParameterService configurationParameterService; 12 + public static CameraHandle cameraHandle;
17 13
18 - @Autowired  
19 - private DateListenService dateListenService;  
20 -  
21 - @Autowired  
22 - private DeviceService deviceService;  
23 -  
24 - @Autowired  
25 - private FishGroupImageRecognitionService fishGroupImageRecognitionService;  
26 -  
27 - @Autowired  
28 - private SqliteService sqliteService;  
29 -  
30 - @Autowired  
31 - private TerminalService terminalService; 14 + public static NettyClient nettyClient;
32 15
  16 + public static DeviceService deviceService;
33 /** 17 /**
34 - * 守护摄像头 18 + * 加载配置
35 */ 19 */
36 - @PostConstruct  
37 - private void run() throws MqttException {  
38 - //持久化初始  
39 - sqliteService.init(); 20 + public static void initConfig() {
40 //配置参数 21 //配置参数
41 - configurationParameterService.initConfigurationParameter();  
42 - //摄像头监听  
43 - fFmCameraService.start();  
44 - //鱼群识别  
45 - fishGroupImageRecognitionService.run(); 22 + ConfigurationParameterService.initConfigurationParameter();
  23 + }
  24 +
  25 + public static void startService()
  26 + {
  27 + /**
  28 + * 串口服务器启动
  29 + */
  30 + serialPortService = new SerialPortService();
  31 +
  32 + /**
  33 + * mq远程登录
  34 + */
  35 + nettyClient = new NettyClient();
  36 + nettyClient.start();
  37 +
  38 + /**
  39 + * 初始化海康的摄像头
  40 + */
  41 + cameraHandle = new CameraRtspHandle();
  42 +
  43 + /**
  44 + * 图像识别
  45 + */
  46 + new FishGroupImageRecognitionService().run();
  47 +
46 //鱼群图像识别控制投料控制 48 //鱼群图像识别控制投料控制
  49 + deviceService = new DeviceService(serialPortService);
47 deviceService.run(); 50 deviceService.run();
48 - //连接上报终端  
49 - terminalService.startMqttListenerService();  
50 - //串口数据上报  
51 - dateListenService.run(); 51 +
  52 + //数据上报
  53 + new DateListenService(serialPortService).run();
52 } 54 }
53 55
54 } 56 }
1 -package com.zhonglai.luhui.smart.feeder.service;  
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.ConfigDto;  
7 -import com.zhonglai.luhui.smart.feeder.dto.VeiwDto;  
8 -import com.zhonglai.luhui.smart.feeder.dto.commd.FeederCommd06Response;  
9 -import com.zhonglai.luhui.smart.feeder.dto.commd.FeederCommdDto;  
10 -import com.zhonglai.luhui.smart.feeder.dto.commd.FeederTimer;  
11 -import com.zhonglai.luhui.smart.feeder.service.device.SerialPortService;  
12 -import com.zhonglai.luhui.smart.feeder.util.FeederCommdUtil;  
13 -import org.eclipse.paho.client.mqttv3.*;  
14 -import org.slf4j.Logger;  
15 -import org.slf4j.LoggerFactory;  
16 -import org.springframework.beans.factory.annotation.Autowired;  
17 -import org.springframework.beans.factory.annotation.Value;  
18 -import org.springframework.stereotype.Component;  
19 -  
20 -import java.util.HashMap;  
21 -import java.util.List;  
22 -import java.util.Map;  
23 -  
24 -@Component  
25 -public class MqttCallback implements MqttCallbackExtended {  
26 -  
27 - private static final Logger log = LoggerFactory.getLogger(MqttCallback.class);  
28 - @Autowired  
29 - private ConfigurationParameterService configurationParameterService;  
30 -  
31 - @Autowired  
32 - private SerialPortService serialPortService;  
33 -  
34 - @Autowired  
35 - private SrsService srsService;  
36 -  
37 - @Autowired  
38 - private FishGroupImageRecognitionService fishGroupImageRecognitionService;  
39 -  
40 - private MqttClient mqttclient;  
41 -  
42 -  
43 - @Value("#{'${mqtt.topics}'.split(',')}")  
44 - private List<String> topics;  
45 -  
46 - @Override  
47 - public void connectComplete(boolean b, String s) {  
48 - log.info("连接成功");  
49 - try {  
50 - subscribe();  
51 - } catch (MqttException e) {  
52 - throw new RuntimeException(e);  
53 - }  
54 - }  
55 -  
56 - @Override  
57 - public void connectionLost(Throwable cause) {  
58 - log.error("连接丢失",cause);  
59 - }  
60 -  
61 - public MqttCallback setMqttClient(MqttClient mqttclient)  
62 - {  
63 - this.mqttclient = mqttclient;  
64 - return this;  
65 - }  
66 -  
67 - @Override  
68 - public void messageArrived(String topic, MqttMessage message) throws Exception {  
69 - log.info("收到消息 {}",message);  
70 - if(topic.indexOf("PUT")>=0)  
71 - {  
72 - Map<String, Register> map = configurationParameterService.getControlMap();  
73 - byte[] bs = message.getPayload();  
74 - if(null != bs && bs.length!=0)  
75 - {  
76 - String str = new String(bs);  
77 - JsonObject jsonObject = GsonConstructor.get().fromJson(str, JsonObject.class);  
78 - if(jsonObject.has("10_1")) //投料机控制  
79 - {  
80 - JsonObject controlData = jsonObject.get("10_1").getAsJsonObject();  
81 -  
82 - Map<Integer, FeederTimer> timerMap = new HashMap<>();  
83 - for (String key:controlData.keySet())  
84 - {  
85 - if(key.startsWith("timer"))  
86 - {  
87 - Integer timerNumber = Integer.parseInt(key.split("_")[0].replace("timer",""));  
88 - FeederTimer feederTimer = timerMap.get(timerNumber);  
89 - if(null == feederTimer)  
90 - {  
91 - feederTimer = new FeederTimer();  
92 - timerMap.put(timerNumber,feederTimer);  
93 - }  
94 -  
95 - feederTimer.setObjectValue(key.replace(""+timerNumber+"",""),Long.valueOf(controlData.get(key).getAsString()));  
96 - }else {  
97 - Register register = map.get(key);  
98 - serialPortService.sendHexData(new FeederCommdDto(new FeederCommd06Response(register.getAddress(),controlData.get(key).getAsInt())).getHstr());  
99 - }  
100 - }  
101 -  
102 - if(null != timerMap && timerMap.size() != 0)  
103 - {  
104 - for (Integer timerNumber:timerMap.keySet())  
105 - {  
106 - serialPortService.sendHexData(FeederCommdUtil.controlTimer(timerNumber,timerMap.get(timerNumber)));  
107 - }  
108 - }  
109 - }  
110 - else if(jsonObject.has("0")) //主机  
111 - {  
112 - ConfigDto configDto = GsonConstructor.get().fromJson(jsonObject.get("0").toString(),ConfigDto.class);  
113 - configurationParameterService.setConfig(configDto.getConfigurationParameter(),configDto.getValue());  
114 - }  
115 - else if(jsonObject.has("1_1")) //探头  
116 - {  
117 - VeiwDto veiwDto = GsonConstructor.get().fromJson(jsonObject.get("1_1").toString(),VeiwDto.class);  
118 - if(null != veiwDto.getPush_camera())  
119 - {  
120 - switch (veiwDto.getPush_camera())  
121 - {  
122 - case 0:  
123 - srsService.stop();  
124 - break;  
125 - case 1:  
126 - srsService.run(300);  
127 - fishGroupImageRecognitionService.setText(veiwDto.getText());  
128 - srsService.setDisplaySrc(veiwDto.getDisplaySrc());  
129 - break;  
130 - }  
131 - }  
132 - }  
133 - }  
134 - }  
135 - }  
136 -  
137 -  
138 - @Override  
139 - public void deliveryComplete(IMqttDeliveryToken token) {  
140 - // 成功发出消息  
141 - log.info("成功发出消息 messageid{}",token);  
142 - }  
143 -  
144 - private void subscribe() throws MqttException {  
145 - mqttclient.subscribe(topics.toArray(new String[topics.size()]));  
146 - }  
147 -}  
  1 +package com.zhonglai.luhui.smart.feeder.service;
  2 +
  3 +import org.bytedeco.javacv.Frame;
  4 +
  5 +public interface PushVideo {
  6 + void display(Frame filteredFrame);
  7 +}
1 -package com.zhonglai.luhui.smart.feeder.service;  
2 -  
3 -import com.alibaba.fastjson.JSONObject;  
4 -import com.ruoyi.common.utils.GsonConstructor;  
5 -import com.zhonglai.luhui.dao.service.PublicService;  
6 -import com.zhonglai.luhui.smart.feeder.domain.Register;  
7 -import com.zhonglai.luhui.smart.feeder.dto.ConfigurationParameter;  
8 -import com.zhonglai.luhui.smart.feeder.dto.FishCurveControlCondition;  
9 -import com.zhonglai.luhui.smart.feeder.dto.SerialPortConfig;  
10 -import com.zhonglai.luhui.smart.feeder.mapper.AbsValueCommandMapper;  
11 -import org.slf4j.Logger;  
12 -import org.slf4j.LoggerFactory;  
13 -import org.springframework.beans.factory.annotation.Autowired;  
14 -import org.springframework.beans.factory.annotation.Value;  
15 -import org.springframework.stereotype.Service;  
16 -  
17 -import javax.annotation.PostConstruct;  
18 -import java.io.File;  
19 -import java.io.IOException;  
20 -import java.util.HashMap;  
21 -import java.util.List;  
22 -import java.util.Map;  
23 -  
24 -@Service  
25 -public class SqliteService {  
26 -  
27 - private static Logger logger = LoggerFactory.getLogger(SqliteService.class);  
28 -  
29 - @Autowired  
30 - private PublicService publicService;  
31 -  
32 - @Autowired  
33 - private AbsValueCommandMapper absValueCommandMapper;  
34 -  
35 - @Value("${spring.datasource.druid.master.url}")  
36 - private String masterUrl;  
37 -  
38 - public void init()  
39 - {  
40 - initDb();  
41 - initSysConfig();  
42 - initAbsValueCommand();  
43 - }  
44 -  
45 - /**  
46 - * 数据库  
47 - */  
48 - private void initDb()  
49 - {  
50 - logger.info("检查数据库文件");  
51 - File dbFile = new File(masterUrl.replace("jdbc:sqlite:",""));  
52 - if (!dbFile.exists()) {  
53 - logger.info("数据库文件不存在自动创建");  
54 - try {  
55 - // 创建新的数据库文件  
56 - boolean created = dbFile.createNewFile();  
57 - if (created) {  
58 - System.out.println("成功创建数据库文件my.db");  
59 - // 进行其他初始化操作,如创建表格等  
60 - } else {  
61 - System.out.println("创建数据库文件my.db失败");  
62 - }  
63 - } catch (IOException e) {  
64 - e.printStackTrace();  
65 - }  
66 - }  
67 -  
68 -  
69 - }  
70 -  
71 - /**  
72 - * 配置表  
73 - */  
74 - private void initSysConfig()  
75 - {  
76 - logger.info("检查配置表");  
77 - Long ct = publicService.selectCountBySql("SELECT count(*) ct FROM sqlite_master WHERE type='table' AND `name`='sys_config'");  
78 - if (0==ct)  
79 - {  
80 - logger.info("配置表不存在自动创建");  
81 - publicService.updateBySql("CREATE TABLE \"sys_config\" (\n" +  
82 - " \"parameter_name\" TEXT NOT NULL,\n" +  
83 - " \"parameter_value\" TEXT NOT NULL,\n" +  
84 - " \"describe\" TEXT,\n" +  
85 - " PRIMARY KEY (\"parameter_name\"),\n" +  
86 - " CONSTRAINT \"名称唯一\" UNIQUE (\"parameter_name\" ASC)\n" +  
87 - ")");  
88 -  
89 - logger.info("初始化置表数据");  
90 - publicService.updateBySql("INSERT INTO \"sys_config\" VALUES ('ifVeiw', 'false', '是否显示');\n" +  
91 - "INSERT INTO \"sys_config\" VALUES ('captureNumber', '0', '摄像头编号');\n" +  
92 - "INSERT INTO \"sys_config\" VALUES ('reflectionThreshold', '100', '反光阈值');\n" +  
93 - "INSERT INTO \"sys_config\" VALUES ('kernelSize', '3', '去噪调整内核大小,用来消除小的物体或噪声');\n" +  
94 - "INSERT INTO \"sys_config\" VALUES ('maxValue', '255.0', '最大反光阈值');\n" +  
95 - "INSERT INTO \"sys_config\" VALUES ('VeiwDto_isFrame', 'false', '是否显示原图');\n" +  
96 - "INSERT INTO \"sys_config\" VALUES ('VeiwDto_isBinaryImage', 'false', '是否显示临时图');\n" +  
97 - "INSERT INTO \"sys_config\" VALUES ('VeiwDto_isSize', 'false', '是否显示面积');\n" +  
98 - "INSERT INTO \"sys_config\" VALUES ('VeiwDto_isAbsValue', 'false', '是否显示斜率');\n" +  
99 - "INSERT INTO \"sys_config\" VALUES ('absValue', '0', '是否显示斜率');\n" +  
100 - "INSERT INTO \"sys_config\" VALUES ('FishGroupImageRecognition', 'true', '鱼群图像识别是否开启');\n" +  
101 - "INSERT INTO \"sys_config\" VALUES ('FeedingControl', 'true', '鱼群图像识别投料控制是否开启');\n" +  
102 - "INSERT INTO \"sys_config\" VALUES ('SerialPortConfig', '{\"portName\": \"COM6\",\"baudrate\": 9600,\"dataBits\": 8,\"stopBits\": 0,\"parity\": 0}', '串口配置');\n" +  
103 - "\n" );  
104 - }  
105 - }  
106 -  
107 -  
108 - private void initAbsValueCommand() {  
109 - logger.info("检查斜率范围对应的档位表");  
110 - Long ct = publicService.selectCountBySql("SELECT count(*) ct FROM sqlite_master WHERE type='table' AND name='absValue_command'");  
111 - if (0 == ct)  
112 - {  
113 - logger.info("斜率范围对应的档位不存在自动创建");  
114 - publicService.updateBySql("CREATE TABLE \"absValue_command\" (\n" +  
115 - " \"sartAbsValue\" integer,\n" +  
116 - " \"gear\" integer NOT NULL,\n" +  
117 - " PRIMARY KEY (\"gear\"),\n" +  
118 - " CONSTRAINT \"档位唯一\" UNIQUE (\"gear\" ASC)\n" +  
119 - ")");  
120 - }  
121 - }  
122 -  
123 - public List<Map<String,Object>> getAllSysConfig()  
124 - {  
125 - return publicService.getObjectListBySQL("SELECT * FROM sys_config");  
126 - }  
127 -  
128 - public List<FishCurveControlCondition> getAllAbsValueCommand()  
129 - {  
130 - return absValueCommandMapper.getFishCurveControlConditionList("SELECT * FROM absValue_command");  
131 - }  
132 -  
133 - public List<Map<String,Object>> getAllRegister()  
134 - {  
135 - return publicService.getObjectListBySQL("SELECT * FROM register");  
136 - }  
137 -  
138 - public void updateConfigurationParameter(ConfigurationParameter key,Object value)  
139 - {  
140 - switch (key)  
141 - {  
142 - case absValue_command:  
143 - List<FishCurveControlCondition> list = (List<FishCurveControlCondition>) value;  
144 - for(FishCurveControlCondition fishCurveControlCondition:list)  
145 - {  
146 - updateabsValueCommand(fishCurveControlCondition.getGear(),fishCurveControlCondition.getSartAbsValue());  
147 - }  
148 - break;  
149 - default:  
150 - updateSysConfig(key, key.valueToString(value));  
151 - break;  
152 - }  
153 - }  
154 -  
155 - public void updateSysConfig(ConfigurationParameter key,String value)  
156 - {  
157 - publicService.updateBySql("delete from sys_config where parameter_name='"+key.name()+"'");  
158 - publicService.updateBySql("insert into sys_config(`parameter_name`,`parameter_value`,`describe`) values ('"+key.name()+"','"+value+"','"+key.getDescribe()+"')");  
159 - }  
160 -  
161 - public void updateabsValueCommand(Integer gear,Integer sartAbsValue)  
162 - {  
163 - publicService.updateBySql("delete from absValue_command where sartAbsValue="+sartAbsValue+"");  
164 - publicService.updateBySql("insert into absValue_command(`gear`,`sartAbsValue`) values ("+gear+",'"+sartAbsValue+"')");  
165 - }  
166 -  
167 - public void deleteabsValueCommandAll()  
168 - {  
169 - publicService.updateBySql("delete from absValue_command ");  
170 - }  
171 -  
172 -  
173 -}  
1 -package com.zhonglai.luhui.smart.feeder.service;  
2 -  
3 -import com.alibaba.fastjson.JSONObject;  
4 -import com.ruoyi.common.utils.ip.IpUtils;  
5 -import org.eclipse.paho.client.mqttv3.MqttClient;  
6 -import org.eclipse.paho.client.mqttv3.MqttConnectOptions;  
7 -import org.eclipse.paho.client.mqttv3.MqttException;  
8 -import org.eclipse.paho.client.mqttv3.MqttMessage;  
9 -import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;  
10 -import org.slf4j.Logger;  
11 -import org.slf4j.LoggerFactory;  
12 -import org.springframework.beans.factory.annotation.Autowired;  
13 -import org.springframework.beans.factory.annotation.Value;  
14 -import org.springframework.stereotype.Service;  
15 -  
16 -import javax.annotation.PostConstruct;  
17 -import java.util.ArrayList;  
18 -import java.util.HashMap;  
19 -import java.util.List;  
20 -import java.util.Map;  
21 -  
22 -/**  
23 - * 终端服务  
24 - */  
25 -@Service  
26 -public class TerminalService {  
27 - private static final Logger log = LoggerFactory.getLogger(TerminalService.class);  
28 -  
29 - private MqttClient mqttclient;  
30 - private MqttConnectOptions options;  
31 -  
32 - @Autowired  
33 - private MqttCallback mqttCallback;  
34 -  
35 - @Value("${mqtt.broker}")  
36 - private String broker;  
37 - @Value("${mqtt.clientId}")  
38 - private String clientId;  
39 -  
40 - @Value("${mqtt.username}")  
41 - private String username;  
42 - @Value("${mqtt.password}")  
43 - private String password;  
44 -  
45 - public void startMqttListenerService() throws MqttException{  
46 - log.info("-----------开始启动mqtt监听服务--------------------");  
47 - init();  
48 - connect();  
49 -  
50 - Map<String,Object> dmap = new HashMap<>();  
51 - Map<String,Object> map = new HashMap<>();  
52 - dmap.put("summary",map);  
53 - map.put("localhostIp",IpUtils.getLocalHost());  
54 - JSONObject jsonObject = new JSONObject();  
55 - jsonObject.put("0",dmap);  
56 - String topic = "ADD_POST";  
57 - publish(topic,jsonObject.toJSONString());  
58 - }  
59 -  
60 -  
61 - public void init() throws MqttException {  
62 - if(null == mqttclient)  
63 - {  
64 - mqttclient = new MqttClient(broker, clientId, new MemoryPersistence());  
65 - }  
66 - options = new MqttConnectOptions();  
67 - options.setCleanSession(true);  
68 - options.setConnectionTimeout(15);  
69 - //设置断开后重新连接  
70 - options.setAutomaticReconnect(true);  
71 - mqttclient.setCallback(mqttCallback.setMqttClient(mqttclient));  
72 - }  
73 -  
74 - private void connect() throws MqttException {  
75 - options.setUserName(username);  
76 - options.setPassword(password.toCharArray());  
77 - mqttclient.connect(options);  
78 - }  
79 -  
80 - public void publish(String topic, MqttMessage message) throws MqttException {  
81 - mqttclient.publish(topic,message);  
82 - }  
83 -  
84 - public void publish(String topic, String messageStr) throws MqttException {  
85 - MqttMessage message = new MqttMessage();  
86 - message.setPayload(messageStr.getBytes());  
87 - mqttclient.publish(topic,message);  
88 - }  
89 -  
90 - public void scheduledSubmissionData(String messageStr) throws MqttException {  
91 - String topic = "ALL_POST";  
92 - publish(topic,messageStr);  
93 - }  
94 -  
95 - public void close()  
96 - {  
97 - try {  
98 - options.setAutomaticReconnect(false);  
99 - if(null != mqttclient && mqttclient.isConnected())  
100 - {  
101 - mqttclient.disconnect();  
102 - mqttclient.close();  
103 - }  
104 -  
105 - } catch (MqttException e) {  
106 - log.error("关闭失败",e);  
107 - }  
108 - }  
109 -  
110 -}  
1 -package com.zhonglai.luhui.smart.feeder.service;  
2 -  
3 -import com.alibaba.fastjson.JSONObject;  
4 -import com.ruoyi.common.core.domain.AjaxResult;  
5 -import com.ruoyi.common.utils.GsonConstructor;  
6 -import com.ruoyi.common.utils.StringUtils;  
7 -import com.zhonglai.luhui.smart.feeder.config.WebSocketClien;  
8 -import com.zhonglai.luhui.smart.feeder.dto.WebSocketVO;  
9 -import org.slf4j.Logger;  
10 -import org.slf4j.LoggerFactory;  
11 -import org.springframework.beans.factory.annotation.Autowired;  
12 -import org.springframework.stereotype.Component;  
13 -  
14 -import javax.websocket.*;  
15 -import javax.websocket.server.PathParam;  
16 -import javax.websocket.server.ServerEndpoint;  
17 -import java.io.IOException;  
18 -import java.util.concurrent.ConcurrentHashMap;  
19 -import java.util.concurrent.CopyOnWriteArraySet;  
20 -  
21 -/**  
22 - * 会话连接  
23 - */  
24 -@ServerEndpoint("/websocket/{userId}")  
25 -@Component  
26 -public class WebSocketSever {  
27 - private static final Logger log = LoggerFactory.getLogger(WebSocketSever.class);  
28 -  
29 - @Autowired  
30 - private DeviceService deviceService;  
31 -  
32 - // 与某个客户端的连接会话,需要通过它来给客户端发送数据  
33 - private Session session;  
34 -  
35 - private Boolean runState = false;  
36 -  
37 - /**  
38 - * 建立WebSocket连接  
39 - *  
40 - * @param session  
41 - * @param userId 用户ID  
42 - */  
43 - @OnOpen  
44 - public void onOpen(Session session, @PathParam(value = "userId") Integer userId) {  
45 - log.info("WebSocket建立连接中,连接用户ID:{}", userId);  
46 - WebSocketClien.login(userId);  
47 - // 建立连接  
48 - this.session = session;  
49 - WebSocketClien.webSocketSet.add(this);  
50 - WebSocketClien.sessionPool.put(userId, session);  
51 - log.info("建立连接完成,当前在线人数为:{}", WebSocketClien.webSocketSet.size());  
52 - sendMessageByUser(userId,AjaxResult.success("链接成功").toString());  
53 - }  
54 -  
55 - /**  
56 - * 发生错误  
57 - *  
58 - * @param throwable e  
59 - */  
60 - @OnError  
61 - public void onError(Throwable throwable) {  
62 - throwable.printStackTrace();  
63 - }  
64 -  
65 - /**  
66 - * 连接关闭  
67 - */  
68 - @OnClose  
69 - public void onClose() {  
70 - WebSocketClien.webSocketSet.remove(this);  
71 - log.info("连接断开,当前在线人数为:{}", WebSocketClien.webSocketSet.size());  
72 - }  
73 -  
74 - /**  
75 - * 接收客户端消息  
76 - *  
77 - * @param message 接收的消息  
78 - */  
79 - @OnMessage  
80 - public void onMessage(String message) {  
81 - log.info("收到客户端发来的消息:{}", message);  
82 - if(StringUtils.isNotEmpty(message))  
83 - {  
84 - switch (message)  
85 - {  
86 - case "openRunState":  
87 - runState = true;  
88 - case "closeRunState":  
89 - runState = false;  
90 - }  
91 - }  
92 - }  
93 -  
94 - /**  
95 - * 推送消息到指定用户  
96 - *  
97 - * @param userId 用户ID  
98 - * @param message 发送的消息  
99 - */  
100 - public void sendMessageByUser(Integer userId, String message) {  
101 - log.info("用户ID:" + userId + ",推送内容:" + message);  
102 - try {  
103 - session.getBasicRemote().sendText(message);  
104 - } catch (IOException e) {  
105 - log.error("推送消息到指定用户发生错误:" + e.getMessage(), e);  
106 - }  
107 - }  
108 -  
109 - /**  
110 - * 推送消息到指定用户  
111 - *  
112 - * @param webSocketVO 用户ID  
113 - */  
114 - public void sendWebSocketVO(WebSocketVO webSocketVO) {  
115 - try {  
116 - if(runState)  
117 - {  
118 - webSocketVO.setStateData(deviceService.getState());  
119 - }  
120 - session.getBasicRemote().sendText(JSONObject.toJSONString(webSocketVO));  
121 - } catch (IOException e) {  
122 - log.error("推送消息到指定用户发生错误:" + e.getMessage(), e);  
123 - }  
124 - }  
125 - /**  
126 - * 群发消息  
127 - *  
128 - * @param message 发送的消息  
129 - */  
130 - public void sendAllMessage(String message) {  
131 - log.info("发送消息:{}", message);  
132 - for (WebSocketSever webSocket : WebSocketClien.webSocketSet) {  
133 - try {  
134 - webSocket.session.getBasicRemote().sendText(message);  
135 - } catch (IOException e) {  
136 - log.error("群发消息发生错误:" + e.getMessage(), e);  
137 - }  
138 - }  
139 - }  
140 -}  
1 package com.zhonglai.luhui.smart.feeder.service.device; 1 package com.zhonglai.luhui.smart.feeder.service.device;
2 2
3 -import org.bytedeco.javacv.Frame; 3 +
  4 +import com.zhonglai.luhui.smart.feeder.service.PushVideo;
4 5
5 public interface CameraHandle { 6 public interface CameraHandle {
6 - public void init(); 7 + public boolean init();
7 public org.opencv.core.Mat getMat(); 8 public org.opencv.core.Mat getMat();
8 - 9 + public boolean isOpen();
  10 + public void pushVideo(PushVideo pushVideo);
9 } 11 }
1 -package com.zhonglai.luhui.smart.feeder.service.device;  
2 -  
3 -import com.ruoyi.common.utils.StringUtils;  
4 -import com.zhonglai.luhui.smart.feeder.config.OperatingData;  
5 -import com.zhonglai.luhui.smart.feeder.dto.ConfigurationParameter;  
6 -import org.opencv.videoio.VideoCapture;  
7 -import org.slf4j.Logger;  
8 -import org.slf4j.LoggerFactory;  
9 -import org.springframework.beans.factory.annotation.Autowired;  
10 -import org.springframework.beans.factory.annotation.Value;  
11 -import org.springframework.stereotype.Service;  
12 -  
13 -import java.io.File;  
14 -import java.util.concurrent.ScheduledExecutorService;  
15 -import java.util.concurrent.ScheduledFuture;  
16 -import java.util.concurrent.TimeUnit;  
17 -/**  
18 - * 摄像头  
19 - */  
20 -@Service  
21 -public class CameraService {  
22 - private static final Logger logger = LoggerFactory.getLogger(CameraService.class);  
23 -  
24 - @Value("${sys.network_camera_ip}")  
25 - private String ip;  
26 - @Value("${sys.mp4_file_path}")  
27 - private String MP4_FILE_PATH;  
28 -  
29 - private VideoCapture videoCapture;  
30 -  
31 - private ScheduledFuture scheduledFuture;  
32 -  
33 - @Autowired  
34 - private ScheduledExecutorService scheduledExecutorService;  
35 -  
36 - /**  
37 - * 初始化摄像头  
38 - */  
39 - private void openCapture()  
40 - {  
41 - switch (OperatingData.cameraConfig.getCameraInterfaceType().toUpperCase())  
42 - {  
43 - case "USB":  
44 - videoCapture = readVideoCaptureForUSB();  
45 - break;  
46 - case "RTSP":  
47 - videoCapture = readVideoCaptureForRtsp();  
48 - break;  
49 - default:  
50 - videoCapture = readVideoCaptureForFile();  
51 - }  
52 -  
53 - if(null == videoCapture)  
54 - {  
55 - return;  
56 - }  
57 - monitorCapture();  
58 - }  
59 -  
60 -  
61 - /**  
62 - * 检测摄像头是否打开  
63 - */  
64 - private void monitorCapture()  
65 - {  
66 - // 检查视频是否成功打开  
67 - if (null !=videoCapture && videoCapture.isOpened()) {  
68 - OperatingData.cameraData.setVideoIsOpen(true);  
69 - return;  
70 - }  
71 - OperatingData.cameraData.setVideoIsOpen(false);  
72 - }  
73 -  
74 - /**  
75 - * 开启  
76 - */  
77 - public void start()  
78 - {  
79 - if(null == scheduledFuture || scheduledFuture.isDone())  
80 - {  
81 - scheduledFuture = scheduledExecutorService.scheduleWithFixedDelay(() -> {  
82 - logger.info("摄像头状态{}",OperatingData.cameraData.isVideoIsOpen());  
83 - if(!OperatingData.cameraData.isVideoIsOpen())  
84 - {  
85 - openCapture();  
86 - }  
87 - },0,1, TimeUnit.SECONDS);  
88 - }  
89 - logger.info("启动摄像头{}");  
90 - }  
91 -  
92 - /**  
93 - * 关闭  
94 - */  
95 - public void close()  
96 - {  
97 - if(scheduledFuture.isDone())  
98 - {  
99 - scheduledFuture.cancel(true);  
100 - }  
101 -  
102 - if(OperatingData.cameraData.isVideoIsOpen())  
103 - {  
104 - OperatingData.cameraData.setVideoIsOpen(false);  
105 - // 释放资源  
106 - videoCapture.release();  
107 - }  
108 - logger.info("关闭摄像头");  
109 - }  
110 -  
111 - /**  
112 - * 释放资源  
113 - */  
114 - public void clean()  
115 - {  
116 - if(OperatingData.cameraData.isVideoIsOpen())  
117 - {  
118 - OperatingData.cameraData.setVideoIsOpen(false);  
119 - // 释放资源  
120 - videoCapture.release();  
121 - }  
122 - }  
123 -  
124 -  
125 - public VideoCapture getVideoCapture() {  
126 - return videoCapture;  
127 - }  
128 -  
129 -  
130 - /**  
131 - * 读取网络摄像头  
132 - * @return  
133 - */  
134 - public VideoCapture readVideoCaptureForRtsp()  
135 - {  
136 -  
137 - String rtspUrl = "rtsp://admin:Luhui586@"+ip+":554/h264/ch1/main/av_stream";  
138 - VideoCapture videoCapture = new VideoCapture(rtspUrl);  
139 - while (!videoCapture.isOpened())  
140 - {  
141 - try {  
142 - Thread.sleep(1000);  
143 - } catch (InterruptedException e) {  
144 - throw new RuntimeException(e);  
145 - }  
146 - }  
147 - return videoCapture;  
148 - }  
149 -  
150 - /**  
151 - * 读取USB口的摄像头  
152 - * @return  
153 - */  
154 - public VideoCapture readVideoCaptureForUSB()  
155 - {  
156 - for(int i=0;i<10;i++)  
157 - {  
158 - logger.info("初始化摄像头");  
159 - try {  
160 - Thread.sleep(3000);  
161 - } catch (InterruptedException e) {  
162 - throw new RuntimeException(e);  
163 - }  
164 - VideoCapture videoCapture = new VideoCapture();  
165 - boolean isopen = videoCapture.open(i);  
166 - if(isopen)  
167 - {  
168 - logger.info("打开化摄像头"+i+"成功");  
169 - return videoCapture;  
170 - }else {  
171 - logger.info("打开化摄像头"+i+"失败");  
172 - }  
173 - if(null != videoCapture)  
174 - {  
175 - return videoCapture; //拿到的第一个摄像头返回  
176 - }  
177 - }  
178 - logger.info("未检测到USB摄像头!!!");  
179 - return null;  
180 - }  
181 -  
182 - /**  
183 - * 读取本地视频文件  
184 - * @return  
185 - */  
186 - private VideoCapture readVideoCaptureForFile()  
187 - {  
188 - logger.info("未检测到摄像头{},尝试打开本地视频",MP4_FILE_PATH);  
189 - //如果找不到摄像头就找本地视频文件  
190 - File file = new File(MP4_FILE_PATH);  
191 - if(file.exists() && file.isFile())  
192 - {  
193 - VideoCapture videoCapture = new VideoCapture();  
194 - boolean isopen = videoCapture.open(MP4_FILE_PATH);  
195 - System.out.println(isopen);  
196 - return videoCapture;  
197 - }  
198 - return null;  
199 - }  
200 -  
201 -}  
@@ -5,7 +5,7 @@ import com.fazecast.jSerialComm.SerialPort; @@ -5,7 +5,7 @@ import com.fazecast.jSerialComm.SerialPort;
5 import com.fazecast.jSerialComm.SerialPortDataListener; 5 import com.fazecast.jSerialComm.SerialPortDataListener;
6 import com.fazecast.jSerialComm.SerialPortEvent; 6 import com.fazecast.jSerialComm.SerialPortEvent;
7 import com.ruoyi.common.utils.ByteUtil; 7 import com.ruoyi.common.utils.ByteUtil;
8 -import com.zhonglai.luhui.smart.feeder.dto.ConfigurationParameter; 8 +import com.zhonglai.luhui.smart.feeder.config.OperatingData;
9 import com.zhonglai.luhui.smart.feeder.dto.ModbusDto; 9 import com.zhonglai.luhui.smart.feeder.dto.ModbusDto;
10 import com.zhonglai.luhui.smart.feeder.dto.SerialPortConfig; 10 import com.zhonglai.luhui.smart.feeder.dto.SerialPortConfig;
11 import com.zhonglai.luhui.smart.feeder.dto.commd.FeederCommdDto; 11 import com.zhonglai.luhui.smart.feeder.dto.commd.FeederCommdDto;
@@ -22,7 +22,6 @@ import java.util.concurrent.BlockingQueue; @@ -22,7 +22,6 @@ import java.util.concurrent.BlockingQueue;
22 import java.util.concurrent.LinkedBlockingQueue; 22 import java.util.concurrent.LinkedBlockingQueue;
23 import java.util.concurrent.TimeUnit; 23 import java.util.concurrent.TimeUnit;
24 24
25 -@Service  
26 public class SerialPortService { 25 public class SerialPortService {
27 private static final Logger logger = LoggerFactory.getLogger(SerialPortService.class); 26 private static final Logger logger = LoggerFactory.getLogger(SerialPortService.class);
28 private SerialPort serialPort; 27 private SerialPort serialPort;
@@ -31,10 +30,8 @@ public class SerialPortService { @@ -31,10 +30,8 @@ public class SerialPortService {
31 private final Object lock = new Object(); 30 private final Object lock = new Object();
32 // 用于存储串口返回的数据,使用线程安全的队列 31 // 用于存储串口返回的数据,使用线程安全的队列
33 private BlockingQueue<ModbusDto> dataQueue = new LinkedBlockingQueue<>(); 32 private BlockingQueue<ModbusDto> dataQueue = new LinkedBlockingQueue<>();
34 - @Autowired  
35 - private ConfigurationParameterService configurationParameterService;  
36 33
37 - public void init() 34 + public SerialPortService()
38 { 35 {
39 open(); 36 open();
40 } 37 }
@@ -60,7 +57,8 @@ public class SerialPortService { @@ -60,7 +57,8 @@ public class SerialPortService {
60 57
61 private void setComPortParameters() 58 private void setComPortParameters()
62 { 59 {
63 - SerialPortConfig serialPortConfig = (SerialPortConfig)configurationParameterService.getConfig(ConfigurationParameter.SerialPortConfig); 60 +
  61 + SerialPortConfig serialPortConfig = OperatingData.feederConfig.getSerialPortConfig();
64 62
65 serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_BLOCKING | SerialPort.TIMEOUT_WRITE_BLOCKING, 1000, 1000);//设置超时 63 serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_BLOCKING | SerialPort.TIMEOUT_WRITE_BLOCKING, 1000, 1000);//设置超时
66 serialPort.setFlowControl(SerialPort.FLOW_CONTROL_DISABLED);//设置串口的控制流,可以设置为disabled,或者CTS, RTS/CTS, DSR, DTR/DSR, Xon, Xoff, Xon/Xoff等 64 serialPort.setFlowControl(SerialPort.FLOW_CONTROL_DISABLED);//设置串口的控制流,可以设置为disabled,或者CTS, RTS/CTS, DSR, DTR/DSR, Xon, Xoff, Xon/Xoff等
@@ -72,7 +70,10 @@ public class SerialPortService { @@ -72,7 +70,10 @@ public class SerialPortService {
72 if(null == serialPort || !serialPort.isOpen()) 70 if(null == serialPort || !serialPort.isOpen())
73 { 71 {
74 serialPort = findSerialPort(); 72 serialPort = findSerialPort();
75 - setComPortParameters(); 73 + if(null != serialPort)
  74 + {
  75 + setComPortParameters();
  76 + }
76 } 77 }
77 if(null == serialPort) 78 if(null == serialPort)
78 { 79 {
1 package com.zhonglai.luhui.smart.feeder.service.device.handle; 1 package com.zhonglai.luhui.smart.feeder.service.device.handle;
2 2
3 -import com.ruoyi.common.utils.ByteUtil;  
4 -import com.sun.jna.Pointer; 3 +import cn.hutool.core.util.ObjectUtil;
  4 +import com.ruoyi.common.utils.StringUtils;
  5 +import com.zhonglai.luhui.smart.feeder.config.OperatingData;
  6 +import com.zhonglai.luhui.smart.feeder.dto.HCCameraRepose;
  7 +import com.zhonglai.luhui.smart.feeder.service.ConfigurationParameterService;
  8 +import com.zhonglai.luhui.smart.feeder.service.PushVideo;
5 import com.zhonglai.luhui.smart.feeder.service.device.CameraHandle; 9 import com.zhonglai.luhui.smart.feeder.service.device.CameraHandle;
6 -import com.zhonglai.luhui.smart.feeder.service.device.CameraService;  
7 import org.bytedeco.ffmpeg.global.avutil; 10 import org.bytedeco.ffmpeg.global.avutil;
8 import org.bytedeco.javacv.*; 11 import org.bytedeco.javacv.*;
9 -import org.bytedeco.opencv.opencv_core.IplImage;  
10 import org.opencv.core.Mat; 12 import org.opencv.core.Mat;
11 import org.slf4j.Logger; 13 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory; 14 import org.slf4j.LoggerFactory;
13 15
14 -import java.io.IOException; 16 +import javax.swing.*;
  17 +import java.io.File;
15 import java.net.*; 18 import java.net.*;
16 import java.util.Enumeration; 19 import java.util.Enumeration;
17 -import java.util.Random;  
18 import java.util.UUID; 20 import java.util.UUID;
19 21
20 public class CameraRtspHandle implements CameraHandle { 22 public class CameraRtspHandle implements CameraHandle {
21 private static final Logger logger = LoggerFactory.getLogger(CameraRtspHandle.class); 23 private static final Logger logger = LoggerFactory.getLogger(CameraRtspHandle.class);
22 private FFmpegFrameGrabber grabber; 24 private FFmpegFrameGrabber grabber;
23 - private String ip = "192.168.0.198"; 25 +
  26 + private OpenCVFrameConverter.ToOrgOpenCvCoreMat converter2;
  27 +
  28 +
  29 + private FFmpegFrameFilter filter;
  30 +
  31 + public static Mat mat;
  32 +
  33 + public CameraRtspHandle()
  34 + {
  35 + init();
  36 +
  37 + }
  38 +
24 @Override 39 @Override
25 - public void init() { 40 + public boolean init() {
  41 + if(isOpen())
  42 + {
  43 + return true;
  44 + }
  45 +
26 try { 46 try {
27 FFmpegFrameGrabber.tryLoad(); 47 FFmpegFrameGrabber.tryLoad();
28 48
29 - String rtspUrl = "rtsp://admin:Luhui586@"+ip+":554/h264/ch1/main/av_stream";  
30 - grabber = new FFmpegFrameGrabber(rtspUrl);  
31 -// grabber.setOption("framerate", "30"); // 设置帧率为30帧/秒  
32 - grabber.setVideoOption("fflags", "nobuffer");  
33 - grabber.setVideoOption("rtsp_transport", "tcp");  
34 - grabber.setOption("stimeout", "2000000");  
35 - avutil.av_log_set_level(avutil.AV_LOG_ERROR);  
36 - grabber.start(); 49 + switch (OperatingData.cameraConfig.getCameraInterfaceType().toLowerCase())
  50 + {
  51 + case "rtsp":
  52 + if(!initRtsp())
  53 + {
  54 + return false;
  55 + }
  56 + break;
  57 + case "local":
  58 + if(!iniLocal())
  59 + {
  60 + return false;
  61 + }
  62 + break;
  63 + default:
  64 + return false;
  65 + }
  66 + // 创建一个FFmpegFrameFilter对象,用于图像压缩
  67 + filter = new FFmpegFrameFilter("scale=640:-1", grabber.getImageWidth(), grabber.getImageHeight());
  68 + try {
  69 + filter.start();
  70 + } catch (FFmpegFrameFilter.Exception e) {
  71 + throw new RuntimeException(e);
  72 + }
  73 + converter2 = new OpenCVFrameConverter.ToOrgOpenCvCoreMat();
  74 + Thread.sleep(3000);
  75 + Thread thread = new Thread(() -> {
  76 + while (isOpen()) {
  77 + try {
  78 + mat = getMat();
  79 + } catch (Exception e) {
  80 + logger.error("抓取摄像头帧失败",e);
  81 + }
  82 + }
  83 + });
  84 + thread.start();
  85 +
  86 + return true;
37 } catch (Exception e) { 87 } catch (Exception e) {
38 logger.error("摄像头初始化失败",e); 88 logger.error("摄像头初始化失败",e);
  89 + return false;
39 } 90 }
40 } 91 }
41 92
  93 + private boolean iniLocal() throws FFmpegFrameGrabber.Exception, InterruptedException {
  94 + File file = new File("2.pm4");
  95 + if(!file.exists())
  96 + {
  97 + return false;
  98 + }
  99 + grabber = new FFmpegFrameGrabber(file);
  100 + avutil.av_log_set_level(avutil.AV_LOG_ERROR);
  101 + grabber.start();
  102 + while (!grabber.hasAudio() || !grabber.hasVideo())
  103 + {
  104 + Thread.sleep(1000);
  105 + }
  106 + return true;
  107 + }
  108 +
  109 + private boolean initRtsp() throws FFmpegFrameGrabber.Exception, InterruptedException {
  110 + String ip = findCameraIp();
  111 + if(StringUtils.isEmpty(ip))
  112 + {
  113 + logger.error("未找到摄像头");
  114 + return false;
  115 + }
  116 +
  117 + String rtspUrl = "rtsp://admin:Luhui586@"+ip+":554/h264/ch1/main/av_stream";
  118 + grabber = new FFmpegFrameGrabber(rtspUrl);
  119 +// grabber.setOption("framerate", "30"); // 设置帧率为30帧/秒
  120 +// grabber.setOption("skip_frame", "nokey"); // 只抓取关键帧
  121 +// grabber.setOption("skip_initial_bytes", "1"); // 跳过初始字节直到第一个关键帧
  122 + grabber.setVideoOption("fflags", "nobuffer");
  123 + grabber.setVideoOption("-vf", "nobuffer");
  124 +// grabber.setOption("buffer_size", "4096"); // 设置缓冲区大小为1024字节
  125 + grabber.setVideoOption("rtsp_transport", "tcp");
  126 + grabber.setOption("stimeout", "2000000");
  127 + avutil.av_log_set_level(avutil.AV_LOG_ERROR);
  128 + grabber.start();
  129 + while (!grabber.hasAudio() || !grabber.hasVideo())
  130 + {
  131 + Thread.sleep(1000);
  132 + }
  133 + return true;
  134 + }
  135 +
  136 + public boolean isOpen()
  137 + {
  138 + if(null == grabber)
  139 + {
  140 + return false;
  141 + }
  142 + if(grabber.isDeinterlace())
  143 + {
  144 + close();
  145 + return false;
  146 + }
  147 + if(grabber.isCloseInputStream())
  148 + {
  149 + close();
  150 + return false;
  151 + }
  152 + if(grabber.isTriggerMode())
  153 + {
  154 + close();
  155 + return false;
  156 + }
  157 + if(!grabber.hasAudio())
  158 + {
  159 + close();
  160 + return false;
  161 + }
  162 + if(!grabber.hasVideo())
  163 + {
  164 + close();
  165 + return false;
  166 + }
  167 +
  168 + return true;
  169 + }
  170 +
42 @Override 171 @Override
43 public Mat getMat() { 172 public Mat getMat() {
44 - return null; 173 + Frame frame = getFrame();
  174 + if(null == frame)
  175 + {
  176 + return null;
  177 + }
  178 + return converter2.convert(frame);
45 } 179 }
46 180
47 - public static void main(String[] args) {  
48 -// CameraRtspHandle cameraRtspHandle = new CameraRtspHandle();  
49 -// cameraRtspHandle.init();  
50 -// FFmpegFrameGrabber grabber = cameraRtspHandle.grabber;  
51 -//  
52 -// CanvasFrame previewCanvas = new CanvasFrame("摄像头预览", CanvasFrame.getDefaultGamma() / grabber.getGamma());  
53 -// previewCanvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
54 -// previewCanvas.setAlwaysOnTop(true);  
55 -//  
56 -// // 创建一个FFmpegFrameFilter对象,用于图像压缩  
57 -// FFmpegFrameFilter filter = new FFmpegFrameFilter("scale=640:-1", grabber.getImageWidth(), grabber.getImageHeight());  
58 -// try {  
59 -// filter.start();  
60 -// } catch (FFmpegFrameFilter.Exception e) {  
61 -// throw new RuntimeException(e);  
62 -// }  
63 -//  
64 -//  
65 -// while (true)  
66 -// {  
67 -// logger.info("当前grabber状态:hasAudio {},hasVideo {},isCloseInputStream {},isDeinterlace {},isTriggerMode {}",grabber.hasAudio(),grabber.hasVideo(),grabber.isCloseInputStream(),grabber.isDeinterlace(),grabber.isTriggerMode());  
68 -// try {  
69 -// filter.push(grabber.grabImage());  
70 -// Frame filteredFrame = filter.pull();  
71 -// if(null != filteredFrame)  
72 -// {  
73 -// previewCanvas.showImage(filteredFrame);  
74 -// }  
75 -// } catch (FFmpegFrameGrabber.Exception e) {  
76 -// logger.info("无法显示");  
77 -// } catch (FFmpegFrameFilter.Exception e) {  
78 -// throw new RuntimeException(e);  
79 -// }  
80 -// }  
81 - // 创建UDP Socket  
82 - MulticastSocket socket = null;  
83 - try {  
84 - socket = new MulticastSocket (37020);  
85 - socket.setTimeToLive(1);  
86 -// socket.setSoTimeout(10000);  
87 - socket.joinGroup( InetAddress.getByName("239.255.255.250"));  
88 - } catch (SocketException e) {  
89 - throw new RuntimeException(e);  
90 - } catch (UnknownHostException e) {  
91 - throw new RuntimeException(e);  
92 - } catch (IOException e) {  
93 - throw new RuntimeException(e); 181 + public Frame toFram(Mat mat) {
  182 + if(null == mat)
  183 + {
  184 + return null;
94 } 185 }
  186 + return converter2.convert(mat);
  187 + }
  188 +
  189 + private Frame getFrame() {
  190 + Frame frame = null;
95 try { 191 try {
  192 + frame = grabber.grabImage();
  193 + if (frame == null || frame.imageHeight==0) {
  194 + //TODO:连续n次为null,进行重连
  195 + logger.info("读取不到画面,当前grabber状态:hasAudio {},hasVideo {},isCloseInputStream {},isDeinterlace {},isTriggerMode {}",grabber.hasAudio(),grabber.hasVideo(),grabber.isCloseInputStream(),grabber.isDeinterlace(),grabber.isTriggerMode());
  196 + return null;
  197 + }
  198 + else{
  199 + return frame;
  200 + }
  201 + } catch (Exception e) {
  202 + logger.error("抓取摄像头帧失败",e);
  203 + return null;
  204 + }
96 205
97 - for (int i=0;i<3;i++)  
98 - {  
99 - UUID uuid = UUID.randomUUID();  
100 - String uuidString = uuid.toString().toUpperCase();  
101 - // 构造sadp请求数据包  
102 - String str = "<?xml version=\"1.0\" encoding=\"utf-8\"?><Probe><Uuid>"+uuidString+"</Uuid><Types>inquiry</Types></Probe>"; 206 + }
103 207
104 - byte[] requestData = str.getBytes();  
105 - DatagramPacket requestPacket = new DatagramPacket(requestData, requestData.length, InetAddress.getByName("239.255.255.250"), 37020); 208 + public Frame compress(Frame frame)
  209 + {
  210 + try {
  211 + filter.push(frame);
  212 + Frame filteredFrame = filter.pull();
  213 + return filteredFrame;
  214 + } catch (FFmpegFrameFilter.Exception e) {
  215 + logger.error("压缩失败",e);
  216 + }
  217 + return frame;
  218 + }
106 219
107 - Thread.sleep(1000);  
108 - // 发送请求数据包  
109 - socket.send(requestPacket); 220 + public void pushVideo(PushVideo pushVideo)
  221 + {
  222 + logger.info("当前grabber状态:hasAudio {},hasVideo {},isCloseInputStream {},isDeinterlace {},isTriggerMode {}",grabber.hasAudio(),grabber.hasVideo(),grabber.isCloseInputStream(),grabber.isDeinterlace(),grabber.isTriggerMode());
  223 + if(grabber.hasAudio() && grabber.hasVideo())
  224 + {
  225 + try {
  226 + Frame filteredFrame = compress(grabber.grabImage());
  227 + if(null != filteredFrame)
  228 + {
  229 + pushVideo.display(filteredFrame);
  230 + }
  231 + } catch (FFmpegFrameGrabber.Exception e) {
  232 + logger.info("无法显示");
110 } 233 }
  234 + }
111 235
  236 + }
  237 +
  238 + public static void main(String[] args) {
  239 + ConfigurationParameterService.initConfigurationParameter();
  240 + CameraRtspHandle cameraRtspHandle = new CameraRtspHandle();
  241 + if(cameraRtspHandle.isOpen())
  242 + {
  243 + CanvasFrame previewCanvas = new CanvasFrame("摄像头预览", CanvasFrame.getDefaultGamma() / cameraRtspHandle.grabber.getGamma());
  244 + previewCanvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  245 + previewCanvas.setAlwaysOnTop(true);
112 while (true) 246 while (true)
113 { 247 {
114 - // 接收响应数据包  
115 - byte[] responseData = new byte[4096];  
116 - DatagramPacket responsePacket = new DatagramPacket(responseData, responseData.length);  
117 - socket.receive(responsePacket);  
118 -  
119 - // 解析响应数据包  
120 - String response = new String(responsePacket.getData(), 0, responsePacket.getLength());  
121 - System.out.println("Response: " + response); 248 + cameraRtspHandle.pushVideo(filteredFrame -> previewCanvas.showImage(filteredFrame));
122 } 249 }
  250 + }
123 251
124 - } catch (Exception e) {  
125 - e.printStackTrace();  
126 - }finally {  
127 - try {  
128 - socket.leaveGroup( InetAddress.getByName("239.255.255.250"));  
129 - } catch (IOException e) {  
130 - throw new RuntimeException(e); 252 + }
  253 +
  254 +
  255 + private static String getLocalIp()
  256 + {
  257 + Enumeration<NetworkInterface> interfaces = null;
  258 + try {
  259 + interfaces = NetworkInterface.getNetworkInterfaces();
  260 + while (interfaces.hasMoreElements()) {
  261 + NetworkInterface networkInterface = interfaces.nextElement();
  262 + if (networkInterface.isLoopback() || !networkInterface.isUp()) {
  263 + continue;
  264 + }
  265 + Enumeration<InetAddress> addresses = networkInterface.getInetAddresses();
  266 + while (addresses.hasMoreElements()) {
  267 + InetAddress addr = addresses.nextElement();
  268 + if (addr.isSiteLocalAddress()) { // Checks if this address is a "site local" address.
  269 +
  270 + if(addr.getHostAddress().contains("192.168"))
  271 + {
  272 + return addr.getHostAddress();
  273 + }
  274 + }
  275 + }
131 } 276 }
132 - // 关闭Socket  
133 - socket.close(); 277 + } catch (SocketException e) {
134 } 278 }
  279 + return null;
135 } 280 }
136 281
137 - public static String formatUuid(String uuid) {  
138 - return uuid.substring(0, 8) + "-" +  
139 - uuid.substring(8, 12) + "-" +  
140 - uuid.substring(12, 16) + "-" +  
141 - uuid.substring(16, 20) + "-" +  
142 - uuid.substring(20); 282 + public static String findCameraIp() {
  283 + String localIP = getLocalIp();
  284 + if(null == localIP)
  285 + {
  286 + return null;
  287 + }
  288 + try {
  289 + final String[] ip = new String[1];
  290 + final Object lock = new Object();
  291 +
  292 + Thread thread1 = new Thread(() -> {
  293 + try {
  294 + synchronized (lock) {
  295 + ip[0] = getCameraIp(localIP);
  296 + lock.notify();
  297 + }
  298 + } catch (Exception e) {
  299 + e.printStackTrace();
  300 + }
  301 + });
  302 +
  303 + Thread thread2 = new Thread(() -> {
  304 + try {
  305 + while (StringUtils.isEmpty(ip[0]))
  306 + {
  307 + findCamera(localIP);
  308 + Thread.sleep(1000);
  309 + }
  310 + } catch (InterruptedException e) {
  311 + e.printStackTrace();
  312 + }
  313 + });
  314 +
  315 + thread1.start();
  316 + thread2.start();
  317 +
  318 + synchronized (lock) {
  319 + lock.wait(5000);
  320 + }
  321 + return ip[0];
  322 + } catch (InterruptedException e) {
  323 + }
  324 + return null;
143 } 325 }
144 326
145 - public static void sendudp() 327 + private static void findCamera(String ip)
146 { 328 {
147 try { 329 try {
148 - // 创建组播Socket  
149 - InetAddress group = InetAddress.getByName("239.255.255.250");  
150 - MulticastSocket socket = new MulticastSocket(37020); 330 + InetAddress group = InetAddress.getByName("239.255.255.250"); // 组播地址
  331 + int port = 37020; // 组播端口
151 332
152 - // 加入组播组  
153 - socket.joinGroup(group); 333 + MulticastSocket multicastSocket = new MulticastSocket(new InetSocketAddress(InetAddress.getByName(ip), 37020));
154 334
155 - while (socket.isConnected())  
156 - {  
157 - // 接收消息  
158 - byte[] buffer = new byte[4096];  
159 - DatagramPacket packet = new DatagramPacket(buffer, buffer.length);  
160 - socket.receive(packet);  
161 - // 解析消息并处理  
162 - String message = new String(packet.getData(), 0, packet.getLength());  
163 - System.out.println("Received message: " + message);  
164 - }  
165 - // 退出组播组  
166 - socket.leaveGroup(group); 335 + // 发送消息
  336 + String uuid = UUID.randomUUID().toString().toUpperCase();
  337 + String message = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
  338 + "<Probe>" +
  339 + " <Uuid>" + uuid + "</Uuid>" +
  340 + " <Types>inquiry</Types>" +
  341 + "</Probe>";
  342 + byte[] buffer = message.getBytes();
  343 + DatagramPacket packet = new DatagramPacket(buffer, buffer.length, group, port);
  344 + multicastSocket.send(packet);
167 345
168 - // 关闭Socket  
169 - socket.close(); 346 + multicastSocket.close();
170 } catch (Exception e) { 347 } catch (Exception e) {
171 e.printStackTrace(); 348 e.printStackTrace();
172 - }finally {  
173 -  
174 - }  
175 - }  
176 -  
177 - /**  
178 - * 生成UUID的方法  
179 - * @return 返回 UUID 字符串  
180 - */  
181 - public static String generateUUID() {  
182 - // 获取当前时间戳  
183 - long timeMillis = 1697789348000l;  
184 - // 获取机器MAC地址  
185 - String macAddress = "G24198441";  
186 - // 生成随机数  
187 - int randomInt = new Random().nextInt();  
188 - // 获取个人或组织的标识码(这里设为 001)  
189 - int nodeId = 001;  
190 - // 组合 UUID 字符串  
191 - String uuid = String.format("%016x", timeMillis) //  
192 - + String.format("%016x", randomInt) //  
193 - + String.format("%016x", nodeId) //  
194 - + macAddress;  
195 - // 返回 UUID 字符串  
196 - return uuid; 349 + }
  350 + }
  351 +
  352 + private static String getCameraIp(String ip) throws Exception {
  353 + // 1.创建组播socket,加入指定的组播地址和端口
  354 + InetAddress group = InetAddress.getByName("239.255.255.250");
  355 + MulticastSocket multicastSocket = new MulticastSocket(37020);
  356 +
  357 + multicastSocket.joinGroup(new InetSocketAddress(group,37020),NetworkInterface.getByInetAddress(InetAddress.getByName(ip)));
  358 + multicastSocket.setSoTimeout(100000);
  359 + // 2.创建接收的数据包
  360 + byte[] buf = new byte[1024];
  361 +
  362 +
  363 + // 4.解析数据包,并打印出来
  364 + HCCameraRepose probe = null;
  365 + while (ObjectUtil.isEmpty(probe))
  366 + {
  367 + DatagramPacket dpReceive = new DatagramPacket(buf, buf.length);
  368 + // 3.调用socket对象的接收方法接收数据包
  369 + multicastSocket.receive(dpReceive);
  370 + String receivedXml = new String(dpReceive.getData(), 0, dpReceive.getLength());
  371 +
  372 + String startTag = "<IPv4Address>";
  373 + String endTag = "</IPv4Address>";
  374 + int start = receivedXml.indexOf(startTag);
  375 + int end = receivedXml.indexOf(endTag);
  376 + if(start<0)
  377 + {
  378 + continue;
  379 + }
  380 + // 检查是否找到标签
  381 + if (start == -1 || end == -1) {
  382 + return "No IPv4Address tag found.";
  383 + }
  384 +
  385 + // 计算开始位置(包含开始标签的长度,因为我们想要从标签后面开始截取)
  386 + start = start + startTag.length();
  387 +
  388 + // 截取并返回结果
  389 + return receivedXml.substring(start, end);
  390 + }
  391 +
  392 + return probe.getIPv4Address();
  393 + }
  394 +
  395 + public void close()
  396 + {
  397 + if(null != grabber)
  398 + {
  399 + try {
  400 + grabber.release();
  401 + grabber.close();
  402 + grabber = null;
  403 + } catch (FrameGrabber.Exception e) {
  404 + logger.info("摄像头关闭失败",e);
  405 + }
  406 + }
  407 + if(null !=converter2)
  408 + {
  409 + converter2.close();
  410 + }
  411 +
197 } 412 }
198 } 413 }
  1 +package com.zhonglai.luhui.smart.feeder.service.feeder;
  2 +
  3 +import com.google.gson.JsonObject;
  4 +import com.ruoyi.common.utils.GsonConstructor;
  5 +import com.zhonglai.luhui.smart.feeder.config.OperatingData;
  6 +import com.zhonglai.luhui.smart.feeder.dto.mqtt.CmdDto;
  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;
  10 +import io.netty.channel.ChannelHandlerContext;
  11 +import io.netty.handler.codec.MessageToMessageDecoder;
  12 +import org.apache.commons.lang3.StringUtils;
  13 +
  14 +import java.util.List;
  15 +import java.util.regex.Matcher;
  16 +import java.util.regex.Pattern;
  17 +
  18 +/**
  19 + * 协议解析
  20 + */
  21 +public class AgreementHandler extends MessageToMessageDecoder<String> {
  22 + private CfgdataService cfgdataService = new CfgdataService();
  23 + private ManualcontrolService manualcontrolService = new ManualcontrolService();
  24 +
  25 + private CameracontrolService cameracontrolService = new CameracontrolService();
  26 +
  27 + private NettyClient nettyClient;
  28 +
  29 + public AgreementHandler(NettyClient nettyClient)
  30 + {
  31 + this.nettyClient = nettyClient;
  32 + }
  33 +
  34 + @Override
  35 + public void channelActive(ChannelHandlerContext ctx) throws Exception {
  36 + nettyClient.setCtx(ctx);
  37 + // 连接建立时的处理,发送请求注册消息给服务器
  38 + JsonObject jsonObject = new JsonObject();
  39 + jsonObject.addProperty("cmd","manualcontrol");
  40 + jsonObject.addProperty("type","4G.hs");
  41 + MessageUtil.sendMessage(ctx, new CmdDto().setImei(OperatingData.sysConfig.getNettyConfig().getClientId()).setJsonObject(jsonObject).generateCmd(),true);
  42 + }
  43 +
  44 + @Override
  45 + public void channelInactive(ChannelHandlerContext ctx) throws Exception {
  46 + Thread.sleep(3000);
  47 + nettyClient.close();
  48 + Thread.sleep(3000);
  49 + nettyClient.start();
  50 + }
  51 +
  52 + private static boolean checkAgreement(String data)
  53 + {
  54 + String regEx = "(?:\\^)\\d+\\{.*}\\w+(?:~)";
  55 + // 编译正则表达式
  56 + Pattern pattern = Pattern.compile(regEx);
  57 + // 忽略大小写的写法
  58 + // Pattern pat = Pattern.compile(regEx, Pattern.CASE_INSENSITIVE);
  59 + Matcher matcher = pattern.matcher(data);
  60 + // 字符串是否与正则表达式相匹配
  61 + boolean rs = matcher.matches();
  62 + return rs;
  63 + }
  64 +
  65 + @Override
  66 + protected void decode(ChannelHandlerContext ctx, String msg, List<Object> out) throws Exception {
  67 + try {
  68 + System.out.println("读取到数据:"+msg);
  69 + if(StringUtils.isNotBlank(msg) && checkAgreement(msg))
  70 + {
  71 + CmdDto cmdDto = new CmdDto(msg);
  72 + if(cmdDto.checkLRC())
  73 + {
  74 + HeadDto headDto = GsonConstructor.get().fromJson(cmdDto.getJsonObject(), HeadDto.class);
  75 + switch (headDto.getCmd())
  76 + {
  77 + case "devicedataOK":
  78 + break;
  79 + case "cfgdata":
  80 + cfgdataService.noticeFeeder(ctx,cmdDto);
  81 + break;
  82 + case "manualcontrol":
  83 + manualcontrolService.noticeFeeder(ctx,cmdDto);
  84 + break;
  85 + case "cameracontrol":
  86 + cameracontrolService.noticeFeeder(ctx,cmdDto);
  87 + break;
  88 + default:
  89 + break;
  90 + }
  91 + }
  92 + }
  93 + }catch (Exception e)
  94 + {
  95 + }
  96 + }
  97 +}
  1 +package com.zhonglai.luhui.smart.feeder.service.feeder;
  2 +
  3 +import com.google.gson.JsonObject;
  4 +import com.ruoyi.common.utils.GsonConstructor;
  5 +import com.zhonglai.luhui.smart.feeder.config.OperatingData;
  6 +import com.zhonglai.luhui.smart.feeder.dto.CameraConfig;
  7 +import com.zhonglai.luhui.smart.feeder.dto.commd.FeederBackstateTtpe;
  8 +import com.zhonglai.luhui.smart.feeder.dto.mqtt.CameracontrolRequest;
  9 +import com.zhonglai.luhui.smart.feeder.dto.mqtt.CmdDto;
  10 +import com.zhonglai.luhui.smart.feeder.service.InitService;
  11 +import com.zhonglai.luhui.smart.feeder.service.device.handle.CameraRtspHandle;
  12 +import com.zhonglai.luhui.smart.feeder.util.FeederCommd06ResponseType;
  13 +import com.zhonglai.luhui.smart.feeder.util.FeederCommdUtil;
  14 +import com.zhonglai.luhui.smart.feeder.util.MessageUtil;
  15 +import io.netty.channel.ChannelHandlerContext;
  16 +import org.slf4j.Logger;
  17 +import org.slf4j.LoggerFactory;
  18 +
  19 +
  20 +public class CameracontrolService {
  21 + private static final Logger logger = LoggerFactory.getLogger(CameracontrolService.class);
  22 + public void noticeFeeder(ChannelHandlerContext ctx,CmdDto cmdDto)
  23 + {
  24 + if(!InitService.cameraHandle.isOpen())
  25 + {
  26 + MessageUtil.sendFeederResponseMessage(ctx,"cfgdataOK", FeederBackstateTtpe.cameraErr,0);
  27 + return;
  28 + }
  29 +
  30 + JsonObject data = cmdDto.getJsonObject();
  31 + if (null == data || data.size()==0)
  32 + {
  33 + MessageUtil.sendFeederResponseMessage(ctx,"cfgdataOK", FeederBackstateTtpe.success,0xE2);
  34 + return;
  35 + }
  36 +
  37 + try {
  38 + CameracontrolRequest cameracontrolRequest = GsonConstructor.get().fromJson(data.toString(), CameracontrolRequest.class);
  39 + OperatingData.setClassObjecValue(cameracontrolRequest.getCameraConfig(), (fieldname, fieldObject) -> {
  40 + switch (fieldname)
  41 + {
  42 + case "cameraInterfaceType":
  43 + ((CameraRtspHandle)InitService.cameraHandle).close();
  44 + InitService.cameraHandle.init();
  45 + break;
  46 + }
  47 + });
  48 + MessageUtil.sendFeederResponseMessage(ctx,"cfgdataOK", FeederBackstateTtpe.success,0);
  49 + }catch (Exception e)
  50 + {
  51 + MessageUtil.sendFeederResponseMessage(ctx,"cfgdataOK", FeederBackstateTtpe.runErr,0);
  52 + }
  53 + }
  54 +
  55 +
  56 +}
  1 +package com.zhonglai.luhui.smart.feeder.service.feeder;
  2 +
  3 +import com.google.gson.JsonObject;
  4 +import com.ruoyi.common.utils.GsonConstructor;
  5 +import com.zhonglai.luhui.smart.feeder.Main;
  6 +import com.zhonglai.luhui.smart.feeder.config.OperatingData;
  7 +import com.zhonglai.luhui.smart.feeder.domain.Register;
  8 +import com.zhonglai.luhui.smart.feeder.dto.CameraConfig;
  9 +import com.zhonglai.luhui.smart.feeder.dto.commd.FeederBackstateTtpe;
  10 +import com.zhonglai.luhui.smart.feeder.dto.commd.FeederTimer;
  11 +import com.zhonglai.luhui.smart.feeder.dto.mqtt.CameracontrolRequest;
  12 +import com.zhonglai.luhui.smart.feeder.dto.mqtt.CfgdataRequest;
  13 +import com.zhonglai.luhui.smart.feeder.dto.mqtt.CmdDto;
  14 +import com.zhonglai.luhui.smart.feeder.dto.mqtt.Condata;
  15 +import com.zhonglai.luhui.smart.feeder.service.ConfigurationParameterService;
  16 +import com.zhonglai.luhui.smart.feeder.service.InitService;
  17 +import com.zhonglai.luhui.smart.feeder.util.FeederCommd06ResponseType;
  18 +import com.zhonglai.luhui.smart.feeder.util.FeederCommdUtil;
  19 +import com.zhonglai.luhui.smart.feeder.util.MessageUtil;
  20 +import io.netty.channel.ChannelHandlerContext;
  21 +import org.slf4j.Logger;
  22 +import org.slf4j.LoggerFactory;
  23 +
  24 +import java.lang.reflect.Field;
  25 +import java.util.List;
  26 +import java.util.Map;
  27 +
  28 +public class CfgdataService {
  29 + private static final Logger logger = LoggerFactory.getLogger(CfgdataService.class);
  30 + public void noticeFeeder(ChannelHandlerContext ctx,CmdDto cmdDto)
  31 + {
  32 + if(!InitService.serialPortService.open())
  33 + {
  34 + MessageUtil.sendFeederResponseMessage(ctx,"cfgdataOK", FeederBackstateTtpe.serialPortErr,0);
  35 + return;
  36 + }
  37 + JsonObject data = cmdDto.getJsonObject();
  38 + if (null == data || data.size()==0)
  39 + {
  40 + MessageUtil.sendFeederResponseMessage(ctx,"cfgdataOK", FeederBackstateTtpe.success,0xE2);
  41 + return;
  42 + }
  43 + try {
  44 + CfgdataRequest cfgdataRequest = GsonConstructor.get().fromJson(data.toString(), CfgdataRequest.class);
  45 + OperatingData.setClassObjecValue(cfgdataRequest.getCondata(), (fieldname, fieldObject) -> {
  46 + try {
  47 + String commd = FeederCommdUtil.controlData( FeederCommd06ResponseType.valueOf(fieldname),(Integer) fieldObject);
  48 + logger.info("远程发送指令{}",commd);
  49 + InitService.serialPortService.sendStrData(commd);
  50 + }catch (Exception e)
  51 + {
  52 + logger.error("发送指令失败:"+GsonConstructor.get().toJson(fieldname),e);
  53 + MessageUtil.sendFeederResponseMessage(ctx,"cfgdataOK", FeederBackstateTtpe.serialPortCommandSendErr,0);
  54 + throw new RuntimeException(e);
  55 + }
  56 + });
  57 +
  58 +
  59 + List<Integer[]> timerList = cfgdataRequest.getTimer();
  60 + if(null != timerList && timerList.size() != 0 )
  61 + {
  62 + for (int i=0;i<timerList.size();i++)
  63 + {
  64 + Integer[] timerNumber = timerList.get(i);
  65 + FeederTimer feederTimer = new FeederTimer();
  66 + feederTimer.setTimer_start_m(timerNumber[1]);
  67 + feederTimer.setTimer_start_h(timerNumber[0]);
  68 + feederTimer.setTimer_if_start(timerNumber[4]);
  69 + feederTimer.setTimer_is_start(1);
  70 + feederTimer.setTimer_close_m(timerNumber[3]);
  71 + feederTimer.setTimer_close_h(timerNumber[2]);
  72 + feederTimer.setTimer_if_close(timerNumber[4]);
  73 + feederTimer.setTimer_is_close(1);
  74 + InitService.serialPortService.sendHexData(FeederCommdUtil.controlTimer((i/2)+1,feederTimer));
  75 + }
  76 + }
  77 + MessageUtil.sendFeederResponseMessage(ctx,"cfgdataOK", FeederBackstateTtpe.success,0);
  78 + }catch (Exception e)
  79 + {
  80 + MessageUtil.sendFeederResponseMessage(ctx,"cfgdataOK", FeederBackstateTtpe.runErr,0);
  81 + }
  82 +
  83 + }
  84 +
  85 +}
  1 +package com.zhonglai.luhui.smart.feeder.service.feeder;
  2 +
  3 +import com.google.gson.JsonObject;
  4 +import com.ruoyi.common.utils.GsonConstructor;
  5 +import com.zhonglai.luhui.smart.feeder.config.OperatingData;
  6 +import com.zhonglai.luhui.smart.feeder.dto.commd.FeederBackstateTtpe;
  7 +import com.zhonglai.luhui.smart.feeder.dto.mqtt.CfgdataRequest;
  8 +import com.zhonglai.luhui.smart.feeder.dto.mqtt.CmdDto;
  9 +import com.zhonglai.luhui.smart.feeder.dto.mqtt.Condata;
  10 +import com.zhonglai.luhui.smart.feeder.dto.mqtt.ManualcontrolRequest;
  11 +import com.zhonglai.luhui.smart.feeder.service.InitService;
  12 +import com.zhonglai.luhui.smart.feeder.util.FeederCommd06ResponseType;
  13 +import com.zhonglai.luhui.smart.feeder.util.FeederCommdUtil;
  14 +import com.zhonglai.luhui.smart.feeder.util.MessageUtil;
  15 +import io.netty.channel.ChannelHandlerContext;
  16 +import org.slf4j.Logger;
  17 +import org.slf4j.LoggerFactory;
  18 +
  19 +import java.lang.reflect.Field;
  20 +
  21 +public class ManualcontrolService {
  22 + private static final Logger logger = LoggerFactory.getLogger(CfgdataService.class);
  23 +
  24 + public void noticeFeeder(ChannelHandlerContext ctx,CmdDto cmdDto)
  25 + {
  26 + if(!InitService.serialPortService.open())
  27 + {
  28 + MessageUtil.sendFeederResponseMessage(ctx,"cfgdataOK", FeederBackstateTtpe.serialPortErr,0);
  29 + return;
  30 + }
  31 +
  32 + JsonObject data = cmdDto.getJsonObject();
  33 + if (null == data || data.size()==0)
  34 + {
  35 + MessageUtil.sendFeederResponseMessage(ctx,"cfgdataOK", FeederBackstateTtpe.success,0xE2);
  36 + return;
  37 + }
  38 + try {
  39 + ManualcontrolRequest manualcontrolRequest = GsonConstructor.get().fromJson(data.toString(), ManualcontrolRequest.class);
  40 + OperatingData.setClassObjecValue(manualcontrolRequest.getCondata(), (fieldname, fieldObject) -> {
  41 + try {
  42 + String commd = FeederCommdUtil.controlData( FeederCommd06ResponseType.valueOf(fieldname),(Integer) fieldObject);
  43 + logger.info("远程发送指令{}",commd);
  44 + InitService.serialPortService.sendStrData(commd);
  45 + }catch (Exception e)
  46 + {
  47 + logger.error("发送指令失败:"+GsonConstructor.get().toJson(fieldname),e);
  48 + MessageUtil.sendFeederResponseMessage(ctx,"cfgdataOK", FeederBackstateTtpe.serialPortCommandSendErr,0);
  49 + throw new RuntimeException(e);
  50 + }
  51 + });
  52 +
  53 + MessageUtil.sendFeederResponseMessage(ctx,"cfgdataOK", FeederBackstateTtpe.success,0);
  54 + }catch (Exception e)
  55 + {
  56 + MessageUtil.sendFeederResponseMessage(ctx,"cfgdataOK", FeederBackstateTtpe.runErr,0);
  57 + }
  58 +
  59 + }
  60 +}