正在显示
58 个修改的文件
包含
1683 行增加
和
2623 行删除
| @@ -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; | 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 | -} |
lh-modules/lh-smart-feeder/src/main/java/com/zhonglai/luhui/smart/feeder/config/ScheduledConfig.java
0 → 100644
| 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 | } |
lh-modules/lh-smart-feeder/src/main/java/com/zhonglai/luhui/smart/feeder/dto/ConfigDto.java
已删除
100644 → 0
| 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 | } |
| @@ -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 | } |
lh-modules/lh-smart-feeder/src/main/java/com/zhonglai/luhui/smart/feeder/dto/HCCameraRepose.java
0 → 100644
| 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 | +} |
lh-modules/lh-smart-feeder/src/main/java/com/zhonglai/luhui/smart/feeder/dto/NettyConfig.java
0 → 100644
| 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.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 | +} |
lh-modules/lh-smart-feeder/src/main/java/com/zhonglai/luhui/smart/feeder/dto/mqtt/CmdDto.java
0 → 100644
| 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 | } |
lh-modules/lh-smart-feeder/src/main/java/com/zhonglai/luhui/smart/feeder/dto/mqtt/ReturnOkDto.java
0 → 100644
| 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 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 | +} |
-
请 注册 或 登录 后发表评论