作者 钟来

模块整理

正在显示 53 个修改的文件 包含 2695 行增加42 行删除
... ... @@ -15,7 +15,7 @@ public class SysParameter {
public static String service_ip = ""; //服务所在地址
@Value("${mqtt.topicconfig:/{{roleid}}/{{username}}/{{clientid}}/{{topicType}}/{{messageid}}}")
@Value("${mqtt.topicconfig:/{{roleid}}/{{username}}/{{topicType}}/{{clientid}}}")
public String tempTopicconfig ; //topic 配置
@Value("${mqtt.topics")
... ...
... ... @@ -21,9 +21,11 @@ public class DBFactoryImp implements DBFactory{
try {
if(null==ds )
{
String path = System.getProperty("user.dir")+"/configs/";
String dbPath = System.getProperty("dbPath");
String path = null != dbPath?dbPath:System.getProperty("user.dir")+"/configs/";
Properties p = new Properties();
p.load(new FileInputStream(new File(path+"dbcpconfig.properties")));
System.out.println("》》》》》》》》》》》》》数据库配置文件地址:"+path+"dbcpconfig.properties");
p.load(new FileInputStream(path+"dbcpconfig.properties"));
// p.load(DBFactory.class
// .getClassLoader().getResourceAsStream("configs/dbcpconfig.properties"));
ds = BasicDataSourceFactory.createDataSource(p);
... ...
... ... @@ -188,4 +188,12 @@ public class ByteUtil {
crc = crc.substring(2, 4) + crc.substring(0, 2);
return crc.toUpperCase();
}
public static String changerTwoStr(String str) {
if (null == str && "".equals(str)) {
return "00";
} else {
return str.length() == 1 ? "0" + str : str.substring(str.length() - 2, str.length());
}
}
}
... ...
... ... @@ -6,8 +6,8 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan(basePackages = {
"com.zhonglai.luhui.config",
"com.zhonglai.luhui.controller",
"com.zhonglai.luhui.lsy.plc.service.config",
"com.zhonglai.luhui.lsy.plc.service.controller",
}
)
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
... ...
package com.zhonglai.luhui.data.file.service.baidu;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.ruoyi.common.core.domain.Message;
import com.ruoyi.common.core.domain.MessageCode;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.GsonConstructor;
import com.zhonglai.luhui.data.file.service.config.SysConfig;
import com.zhonglai.luhui.data.file.service.dto.BaiduFileInfo;
import com.zhonglai.luhui.data.file.service.dto.SysTripartitePlatformToken;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.*;
import java.net.*;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 百度网盘服务
*/
public class BaiDuWangPanService {
public static String typestr = "BaiDuWangPanToken_ZL";
/**
* 获取授权地址
* @param redirect_uri
... ... @@ -76,6 +96,140 @@ public class BaiDuWangPanService {
return null;
}
public static String getToken()
{
try {
Entity entity = Db.use().get("sys_tripartite_platform_token","tripartite_platform_type",typestr);
if(null == entity)
{
return null;
}
SysTripartitePlatformToken sysTripartitePlatformToken = entity.toBean(SysTripartitePlatformToken.class);
int time = DateUtils.getNowTimeMilly();
if((sysTripartitePlatformToken.getAccess_token_end_time()-time)<=3600)
{
if((sysTripartitePlatformToken.getRefresh_token_end_time()-time)<=(24*60*60))
{
String str = BaiDuWangPanService.refreshToken(sysTripartitePlatformToken.getRefresh_token());
BaiDuWangPanResponse baiDuWangPanResponse = GsonConstructor.get().fromJson(str,BaiDuWangPanResponse.class);
sysTripartitePlatformToken.setAccess_token(baiDuWangPanResponse.getAccess_token());
sysTripartitePlatformToken.setAccess_token_end_time(sysTripartitePlatformToken.getUpdate_time()+baiDuWangPanResponse.getExpires_in());
sysTripartitePlatformToken.setRefresh_token(baiDuWangPanResponse.getRefresh_token());
sysTripartitePlatformToken.setRefresh_token_end_time(sysTripartitePlatformToken.getUpdate_time()+(10*365*24*60*60));
sysTripartitePlatformToken.setUpdate_time(DateUtils.getNowTimeMilly());
Db.use().update(Entity.create().parse(sysTripartitePlatformToken).setTableName("sys_tripartite_platform_token"),Entity.create().addFieldNames("id"));
return sysTripartitePlatformToken.getAccess_token();
}
return null;
}
return sysTripartitePlatformToken.getAccess_token();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
/**
* 文件列表
* @param path
* @param token
* @param pageNum
* @param pageSize
* @return
*/
public static List<BaiduFileInfo> getFileList(String path,String token,Integer pageNum,Integer pageSize)
{
String str = HttpUtil.get("https://pan.baidu.com/rest/2.0/xpan/file?method=list&dir="+path+"&order=time&start="+((pageNum-1)*pageSize)+"&limit="+pageSize+"&web=web&folder=0&access_token="+token+"&desc=1");
System.out.println(str);
JsonObject jsonObject = GsonConstructor.get().fromJson(str, JsonObject.class);
JsonArray jsonArray = jsonObject.get("list").getAsJsonArray();
List<BaiduFileInfo> list = new ArrayList<>();
for (int i=0;i<jsonArray.size();i++)
{
JsonObject file = jsonArray.get(i).getAsJsonObject();
BaiduFileInfo baiduFileInfo = GsonConstructor.get().fromJson(file.toString(),BaiduFileInfo.class);
list.add(baiduFileInfo);
}
return list;
}
/**
* 递归获取文件列表
* @param path
* @param token
* @param pageNum
* @param pageSize
* @return
*/
public static List<BaiduFileInfo> getRecursionFileList(String path,String token,Integer pageNum,Integer pageSize)
{
String str = HttpUtil.get("http://pan.baidu.com/rest/2.0/xpan/multimedia?method=listall&path="+path+"&access_token="+token+"&web=1&recursion=1&start="+((pageNum-1)*pageSize)+"&limit="+pageSize);
System.out.println(str);
JsonObject jsonObject = GsonConstructor.get().fromJson(str, JsonObject.class);
List<BaiduFileInfo> list = new ArrayList<>();
if (jsonObject.has("list") && null != jsonObject.get("list"))
{
JsonArray jsonArray = jsonObject.get("list").getAsJsonArray();
for (int i=0;i<jsonArray.size();i++)
{
JsonObject file = jsonArray.get(i).getAsJsonObject();
BaiduFileInfo baiduFileInfo = GsonConstructor.get().fromJson(file.toString(),BaiduFileInfo.class);
list.add(baiduFileInfo);
}
}
return list;
}
/**
* 搜索文件
* @param path
* @param token
* @return
*/
public static List<BaiduFileInfo> findFileList(String path,String token,String key,Integer pageNum)
{
String str = HttpUtil.get("http://pan.baidu.com/rest/2.0/xpan/file?dir=/apps/test&access_token="+token+"&web=1&recursion=1&page="+pageNum+"&num=2&method=search&key="+key+"&dir="+path);
JsonArray jsonArray = GsonConstructor.get().fromJson(str,JsonObject.class).get("list").getAsJsonArray();
List<BaiduFileInfo> list = new ArrayList<>();
for (int i=0;i<jsonArray.size();i++)
{
JsonObject jsonObject = jsonArray.get(i).getAsJsonObject();
BaiduFileInfo baiduFileInfo = GsonConstructor.get().fromJson(jsonObject.toString(),BaiduFileInfo.class);
list.add(baiduFileInfo);
}
return list;
}
/**
* 上传文件
* @param token
* @return
*/
public static int upLoadFile( File file,String savepath,String token)
{
HttpRequest request = HttpUtil.createPost("https://d.pcs.baidu.com/rest/2.0/pcs/file?method=upload&access_token="+token+"&path="+savepath);
request.form("file", file); // 上传文件
// 发送请求
HttpResponse response = request.execute();
if(response.isOk()) {
System.out.println("上传成功!");
return 1;
} else {
JsonObject jsonObject = GsonConstructor.get().fromJson(response.body(),JsonObject.class);
if(jsonObject.has("error_code") && jsonObject.get("error_code").getAsInt()==31061)
{
return 2;
}
System.out.println("上传失败!"+response.body());
}
return 0;
}
}
... ...
... ... @@ -29,7 +29,6 @@ import java.sql.SQLException;
@RequestMapping("/baiDuWangPan")
public class BaiDuWangPanController {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private static String typestr = "BaiDuWangPanToken_ZL";
@ApiOperation("获取授权连接")
@GetMapping("/getOauth2Url")
... ... @@ -69,7 +68,7 @@ public class BaiDuWangPanController {
try {
SysTripartitePlatformToken sysTripartitePlatformToken = new SysTripartitePlatformToken();
sysTripartitePlatformToken.setTripartite_platform_type(typestr);
sysTripartitePlatformToken.setTripartite_platform_type(BaiDuWangPanService.typestr);
sysTripartitePlatformToken.setTripartite_platform_name("百度网络的授权token(钟来的)");
sysTripartitePlatformToken.setCreate_time(DateUtils.getNowTimeMilly());
sysTripartitePlatformToken.setUpdate_time(DateUtils.getNowTimeMilly());
... ... @@ -91,7 +90,7 @@ public class BaiDuWangPanController {
public Message getToekn()
{
try {
Entity entity = Db.use().get("sys_tripartite_platform_token","tripartite_platform_type",typestr);
Entity entity = Db.use().get("sys_tripartite_platform_token","tripartite_platform_type",BaiDuWangPanService.typestr);
if(null == entity)
{
return new Message(MessageCode.DEFAULT_FAIL_CODE,"未授权");
... ... @@ -110,6 +109,7 @@ public class BaiDuWangPanController {
sysTripartitePlatformToken.setRefresh_token_end_time(sysTripartitePlatformToken.getUpdate_time()+(10*365*24*60*60));
sysTripartitePlatformToken.setUpdate_time(DateUtils.getNowTimeMilly());
Db.use().update(Entity.create().parse(sysTripartitePlatformToken).setTableName("sys_tripartite_platform_token"),Entity.create().addFieldNames("id"));
return new Message(MessageCode.DEFAULT_SUCCESS_CODE,sysTripartitePlatformToken.getAccess_token());
}
return new Message(MessageCode.DEFAULT_FAIL_CODE,"授权到期,请重新授权");
}
... ...
package com.zhonglai.luhui.data.file.service.dto;
import com.google.gson.JsonObject;
import lombok.Data;
import java.util.Map;
@Data
public class BaiduFileInfo {
private Long fs_id; //uint64; //文件在云端的唯一标识ID
private String path; //string; //文件的绝对路径
private String server_filename; //string; //文件名称
private Integer size; //uint; //文件大小,单位B
private Integer server_mtime; //uint; //文件在服务器修改时间
private Integer server_ctime; //uint; //文件在服务器创建时间
private Integer local_mtime; //uint; //文件在客户端修改时间
private Integer local_ctime; //uint; //文件在客户端创建时间
private Integer isdir; //uint; //是否为目录,0 文件、1 目录
private Integer category; //uint; //文件类型,1 视频、2 音频、3 图片、4 文档、5 应用、6 其他、7 种子
private String md5; //string; //云端哈希(非文件真实MD5),只有是文件类型时,该字段才存在
private Integer dir_empty; //int; //该目录是否存在子目录,只有请求参数web=1且该条目为目录时,该字段才存在, 0为存在, 1为不存在
private Map<String,String> thumbs; //array; //只有请求参数web=1且该条目分类为图片时,该字段才存在,包含三个尺寸的缩略图URL
}
... ...
package com.zhonglai.luhui.data.file.service.util;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import com.zhonglai.luhui.data.file.service.baidu.BaiDuWangPanService;
import com.zhonglai.luhui.data.file.service.dto.BaiduFileInfo;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import java.io.*;
import java.net.URLEncoder;
import java.sql.SQLException;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* 文件工具
*/
public class FileUtil {
private static String LvLianFilePath = "D:/data/ly_sensor_data";
private static String BaiDuWangPanFilePath = "/禄辉/ly_sensor_data";
private static String tempFilePath = "D:/data";
private static String CRLF = "\r\n";
/**
* 读取绿联云的文件
* @param lvLianFilePath
*/
public static void readLvLianFile(String lvLianFilePath)
{
File file = new File(lvLianFilePath);
if(file.exists())
{
File[] devices = file.listFiles();
if(null != devices && devices.length !=0)
{
for (File device:devices)
{
ScheduledUtil.scheduler.schedule(() -> {
System.out.println("读取到设备数据文件夹:"+device.getAbsolutePath());
File[] sentDevice = device.listFiles();
for (File sentD:sentDevice)
{
ScheduledUtil.scheduler.schedule(() -> {
readLvLianDataFileToBaiduDataFile(sentD);
},0,TimeUnit.SECONDS);
}
},1, TimeUnit.SECONDS);
}
while (ScheduledUtil.scheduler.isShutdown())
{
return;
}
}
}
}
/**
* 创建百度网盘存放路径
* @return
*/
public static String createBaiduWangPanPat(String yea,String deviceType,String imei,String deviceInfoId,String dataType)
{
return new StringBuffer(BaiDuWangPanFilePath).append("/").append(yea).append("/").append(deviceType).append("/").append(imei).append("/").append(deviceInfoId).append("-").append(dataType).append(".csv").toString();
}
/**
* 读取绿联云的数据文件,并且拆分成百度存储的数据文件
*/
public static void readLvLianDataFileToBaiduDataFile(File lvLianDataFile)
{
if(null != lvLianDataFile && lvLianDataFile.exists()&& lvLianDataFile.isFile())
{
String name = lvLianDataFile.getName();
String imei = lvLianDataFile.getParentFile().getName();
String deviceInfoId = name.substring(0,name.indexOf("-"));
String dataType = name.substring(name.indexOf("-")+1,name.indexOf("."));
String deviceType = deviceTypeMap.get(imei);
String time = "";
BufferedReader reader = null;
BufferedWriter bufferedWriter = null;
try {
reader = cn.hutool.core.io.FileUtil.getReader(lvLianDataFile, "UTF-8");
String line;
while (true) {
line = reader.readLine();
if (line == null) {
break;
}
String[] ds = line.split(",");
if(null != ds && ds.length==2)
{
String yea = DateFormatUtils.format(new Date(Integer.valueOf(ds[0])*1000l), "yyyy");
if(!yea.equals(time))
{
time = yea;
String baiduPath = createBaiduWangPanPat(yea,null==deviceType?"device_model":deviceType,imei,deviceInfoId,dataType);
File file = new File(tempFilePath+baiduPath);
bufferedWriter = FileWriter.create(file, CharsetUtil.CHARSET_UTF_8).getWriter(true);
}
if (null != bufferedWriter)
{
bufferedWriter.write(line);
//默认换行符
bufferedWriter.write(CRLF);
bufferedWriter.flush();
}
}
}
} catch (IOException e) {
throw new IORuntimeException(e);
} finally {
IoUtil.close(reader);
IoUtil.close(bufferedWriter);
}
}
}
public static void initDeviceType()
{
try {
List<Entity> list = Db.use().query("select device_model,id from device_host");
if(null != list && list.size() !=0 )
{
for (Entity entity:list)
{
deviceTypeMap.put(entity.getStr("id"),entity.get("device_model","device_model"));
}
}
} catch (SQLException e) {
System.err.println(e);
}
}
static Map<String,String> deviceTypeMap = new HashMap<>();
public static void main(String[] args) {
initDeviceType();
readLvLianFile("D:/data/ly_sensor_data");
}
}
... ...
package com.zhonglai.luhui.data.file.service.util;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
public class ScheduledUtil {
public final static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(20);
}
... ...
url=jdbc:mysql://rm-wz9740un21f09iokuao.mysql.rds.aliyuncs.com:3306/mqtt_broker?useUnicode=true&characterEncoding=utf8&autoReconnect=true
url=jdbc:mysql://rm-wz9740un21f09iokuao.mysql.rds.aliyuncs.com:3306/liu_yu_le?useUnicode=true&characterEncoding=utf8&autoReconnect=true
user = luhui
pass = Luhui586
... ...
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.zhonglai.luhui</groupId>
<artifactId>lh-modules</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>lh-lsy-plc-service</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- spring-boot-devtools -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional> <!-- 表示依赖不会传递 -->
</dependency>
<!-- SpringBoot Web容器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring框架基本的核心工具 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<!-- SpringWeb模块 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<!-- yml解析器 -->
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</dependency>
<!-- servlet包 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
</dependency>
<!-- 文档 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
<exclusions>
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
</exclusion>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--https://mvnrepository.com/artifact/io.swagger/swagger-models-->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>${swagger-models.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
<!--&lt;!&ndash; https://mvnrepository.com/artifact/com.github.xiaoymin/swagger-bootstrap-ui &ndash;&gt;-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>${swagger-ui.version}</version>
</dependency>
<!-- 支持data -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- 阿里JSON解析器 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<!--常用工具类 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!-- 通用工具-->
<dependency>
<groupId>com.zhonglai.luhui</groupId>
<artifactId>lh-domain</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.zhonglai.luhui</groupId>
<artifactId>lh-jar-device-service</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.zhonglai.luhui</groupId>
<artifactId>lh-jar-device-analysis</artifactId>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<finalName>lh-lsy-plc-service</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<!--
生成的jar中,不要包含pom.xml和pom.properties这两个文件
-->
<addMavenDescriptor>false</addMavenDescriptor>
<manifest>
<!--
是否要把第三方jar放到manifest的classpath中
-->
<addClasspath>true</addClasspath>
<!--
生成的manifest中classpath的前缀,因为要把第三方jar放到lib目录下,所以classpath的前缀是lib/
-->
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.zhonglai.luhui.lsy.plc.service.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<!-- The configuration of maven-assembly-plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<descriptors>
<descriptor>src/main/resources/package.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
... ...
package com.zhonglai.luhui.lsy.plc.service;
import com.zhonglai.luhui.lsy.plc.service.dto.DeviceProductProtocol;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan(basePackages = {
"com.zhonglai.luhui.device.analysis.comm.agreement",
"com.zhonglai.luhui.device.analysis.comm.config",
"com.zhonglai.luhui.lsy.plc.service",
})
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class Main {
private static Logger log = LoggerFactory.getLogger(Main.class);
public static void main(String[] args) {
log.info("启动服务");
// System.setProperty("dbPath","E:/work/idea/Luhui/lh-modules/lh-lsy-plc-service/src/main/resources/");
DeviceProductProtocol.init();
SpringApplicationBuilder builder = new SpringApplicationBuilder(Main.class);
builder.run( args);
}
}
\ No newline at end of file
... ...
package com.zhonglai.luhui.lsy.plc.service.comm.service;
import com.alibaba.fastjson.JSONObject;
import com.zhonglai.luhui.device.analysis.dto.ApiName;
import com.zhonglai.luhui.device.analysis.dto.DeviceCommandApiParameter;
import com.zhonglai.luhui.device.analysis.dto.Message;
import com.zhonglai.luhui.device.analysis.dto.MessageCode;
import com.zhonglai.luhui.device.domain.IotDevice;
import com.zhonglai.luhui.device.domain.IotTerminal;
import org.eclipse.paho.client.mqttv3.MqttException;
/**
* 设备指令接口
*/
public class DeviceCommandApi {
private ApiName apiName; //指令接口名称
private DeviceCommandApiParameter deviceCommandApiParameter; //参数
public Message invokeApi(MqttDeviceService deviceService) throws InterruptedException, MqttException {
switch (apiName)
{
// case read:
// return deviceService.read(deviceCommandApiParameter.getClient_id(),deviceCommandApiParameter.getMap());
// case control:
// return deviceService.control(deviceCommandApiParameter.getClient_id(), deviceCommandApiParameter.getMap());
// case controlHex:
// return deviceService.controlHex(deviceCommandApiParameter.getClient_id(),deviceCommandApiParameter.getData());
// case closeSession:
// return deviceService.closeSession(deviceCommandApiParameter.getClient_id());
// case delIotDevice:
// deviceService.closeSession(deviceCommandApiParameter.getClient_id()); //强制下线
// return deviceService.delIotDevice(deviceCommandApiParameter.getClient_id());
// case delIotTerminal:
// deviceService.closeSession(deviceCommandApiParameter.getClient_id()); //强制下线
// return deviceService.delIotTerminal(deviceCommandApiParameter.getClient_id(),deviceCommandApiParameter.getNumber());
// case getFirmwareVersion:
// return deviceService.getFirmwareVersion(deviceCommandApiParameter.getData());
// case updateIotDevice:
// IotDevice iotDevice = JSONObject.parseObject(JSONObject.toJSONString(deviceCommandApiParameter.getMap()), IotDevice.class);
// deviceCommandApiParameter.setClient_id(iotDevice.getClient_id());
// return deviceService.updateIotDevice(iotDevice);
// case updateIotTerminal:
// IotTerminal iotTerminal = JSONObject.parseObject(JSONObject.toJSONString(deviceCommandApiParameter.getMap()), IotTerminal.class);
// deviceCommandApiParameter.setClient_id(iotTerminal.getId());
// return deviceService.updateIotTerminal(iotTerminal);
// case delDeviceHost:
// return deviceService.delDeviceHost(deviceCommandApiParameter.getClient_id());
// case delDeviceInfo:
// deviceCommandApiParameter.setClient_id(deviceCommandApiParameter.getData());
// return deviceService.delDeviceInfo(deviceCommandApiParameter.getData());
// case delDeviceInfoFromDeviceId:
// return deviceService.delDeviceInfoFromDeviceId(deviceCommandApiParameter.getClient_id());
// case transferPond:
// return deviceService.transferPond(deviceCommandApiParameter.getClient_id(),deviceCommandApiParameter.getMap());
// case updateDeviceInfo:
// return deviceService.updateDeviceInfo(deviceCommandApiParameter.getClient_id(),deviceCommandApiParameter.getMap());
default:
return new Message(MessageCode.DEFAULT_FAIL_CODE,"接口不存在");
}
}
public ApiName getApiName() {
return apiName;
}
public void setApiName(ApiName apiName) {
this.apiName = apiName;
}
public DeviceCommandApiParameter getDeviceCommandApiParameter() {
return deviceCommandApiParameter;
}
public void setDeviceCommandApiParameter(DeviceCommandApiParameter deviceCommandApiParameter) {
this.deviceCommandApiParameter = deviceCommandApiParameter;
}
}
... ...
package com.zhonglai.luhui.lsy.plc.service.comm.service;
import com.zhonglai.luhui.device.analysis.comm.dao.BaseDao;
import com.zhonglai.luhui.lsy.plc.service.dto.DeviceInfo;
import com.zhonglai.luhui.lsy.plc.service.dto.LogDeviceOperation;
import com.zhonglai.luhui.lsy.plc.service.dto.OrderDtu;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class DeviceService {
private static BaseDao baseDao = new BaseDao();
/**
* 获取设备
* @param imei
* @return
*/
public OrderDtu getOrderDtu(String imei)
{
Map<String,Object> where = new HashMap<>();
where.put("orderDtuImei",imei);
return (OrderDtu) baseDao.get(OrderDtu.class,where);
}
/**
* 获取设备
* @param id
* @return
*/
public DeviceInfo getDeviceInfo(String id)
{
Map<String,Object> where = new HashMap<>();
where.put("id",id);
return (DeviceInfo) baseDao.get(DeviceInfo.class,where);
}
/**
* 获取设备
* @return
*/
public List<DeviceInfo> getDeviceInfoList(String imei)
{
return baseDao.findBysql("SELECT `id`,alarm_code,data_value,device_service_ip FROM `device_info` WHERE `id` LIKE '%"+imei+"%'", DeviceInfo.class);
}
/**
* 获取设备
* @return
*/
public void upDeviceInfo(DeviceInfo deviceInfo)
{
baseDao.update(deviceInfo);
}
/**
* 获取设备
* @return
*/
public void addloglist(List<LogDeviceOperation> logDeviceOperationList,String tableName)
{
baseDao.insertList(logDeviceOperationList, tableName);
}
}
... ...
package com.zhonglai.luhui.lsy.plc.service.comm.service;
import com.zhonglai.luhui.device.analysis.comm.dto.ServerDto;
import com.zhonglai.luhui.device.analysis.comm.dto.business.BusinessDto;
import com.zhonglai.luhui.device.analysis.comm.dto.business.BusinessDtoClassNew;
import com.zhonglai.luhui.device.analysis.comm.factory.BusinessAgreement;
import com.zhonglai.luhui.device.analysis.comm.factory.BusinessAgreementFactory;
import com.zhonglai.luhui.device.analysis.comm.factory.Topic;
import com.zhonglai.luhui.device.analysis.comm.util.ByteUtil;
import com.zhonglai.luhui.lsy.plc.service.comm.util.TopicUtil;
import com.zhonglai.luhui.lsy.plc.service.dto.AllPostDto;
import com.zhonglai.luhui.lsy.plc.service.dto.DeviceProductProtocol;
import com.zhonglai.luhui.lsy.plc.service.dto.OrderDtu;
import com.zhonglai.luhui.lsy.plc.service.service.PLCDataPersistenceService;
import lombok.SneakyThrows;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class MqttCallback implements MqttCallbackExtended {
private static final Logger log = LoggerFactory.getLogger(MqttCallback.class);
@Autowired
private BusinessAgreementFactory businessAgreementFactory;
@Autowired
private TerminalService terminalService; //客户端服务
@Autowired
private DeviceService deviceService;
@Autowired
private PLCDataPersistenceService plcDataPersistenceService;
@SneakyThrows
@Override
public void connectComplete(boolean b, String s) {
// 连接成功
log.info("连接成功");
terminalService.subscribe();
}
@Override
public void connectionLost(Throwable throwable) {
//连接丢失
log.error("连接丢失",throwable);
}
@Override
public void messageArrived(String s, MqttMessage mqttMessage) {
Topic desttopic = TopicUtil.initTopic(s);
desttopic.setTopicType("POST_REQ");
//接收到消息
StringBuffer buffer = new StringBuffer();
buffer.append("topic:");
buffer.append(s);
buffer.append("\r\n");
buffer.append("mqttMessage字符串:");
buffer.append(mqttMessage.toString());
buffer.append("\r\n");
buffer.append("mqttMessage十六进制:");
buffer.append(ByteUtil.hexStringToSpace(ByteUtil.toHexString(mqttMessage.getPayload())));
buffer.append("\r\n");
buffer.append("\r\n");
try {
Topic topic = TopicUtil.initTopic(s);
if(null == topic)
{
log.error("消息{},topic为空,不做解析");
log.error("消息《"+s+"》解析为空 》》》内容:\r\n"+buffer.toString());
return;
}
//日志记录
log.info(buffer.toString());
//准备数据
byte[] data = mqttMessage.getPayload();
OrderDtu orderDtu = deviceService.getOrderDtu(topic.getClientid());
if(null == orderDtu)
{
log.info("设备dtu{}不存在",topic.getClientid());
return;
}
//转化为协议对象
BusinessDto businessDto = BusinessDtoClassNew.newBean(DeviceProductProtocol.payloadtype,data).analyticalModel(null);
BusinessAgreement businessAgreement = businessAgreementFactory.createBusinessAgreement(topic);
//解析为业务对象
ServerDto dto = businessAgreement.analysis(topic,businessAgreement.toData(businessDto));
if(null == dto)
{
return;
}
log.info("{} 解析到的dto【{}】",dto);
//数据持久化
plcDataPersistenceService.persistence(topic, dto);
log.info("{} payload解析完成",s);
} catch (Exception e) {
log.error(s+"消息解析异常",e);
}
}
@Override
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
// 成功发出消息
try {
log.info("成功发出消息 messageid{}",iMqttDeliveryToken.getMessage());
} catch (MqttException e) {
e.printStackTrace();
}
}
public MqttCallback binldTerminalService(TerminalService terminalService)
{
this.terminalService = terminalService;
return this;
}
}
... ...
package com.zhonglai.luhui.lsy.plc.service.comm.service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zhonglai.luhui.device.analysis.comm.db.DeviceService;
import com.zhonglai.luhui.device.analysis.comm.db.mode.TerminalDataThingsModeService;
import com.zhonglai.luhui.device.analysis.comm.dto.LogDeviceOperation;
import com.zhonglai.luhui.device.analysis.comm.dto.thingsmodels.ThingsModelBase;
import com.zhonglai.luhui.device.analysis.comm.dto.thingsmodels.ThingsModelDataTypeEnum;
import com.zhonglai.luhui.device.analysis.comm.dto.thingsmodels.ThingsModelItemBase;
import com.zhonglai.luhui.device.analysis.comm.factory.Topic;
import com.zhonglai.luhui.device.analysis.comm.service.BusinessDataUpdateService;
import com.zhonglai.luhui.device.analysis.comm.service.CacheServiceImpl;
import com.zhonglai.luhui.device.analysis.comm.service.DataPersistenceServiceImpl;
import com.zhonglai.luhui.device.analysis.comm.service.DeviceLogService;
import com.zhonglai.luhui.device.analysis.comm.util.DateUtils;
import com.zhonglai.luhui.device.analysis.dto.Message;
import com.zhonglai.luhui.device.analysis.dto.MessageCode;
import com.zhonglai.luhui.device.analysis.dto.topic.AddPostDto;
import com.zhonglai.luhui.device.domain.IotThingsModel;
import com.zhonglai.luhui.lsy.plc.service.service.ClienNoticeService;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Service
public class MqttDeviceService {
private static final Logger log = LoggerFactory.getLogger(MqttDeviceService.class);
@Autowired
private ClienNoticeService clienNoticeService;
}
... ...
package com.zhonglai.luhui.lsy.plc.service.comm.service;
import com.zhonglai.luhui.device.analysis.comm.config.SysParameter;
import com.zhonglai.luhui.device.analysis.comm.factory.Topic;
import com.zhonglai.luhui.device.analysis.comm.service.DataModeAnalysisService;
import com.zhonglai.luhui.lsy.plc.service.comm.util.TopicUtil;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 终端服务
*/
@Service
public class TerminalService {
private static final Logger log = LoggerFactory.getLogger(TerminalService.class);
@Autowired
private MqttCallback mqttCallback;
@Autowired
private SysParameter sysParameter;
@Value("${mqtt.broker}")
private String broker;
@Value("${mqtt.clientId}")
private String clientId;
@Value("${mqtt.roleid}")
private String roleid;
@Value("#{'${mqtt.mqtt_usernames}'.split(',')}")
private List<String> mqtt_usernames;
@Value("#{'${mqtt.topics}'.split(',')}")
private List<String> topics;
@Value("${mqtt.username}")
private String username;
@Value("${mqtt.sub_clientid}")
private String sub_clientid;
@Value("${mqtt.password}")
private String password;
@Value("${mqtt.topicconfig}")
private String topicconfig;
private MqttClient mqttclient;
private MqttConnectOptions options;
private void init() throws MqttException {
if(null == mqttclient)
{
mqttclient = new MqttClient(broker, clientId, new MemoryPersistence());
}
options = new MqttConnectOptions();
options.setCleanSession(true);
options.setConnectionTimeout(15);
//设置断开后重新连接
options.setAutomaticReconnect(true);
mqttclient.setCallback(mqttCallback.binldTerminalService(this));
}
private void connect() throws MqttException {
options.setUserName(username);
options.setPassword(password.toCharArray());
mqttclient.connect(options);
}
public void subscribe() throws MqttException {
List<String> ts = getCompletionTopics();
mqttclient.subscribe(ts.toArray(new String[ts.size()]));
}
public List<String> getCompletionTopics()
{
List<String> ts = new ArrayList<>();
for(String mqtt_username:mqtt_usernames)
{
for(String tc:topics)
{
String topic = topicconfig.replace("{{roleid}}",roleid).replace("{{username}}",mqtt_username).replace("{{clientid}}",sub_clientid).replace("{{topicType}}",tc);
ts.add(topic);
}
}
return ts;
}
@PostConstruct
public void startMqttListenerService() throws MqttException {
log.info("-----------开始启动mqtt监听服务--------------------");
init();
log.info("-----------启动参数{}--------------------",options);
sysParameter.inittopicconfig();
log.info("-----------终端数据模型配置成功--------------------");
connect();
log.info("-----------mqtt连接服务器成功--------------------");
subscribe();
log.info("-----------订阅{}:{}成功--------------------",sub_clientid,topics);
}
public void publish(String topic, MqttMessage message) throws MqttException {
mqttclient.publish(topic,message);
}
public void publish(String topic, String messageStr) throws MqttException {
MqttMessage message = new MqttMessage();
message.setPayload(messageStr.getBytes());
mqttclient.publish(topic,message);
}
}
... ...
package com.zhonglai.luhui.lsy.plc.service.comm.util;
import com.zhonglai.luhui.device.analysis.comm.config.SysParameter;
import com.zhonglai.luhui.device.analysis.comm.dto.MyException;
import com.zhonglai.luhui.device.analysis.comm.factory.Topic;
import com.zhonglai.luhui.device.analysis.comm.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Field;
import java.util.Optional;
public class TopicUtil {
private static final Logger log = LoggerFactory.getLogger(TopicUtil.class);
public static Topic initTopic(String topic)
{
topic = Optional.ofNullable(topic).orElseThrow(()->new MyException("topic为空"));
String[] sts = topic.split("/");
String[] config = SysParameter.topicconfig.split("/");
int number = sts.length;
if(number>config.length)
{
number = config.length;
}
Topic topicObject = new Topic();
for(int i=1;i<number;i++)
{
String cf = config[i].replace("{{","").replace("}}","");
try {
Field field = topicObject.getClass().getDeclaredField(cf);
field.setAccessible(true);
field.set(topicObject,sts[i]);
} catch (NoSuchFieldException e) {
log.info("{}生成topic时没有属性{}",topic,cf);
} catch (IllegalAccessException e) {
log.info("{}生成topic时无法给{}赋值{}",topic,cf,sts[i]);
}
}
return topicObject;
}
/**
* 生成缓存关键字
* @return
*/
public static String generateRedicKey(Topic topic)
{
return generate(topic,":");
}
/**
* 生成发送消息的topic
* @return
*/
public static String generateSendMessageTopic(Topic topic)
{
return "/"+generate(topic,"/");
}
/**
* 生成客户端关键字
* @return
*/
public static String generateClienKey(Topic topic)
{
return "/"+generate(topic,"/");
}
private static String generate(Topic topic,String division)
{
String str = SysParameter.topicconfig;
if(StringUtils.isEmpty(topic.getRoleid()))
{
topic.setRoleid("2");
}
str = str.replace("/{{roleid}}",topic.getRoleid()+division);
if(StringUtils.isEmpty(topic.getUsername()))
{
topic.setUsername("+");
}
str = str.replace("/{{username}}",topic.getUsername()+division);
if(StringUtils.isEmpty(topic.getClientid()))
{
topic.setClientid( "+");
}
str = str.replace("/{{clientid}}",topic.getClientid()+division);
if(StringUtils.isEmpty(topic.getPayloadtype()))
{
topic.setPayloadtype( "String");
}
str = str.replace("/{{payloadtype}}",topic.getPayloadtype()+division);
if(StringUtils.isEmpty(topic.getTopicType()))
{
topic.setTopicType("PUT");
}
str = str.replace("/{{topicType}}",topic.getTopicType()+division);
if(StringUtils.isNotEmpty(topic.getMessageid()))
{
str = str.replace("/{{messageid}}",topic.getMessageid());
}
if (str.endsWith("/"))
{
str = str.substring(0,str.lastIndexOf("/"));
}
return str;
}
}
... ...
package com.zhonglai.luhui.lsy.plc.service.config;
import io.swagger.annotations.ApiOperation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
.paths(PathSelectors.any())
.build();
}
/**
* 添加摘要信息
*/
private ApiInfo apiInfo()
{
// 用ApiInfoBuilder进行定制
return new ApiInfoBuilder()
// 设置标题
.title("标题:流水鱼plc")
// 描述
.description("描述:用于通过mqtt转发流水鱼plc指令控制终端端操作")
// 作者信息
.contact(new Contact("", null, null))
// 版本
.version("版本号:1.1.1" )
.build();
}
}
\ No newline at end of file
... ...
package com.zhonglai.luhui.lsy.plc.service.controller;
import com.alibaba.fastjson.JSON;
import com.google.gson.JsonObject;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.GsonConstructor;
import com.zhonglai.luhui.device.analysis.comm.factory.Topic;
import com.zhonglai.luhui.device.analysis.comm.util.ByteUtil;
import com.zhonglai.luhui.device.analysis.comm.util.StringUtils;
import com.zhonglai.luhui.device.analysis.comm.util.TableUtil;
import com.zhonglai.luhui.device.analysis.dto.Message;
import com.zhonglai.luhui.device.analysis.dto.MessageCode;
import com.zhonglai.luhui.device.domain.IotDevice;
import com.zhonglai.luhui.device.domain.IotTerminal;
import com.zhonglai.luhui.lsy.plc.service.comm.service.DeviceService;
import com.zhonglai.luhui.lsy.plc.service.comm.service.MqttDeviceService;
import com.zhonglai.luhui.lsy.plc.service.comm.service.TerminalService;
import com.zhonglai.luhui.lsy.plc.service.comm.util.TopicUtil;
import com.zhonglai.luhui.lsy.plc.service.dto.*;
import com.zhonglai.luhui.lsy.plc.service.service.ClienNoticeService;
import com.zhonglai.luhui.lsy.plc.service.service.topic.AllPostTopic;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Api(tags = "设备操作")
@RestController
@RequestMapping("/device")
public class DeviceController {
private static final Logger log = LoggerFactory.getLogger(DeviceController.class);
@Autowired
private ClienNoticeService clienNoticeService;
@Autowired
private DeviceService deviceService;
@ApiOperation("获取一天的日志")
@ApiImplicitParams({
@ApiImplicitParam(value = "设备号",name = "deviceId"),
@ApiImplicitParam(value = "数据",name = "dataObject"),
@ApiImplicitParam(value = "地址位",name = "addressBits"),
@ApiImplicitParam(value = "设备表id",name = "deviceInfoId")
})
@RequestMapping(value = "write/{deviceInfoId}",method = RequestMethod.POST)
public Message write(@PathVariable String deviceInfoId, @RequestBody DeviceControlMessage deviceControlMessage)
{
log.info("控制指令{}",deviceControlMessage);
Map<String,Object> data = deviceControlMessage.getDataObject();
if (null == data)
{
return new Message(MessageCode.DEFAULT_FAIL_CODE,"没有参数");
}
if ( !(data.containsKey("type") && data.get("type").toString().equals("kaiguan")))
{
return new Message(MessageCode.DEFAULT_FAIL_CODE,"只支持开关控制");
}
DeviceInfo deviceInfo = deviceService.getDeviceInfo(deviceInfoId);
Topic topic = new Topic("2",deviceInfo.getDevice_type(),deviceControlMessage.getDeviceId(),"PUT",null);
List<DeviceDataConfig> list = DeviceProductProtocol.deviceDataWriteConfigList;
if(null == list)
{
return new Message(MessageCode.DEFAULT_FAIL_CODE,"该设备未配置请联系管理员");
}
Map<String,Object> map = new HashMap<>();
//记录日志
for (DeviceDataConfig deviceDataConfig:list)
{
if(deviceDataConfig.getSensor_numer().equals(deviceControlMessage.getAddressBits()) && deviceDataConfig.getPlc_data_type().sensorDataType.equals("3") )
{
//记录日志
map.put(deviceDataConfig.getAttribute_name(), data.get("value").toString().equals(deviceDataConfig.getAlarmValue())?1:0);
}
}
try {
MqttMessage mqttMessage = new MqttMessage();
mqttMessage.setPayload(JSON.toJSONString(map).trim().getBytes());
Message message = clienNoticeService.sendMessage(topic,mqttMessage);
if(message.getCode()==1)
{
JsonObject rmap = new JsonObject();
rmap.addProperty("3",data.get("value").toString());
rmap.addProperty("9","01");
message.setData(rmap.toString());
DeviceInfo deviceInfo1 = new DeviceInfo();
deviceInfo1.setId(deviceInfoId);
JsonObject object = new JsonObject();
if(StringUtils.isNotEmpty(deviceInfo.getDataValue()))
{
object = GsonConstructor.get().fromJson(deviceInfo.getDataValue(),JsonObject.class);
}
object.addProperty("3",data.get("value").toString());
deviceInfo1.setDataValue(object.toString());
deviceService.upDeviceInfo(deviceInfo1);
LogDeviceOperation logDeviceOperation = addLogDeviceOperation(topic.getClientid(),deviceControlMessage.getAddressBits(),null,"设备远程"+("01".equals(data.get("value").toString())?"开启":"关闭"),data.get("value").toString(),deviceInfo.getDataValue(),1);
List<LogDeviceOperation> list1 = new ArrayList<>();
list1.add(logDeviceOperation);
deviceService.addloglist(list1,
TableUtil.getNowTableName("runing_fish_device_operation","log_device_operation",3));
}
return message;
} catch (MqttException e) {
log.error("指令转发失败",e);
return new Message(MessageCode.DEFAULT_FAIL_CODE,"指令转发失败");
} catch (InterruptedException e) {
log.error("指令转发失败",e);
return new Message(MessageCode.DEFAULT_FAIL_CODE,"指令转发失败");
}
}
/**
* 添加设备操作日志记录
* @param deviceId 设备imei
* @param sensorNum 传感器或控制器编号
* @param operationInstruction 设备操作指令
* @param describe 设备操作描述
* @param newState 设备操作后的状态
* @param isStateChange 是否有状态改变(0否,1是)
*/
protected LogDeviceOperation addLogDeviceOperation(String deviceId, String sensorNum, String operationInstruction, String describe, String newState, String oldState, Integer isStateChange)
{
//更新设备操作日志记录
LogDeviceOperation logDeviceOperation = new LogDeviceOperation();
logDeviceOperation.setDeviceId(deviceId);
logDeviceOperation.setSensorOrController(sensorNum);
logDeviceOperation.setDeviceOperationTime(DateUtils.getNowTimeMilly());
logDeviceOperation.setOperationInstruction(operationInstruction);
logDeviceOperation.setOperationDescribe(describe);
logDeviceOperation.setDeviceNewState(newState);
logDeviceOperation.setDeviceOldState(oldState);
logDeviceOperation.setDeviceOperationType("-1");
logDeviceOperation.setIsStateChange(isStateChange);
return logDeviceOperation ;
}
}
... ...
package com.zhonglai.luhui.lsy.plc.service.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.util.IOUtils;
import com.zhonglai.luhui.device.analysis.comm.util.DateUtils;
import com.zhonglai.luhui.device.analysis.dto.Message;
import com.zhonglai.luhui.device.analysis.dto.MessageCode;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Date;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@Api(tags = "设备操作")
@Controller
@RequestMapping("/log")
public class LogController {
@ApiOperation("获取一天的日志")
@ApiImplicitParams({
@ApiImplicitParam(value = "时间(格式:20230114)",name = "time"),
@ApiImplicitParam(value = "设备imei",name = "imei"),
})
@RequestMapping(value = "getOneDateLog/{imei}/{time}",method = RequestMethod.GET)
public void getOneDateLog(HttpServletResponse response, @PathVariable String imei, @PathVariable String time) throws IOException {
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Type","text/html;charset=utf-8");
PrintWriter printWriter = response.getWriter();
String dateString = DateUtils.parseDateToStr("yyyyMMdd",new Date());
String fileName= imei+"_"+time+".log";
if(dateString.equals(time))
{
File logsFile = new File("logs/"+fileName);
if (!logsFile.exists())
{
printWriter.println(JSON.toJSONString(new Message(MessageCode.DEFAULT_FAIL_CODE,"文件"+logsFile.getPath()+"不存在")));
}
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(logsFile));
String line;
while((line = reader.readLine()) != null){
printWriter.println(line);
printWriter.println("<br/>");
}
} catch (IOException e) {
e.printStackTrace();
}finally {
IOUtils.close(printWriter);
IOUtils.close(reader);
}
}
File logsFile = new File("zip/"+time+".zip");
BufferedReader reader = null;
try {
ZipFile zipFile = new ZipFile(logsFile);
reader = new BufferedReader(new InputStreamReader(zipFile.getInputStream(new ZipEntry(fileName))));
String line;
while((line = reader.readLine()) != null)
{
printWriter.println(line);
printWriter.println("<br/>");
}
} catch (IOException e) {
printWriter.println(JSON.toJSONString(new Message(MessageCode.DEFAULT_FAIL_CODE,e.getMessage())));
}finally {
IOUtils.close(printWriter);
IOUtils.close(reader);
}
}
}
... ...
package com.zhonglai.luhui.lsy.plc.service.dto;
import com.alibaba.fastjson.JSONObject;
import com.zhonglai.luhui.device.analysis.comm.dto.ServerDto;
import java.util.List;
public class AllPostDto extends ServerDto {
private List<DeviceInfo> deviceInfoList;
private JSONObject data;
public JSONObject getData() {
return data;
}
public void setData(JSONObject data) {
this.data = data;
}
public List<DeviceInfo> getDeviceInfoList() {
return deviceInfoList;
}
public void setDeviceInfoList(List<DeviceInfo> deviceInfoList) {
this.deviceInfoList = deviceInfoList;
}
}
... ...
package com.zhonglai.luhui.lsy.plc.service.dto;
import com.google.gson.JsonObject;
import java.util.Map;
/**
* plc控制请求消息体
* Created by zhonglai on 2016/12/30.
*/
public class DeviceControlMessage {
private String deviceId; //设备号
private String addressBits; //地址位
private String commandWord; //命令字
private Map<String,Object> dataObject; //数据
private String commandTye ; //指令类型
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public String getAddressBits() {
return addressBits;
}
public void setAddressBits(String addressBits) {
this.addressBits = addressBits;
}
public String getCommandWord() {
return commandWord;
}
public void setCommandWord(String commandWord) {
this.commandWord = commandWord;
}
public Map<String, Object> getDataObject() {
return dataObject;
}
public void setDataObject(Map<String, Object> dataObject) {
this.dataObject = dataObject;
}
public String getCommandTye() {
return commandTye;
}
public void setCommandTye(String commandTye) {
this.commandTye = commandTye;
}
}
... ...
package com.zhonglai.luhui.lsy.plc.service.dto;
import lombok.Data;
@Data
public class DeviceDataConfig {
private Integer number;
private String attribute_name;
private String address_bit;
private PLCType device_type;
private String sensor_numer;
private String attribute_describe;
private PLCDataType plc_data_type;
private String alarmCode;
private String alarmValue;
public DeviceDataConfig()
{
}
public DeviceDataConfig(Integer number, String attribute_name, String address_bit, PLCType device_type, PLCDataType plc_data_type,String sensor_numer,String attribute_describe) {
this.number = number;
this.attribute_name = attribute_name;
this.address_bit = address_bit;
this.device_type = device_type;
this.plc_data_type = plc_data_type;
this.sensor_numer = sensor_numer;
this.attribute_describe = attribute_describe;
}
public DeviceDataConfig(Integer number, String attribute_name, String address_bit, PLCType device_type, PLCDataType plc_data_type,String sensor_numer,String attribute_describe,String alarmCode,String alarmValue) {
this.number = number;
this.attribute_name = attribute_name;
this.address_bit = address_bit;
this.device_type = device_type;
this.plc_data_type = plc_data_type;
this.sensor_numer = sensor_numer;
this.attribute_describe = attribute_describe;
this.alarmCode = alarmCode;
this.alarmValue = alarmValue;
}
public String getDeviceInfoId(String imei)
{
if("00".equals(sensor_numer))
{
return imei;
}
return imei+"_"+sensor_numer;
}
}
... ...
package com.zhonglai.luhui.lsy.plc.service.dto;
import lombok.Data;
/**
* @Author: fuchao
* @Description :设备信息表
* @Date: Created in 22:05 2016/12/7
*/
@Data
public class DeviceInfo {
private String id; //设备主键ID(设备IMEI号加编号)
private String dataValue; //数据值(json字符串)
private String alarmCode; //告警代码(正常-00)
private String online; //设备在线状态(00-不在线,01-在线)
private Integer dataUpdateTime; //更新时间
private String deviceServiceIp; //设备服务器IP
private String device_type; //设备类型
}
... ...
package com.zhonglai.luhui.lsy.plc.service.dto;
import lombok.Data;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 产品协议
*/
public class DeviceProductProtocol {
public static String payloadtype = "Json";
public static List<DeviceDataConfig> deviceDataConfigList = new ArrayList<>();
public static List<DeviceDataConfig> deviceDataWriteConfigList = new ArrayList<>();
public static void init()
{
deviceDataConfigList.add(new DeviceDataConfig(1,"C001A_RUN","I0.0",PLCType.推水机,PLCDataType.控制器状态码,"01","运行信号"));
deviceDataConfigList.add(new DeviceDataConfig(2,"C001A_ALARM","I0.1",PLCType.推水机,PLCDataType.故障代码,"01","故障信号","11","01"));
deviceDataConfigList.add(new DeviceDataConfig(3,"C001B_RUN","I0.2",PLCType.推水机,PLCDataType.控制器状态码,"02","运行信号"));
deviceDataConfigList.add(new DeviceDataConfig(4,"C001B_ALARM","I0.3",PLCType.推水机,PLCDataType.故障代码,"02","故障信号","11","01"));
deviceDataConfigList.add(new DeviceDataConfig(5,"C001C_RUN","I0.4",PLCType.推水机,PLCDataType.控制器状态码,"03","运行信号"));
deviceDataConfigList.add(new DeviceDataConfig(6,"C001C_ALARM","I0.5",PLCType.推水机,PLCDataType.故障代码,"03","故障信号","11","01"));
deviceDataConfigList.add(new DeviceDataConfig(7,"C002_RUN","I0.6",PLCType.增氧机,PLCDataType.控制器状态码,"34","运行信号"));
deviceDataConfigList.add(new DeviceDataConfig(8,"C002_ALARM","I0.7",PLCType.增氧机,PLCDataType.故障代码,"34","故障信号","11","01"));
deviceDataConfigList.add(new DeviceDataConfig(9,"P001A_RUN","I1.0",PLCType.排污,PLCDataType.控制器状态码,"21","运行信号"));
deviceDataConfigList.add(new DeviceDataConfig(10,"P001A_ALARM","I1.1",PLCType.排污,PLCDataType.故障代码,"21","故障信号","11","01"));
deviceDataConfigList.add(new DeviceDataConfig(11,"P001B_RUN","I1.2",PLCType.排污,PLCDataType.控制器状态码,"22","运行信号"));
deviceDataConfigList.add(new DeviceDataConfig(12,"P001B_ALARM","I1.3",PLCType.排污,PLCDataType.故障代码,"22","故障信号","11","01"));
deviceDataConfigList.add(new DeviceDataConfig(13,"P001C_RUN","I1.4",PLCType.排污,PLCDataType.控制器状态码,"23","运行信号"));
deviceDataConfigList.add(new DeviceDataConfig(14,"P001C_ALARM","I1.5",PLCType.排污,PLCDataType.控制器状态码,"23","故障信号","11","01"));
deviceDataConfigList.add(new DeviceDataConfig(15,"SD_RUN","I1.6",null,PLCDataType.故障代码,"00","市电供电信号","12","00"));
deviceDataConfigList.add(new DeviceDataConfig(16,"FD_RUN","I1.7",null,PLCDataType.故障代码,"00","发电供电信号","13","01"));
deviceDataConfigList.add(new DeviceDataConfig(17,"DY_ALARM","I2.0",null,PLCDataType.故障代码,"00","电源故障信号","51","01"));
deviceDataConfigList.add(new DeviceDataConfig(18,"SYS_AUTO","I2.1",null,PLCDataType.控制柜状态,"00","系统自动允许"));
deviceDataConfigList.add(new DeviceDataConfig(26,"TX_RUN","M0.0",null,PLCDataType.故障代码,"00","远程通讯正常","01","00"));
deviceDataConfigList.add(new DeviceDataConfig(41,"SYS_ALARM","M1.7",null,PLCDataType.故障代码,"00","设备故障报警","01","01"));
deviceDataWriteConfigList.add(new DeviceDataConfig(27,"YC_ST_C001A","M0.1",PLCType.推水机,PLCDataType.控制器状态码,"01","远程启动按钮",null,"01"));
deviceDataWriteConfigList.add(new DeviceDataConfig(28,"YC_STP_C001A","M0.2",PLCType.推水机,PLCDataType.控制器状态码,"01","远程停止按钮",null,"00"));
deviceDataWriteConfigList.add(new DeviceDataConfig(29,"YC_ST_C001B","M0.3",PLCType.推水机,PLCDataType.控制器状态码,"02","远程启动按钮",null,"01"));
deviceDataWriteConfigList.add(new DeviceDataConfig(30,"YC_STP_C001B","M0.4",PLCType.推水机,PLCDataType.控制器状态码,"02","远程停止按钮",null,"00"));
deviceDataWriteConfigList.add(new DeviceDataConfig(31,"YC_ST_C001C","M0.5",PLCType.推水机,PLCDataType.控制器状态码,"03","远程启动按钮",null,"01"));
deviceDataWriteConfigList.add(new DeviceDataConfig(32,"YC_STP_C001C","M0.6",PLCType.推水机,PLCDataType.控制器状态码,"03","远程停止按钮",null,"00"));
deviceDataWriteConfigList.add(new DeviceDataConfig(33,"YC_ST_C002","M0.7",PLCType.增氧机,PLCDataType.控制器状态码,"34","远程启动按钮",null,"01"));
deviceDataWriteConfigList.add(new DeviceDataConfig(34,"YC_STP_C002","M1.9",PLCType.增氧机,PLCDataType.控制器状态码,"34","远程停止按钮",null,"00"));
deviceDataWriteConfigList.add(new DeviceDataConfig(35,"YC_ST_P001A","M1.1",PLCType.排污,PLCDataType.控制器状态码,"21","远程启动按钮",null,"01"));
deviceDataWriteConfigList.add(new DeviceDataConfig(36,"YC_STP_P001A","M1.2",PLCType.排污,PLCDataType.控制器状态码,"21","远程停止按钮",null,"00"));
deviceDataWriteConfigList.add(new DeviceDataConfig(37,"YC_ST_P001B","M1.3",PLCType.排污,PLCDataType.控制器状态码,"22","远程启动按钮",null,"01"));
deviceDataWriteConfigList.add(new DeviceDataConfig(38,"YC_STP_P001B","M1.4",PLCType.排污,PLCDataType.控制器状态码,"22","远程停止按钮",null,"00"));
deviceDataWriteConfigList.add(new DeviceDataConfig(39,"YC_ST_P001C","M1.5",PLCType.排污,PLCDataType.控制器状态码,"23","远程启动按钮",null,"01"));
deviceDataWriteConfigList.add(new DeviceDataConfig(40,"YC_STP_P001C","M1.6",PLCType.排污,PLCDataType.控制器状态码,"23","远程停止按钮",null,"00"));
}
}
... ...
package com.zhonglai.luhui.lsy.plc.service.dto;
/**
* @Author: fuchao
* @Description :设备操作日志记录表
* @Date: Created in 16:57 2016/12/27
*/
public class LogDeviceOperation {
private Integer deviceOperationId; //设备操作日志id
private String deviceId; //设备id
private Integer deviceOperationTime; //设备操作时间
private String operationInstruction; //设备操作指令
private String operationDescribe; //设备操作描述
private String deviceOldState; //设备操作前状态
private String deviceNewState; //设备操作后的状态
private String deviceOperationType; //设备操作类型
private String sensorOrController; //传感器或控制器编号(控制器以00_开头)
private Integer isStateChange; //是否有状态改变(0否,1是)
public Integer getDeviceOperationId() {
return deviceOperationId;
}
public void setDeviceOperationId(Integer deviceOperationId) {
this.deviceOperationId = deviceOperationId;
}
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public Integer getDeviceOperationTime() {
return deviceOperationTime;
}
public void setDeviceOperationTime(Integer deviceOperationTime) {
this.deviceOperationTime = deviceOperationTime;
}
public String getOperationInstruction() {
return operationInstruction;
}
public void setOperationInstruction(String operationInstruction) {
this.operationInstruction = operationInstruction;
}
public String getOperationDescribe() {
return operationDescribe;
}
public void setOperationDescribe(String operationDescribe) {
this.operationDescribe = operationDescribe;
}
public String getDeviceOldState() {
return deviceOldState;
}
public void setDeviceOldState(String deviceOldState) {
this.deviceOldState = deviceOldState;
}
public String getDeviceNewState() {
return deviceNewState;
}
public void setDeviceNewState(String deviceNewState) {
this.deviceNewState = deviceNewState;
}
public String getDeviceOperationType() {
return deviceOperationType;
}
public void setDeviceOperationType(String deviceOperationType) {
this.deviceOperationType = deviceOperationType;
}
public String getSensorOrController() {
return sensorOrController;
}
public void setSensorOrController(String sensorOrController) {
this.sensorOrController = sensorOrController;
}
public Integer getIsStateChange() {
return isStateChange;
}
public void setIsStateChange(Integer isStateChange) {
this.isStateChange = isStateChange;
}
}
... ...
package com.zhonglai.luhui.lsy.plc.service.dto;
/**
* @Author: fuchao
* @Description :设备DTU表
* @Date: Created in 10:26 2016/12/25
*/
public class OrderDtu {
private Integer orderDtuId; //dtu主键
private String orderDtuImei; //设备的imei
private String orderDtuSim; //卡号
private String deviceType; //设备类型
private Integer orderDtuCreateTime; //记录时间
private Integer userLoginId; //登录表主键id(数据级联登录表插入)
private String userLoginName; //登录名(唯一,数据级联登录表插入)
private Integer purchaseGoodsId; //采购商品id
private Integer purchaseId; //采购id
private String orderDtuSimId; //sim卡id编号
private Integer orderDtuState; //设备库存状态(0库存,1销售,2售后)
private Integer orderWorkState; //设备工作状态(0正常,1异常)
public Integer getOrderDtuId() {
return orderDtuId;
}
public void setOrderDtuId(Integer orderDtuId) {
this.orderDtuId = orderDtuId;
}
public String getOrderDtuImei() {
return orderDtuImei;
}
public void setOrderDtuImei(String orderDtuImei) {
this.orderDtuImei = orderDtuImei;
}
public String getOrderDtuSim() {
return orderDtuSim;
}
public void setOrderDtuSim(String orderDtuSim) {
this.orderDtuSim = orderDtuSim;
}
public String getDeviceType() {
return deviceType;
}
public void setDeviceType(String deviceType) {
this.deviceType = deviceType;
}
public Integer getOrderDtuCreateTime() {
return orderDtuCreateTime;
}
public void setOrderDtuCreateTime(Integer orderDtuCreateTime) {
this.orderDtuCreateTime = orderDtuCreateTime;
}
public Integer getUserLoginId() {
return userLoginId;
}
public void setUserLoginId(Integer userLoginId) {
this.userLoginId = userLoginId;
}
public String getUserLoginName() {
return userLoginName;
}
public void setUserLoginName(String userLoginName) {
this.userLoginName = userLoginName;
}
public Integer getPurchaseGoodsId() {
return purchaseGoodsId;
}
public void setPurchaseGoodsId(Integer purchaseGoodsId) {
this.purchaseGoodsId = purchaseGoodsId;
}
public Integer getPurchaseId() {
return purchaseId;
}
public void setPurchaseId(Integer purchaseId) {
this.purchaseId = purchaseId;
}
public String getOrderDtuSimId() {
return orderDtuSimId;
}
public void setOrderDtuSimId(String orderDtuSimId) {
this.orderDtuSimId = orderDtuSimId;
}
public Integer getOrderDtuState() {
return orderDtuState;
}
public void setOrderDtuState(Integer orderDtuState) {
this.orderDtuState = orderDtuState;
}
public Integer getOrderWorkState() {
return orderWorkState;
}
public void setOrderWorkState(Integer orderWorkState) {
this.orderWorkState = orderWorkState;
}
}
... ...
package com.zhonglai.luhui.lsy.plc.service.dto;
/**
* 数据类型
*/
public enum PLCDataType {
温度("0"),
溶氧("1"),
故障代码("2"),
控制器状态码("3"),
气压("5"),
气温("4"),
控制器模式("6"),
氨氮("7"),
PH("8"),
控制柜状态("9");
public String sensorDataType;
PLCDataType(String sensorDataType)
{
this.sensorDataType = sensorDataType;
}
}
... ...
package com.zhonglai.luhui.lsy.plc.service.dto;
public enum PLCType {
鱼儿乐(0),
喂料机(1),
增氧机(2),
排污(3),
曝气(4),
流量计(5),
水位计(6),
推水机(7),
备用(8);
private Integer device_terminal_type_key;
PLCType(Integer device_terminal_type_key)
{
this.device_terminal_type_key = device_terminal_type_key;
}
public Integer getDevice_terminal_type_key() {
return device_terminal_type_key;
}
}
... ...
package com.zhonglai.luhui.lsy.plc.service.dto;
import com.zhonglai.luhui.device.analysis.comm.dto.ServerDto;
import lombok.Data;
@Data
public class PutReqDto extends ServerDto {
private String result;
private String time;
private String msg;
}
... ...
package com.zhonglai.luhui.lsy.plc.service.service;
import com.zhonglai.luhui.device.analysis.comm.clien.ClienConnection;
import com.zhonglai.luhui.device.analysis.comm.clien.impl.ClienConnectionImpl;
import com.zhonglai.luhui.device.analysis.comm.dto.ApiClientRePlyDto;
import com.zhonglai.luhui.device.analysis.comm.dto.TerminalClientRePlyDto;
import com.zhonglai.luhui.device.analysis.comm.factory.Topic;
import com.zhonglai.luhui.device.analysis.comm.util.ByteUtil;
import com.zhonglai.luhui.device.analysis.dto.Message;
import com.zhonglai.luhui.lsy.plc.service.comm.service.TerminalService;
import com.zhonglai.luhui.lsy.plc.service.comm.util.TopicUtil;
import net.jodah.expiringmap.ExpirationListener;
import net.jodah.expiringmap.ExpirationPolicy;
import net.jodah.expiringmap.ExpiringMap;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* 客户端通知服务
*/
@Service
public class ClienNoticeService {
private static final Logger log = LoggerFactory.getLogger(ClienNoticeService.class);
@Autowired
private TerminalService terminalService;
@Value("${mqtt.client.operationTime}")
private long operationTime; //客户端操作时间
// maxSize: 设置最大值,添加第11个entry时,会导致第1个立马过期(即使没到过期时间)
// expiration:设置每个key有效时间10s, 如果key不设置过期时间,key永久有效。
// variableExpiration: 允许更新过期时间值,如果不设置variableExpiration,不允许后面更改过期时间,一旦执行更改过期时间操作会抛异常UnsupportedOperationException
// policy:
// CREATED: 只在put和replace方法清零过期时间
// ACCESSED: 在CREATED策略基础上增加, 在还没过期时get方法清零过期时间。
// 清零过期时间也就是重置过期时间,重新计算过期时间.
private static ExpiringMap<String, ClienConnection> clienConnectionMap = ExpiringMap.builder().maxSize(20000).expiration(15, TimeUnit.SECONDS)
.asyncExpirationListener(new ExpirationListener<String, ClienConnection>() {
@Override
public void expired(String s, ClienConnection clienConnection) {
log.info("{} 通道消失了>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>",s);
clienConnection.close();
}
})
.expirationPolicy(ExpirationPolicy.CREATED).build();
@Value("#{${mqtt.top_return_map}}")
private Map<String,String> top_return_map; //topic返回的对应关系
public Message sendMessage(Topic topic, MqttMessage mqttMessage) throws MqttException, InterruptedException {
//设置通知渠道
ClienConnection clienConnection = new ClienConnectionImpl();
String key = TopicUtil.generateClienKey(topic).replace(topic.getTopicType(),top_return_map.get(topic.getTopicType()));
log.info("设置通知渠道 {} {}",key,clienConnection);
clienConnectionMap.put(key,clienConnection);
sendMessage(TopicUtil.generateSendMessageTopic(topic),mqttMessage);
synchronized(clienConnection)
{
log.info("{}等待通知",topic.getClientid());
clienConnection.wait(operationTime*1000+3000l);
}
//清楚通道
clienConnectionMap.remove(key);
log.info("{}收到通知{}",topic.getClientid(),clienConnection.getReplyMessage().getMessage());
Message message = clienConnection.getReplyMessage();
log.info("{}返回通知{}",topic.getClientid(),message);
return message;
}
/**
* 发送消息
* @param mqttMessage
* @throws MqttException
* @throws InterruptedException
*/
public void sendMessage(String topic,MqttMessage mqttMessage) throws MqttException, InterruptedException {
//发生指令,等待通知
log.info(topic+"发送的消息内容"+ ByteUtil.hexStringToSpace(ByteUtil.toHexString(mqttMessage.getPayload()).toUpperCase())+" 转化为字符串:"+new String(mqttMessage.getPayload()));
terminalService.publish(topic,mqttMessage);
}
public ClienConnection getClienConnection(Topic topic)
{
return clienConnectionMap.get(TopicUtil.generateClienKey(topic));
}
/**
* 通知给api操作端
* @param topic
* @param apiClientRePlyDto
*/
public void replySendMessage(Topic topic, ApiClientRePlyDto apiClientRePlyDto)
{
log.info("开始通知{},数据:{}",topic,apiClientRePlyDto);
//判断有没有需要回复的客户端,如果有就回复
ClienConnection clienConnection = getClienConnection(topic);
if(null != clienConnection)
{
synchronized(clienConnection)
{
log.info("正在通知{},通知结果{}",topic,apiClientRePlyDto);
clienConnection.reply(apiClientRePlyDto);
}
}
log.info("结束通知{}",topic);
}
/**
* 通知给下位机终端
* @param topic
* @param terminalClientRePlyDto
* @throws MqttException
*/
public void replyTerminalMessage(Topic topic, TerminalClientRePlyDto terminalClientRePlyDto) throws MqttException {
String tc = terminalClientRePlyDto.getReplyCommdTopic(topic);
MqttMessage mqttMessage = new MqttMessage();
mqttMessage.setPayload(terminalClientRePlyDto.getCommd());
log.info("回复终端{}的消息{}",tc,new String(mqttMessage.getPayload()));
terminalService.publish(terminalClientRePlyDto.getReplyCommdTopic(topic),mqttMessage);
}
}
... ...
package com.zhonglai.luhui.lsy.plc.service.service;
import com.zhonglai.luhui.device.analysis.comm.util.DateUtils;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import java.io.*;
import java.util.Calendar;
import java.util.Date;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@Configuration //1.主要用于标记配置类,兼备Component的效果。
@EnableScheduling // 2.开启定时任务
public class LogTask {
public static void main(String[] args) {
LogTask logTask = new LogTask();
logTask.pack();
}
//每天凌晨1点钟,打包日志
@Scheduled(cron = "0 0 1 * * ?")
private void pack() {
File logsFile = new File("logs/");
if(logsFile.exists() )
{
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
cal.add(Calendar.DATE,-1);
String dateString = DateUtils.parseDateToStr("yyyyMMdd",cal.getTime());
String logfilename = "_"+ dateString +".log";
String[] files = logsFile.list((dir, name) -> {
if(name.indexOf(logfilename)>=0)
{
return true;
}
return false;
});
if(null != files && files.length != 0 )
{
String savePath = "zip/"+dateString+".zip";
File saveFile = new File(savePath);
if(!saveFile.getParentFile().exists())
{
saveFile.getParentFile().mkdirs();
}
batchZip(saveFile,logsFile.getPath(),files);
for(String fp:files)
{
new File(logsFile.getPath()+"/"+fp).delete();
}
}
}
}
//每天凌晨2点钟,删除30天之前的压缩包
@Scheduled(cron = "0 0 2 * * ?")
private void del()
{
File logsFile = new File("zip/");
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
cal.add(Calendar.DATE,-30);
String dateString = DateUtils.parseDateToStr("yyyyMMdd",cal.getTime());
String[] files = logsFile.list((dir, name) -> {
if(name.compareTo(dateString)<=0)
{
return true;
}
return false;
});
if(null != files && files.length != 0 )
{
for(String fp:files)
{
new File(logsFile.getPath()+"/"+fp).delete();
}
}
}
/**
* 批量压缩
* @param saveFile 压缩文件保存地址
* @param files 被压缩文件地址列表
*/
private void batchZip(File saveFile,String path,String[] files)
{
ZipOutputStream zip = null;
try {
zip = new ZipOutputStream(new FileOutputStream(saveFile));
for(String filepath:files)
{
zip(zip,path+"/"+filepath);
}
zip.finish();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(null != zip)
{
try {
zip.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 压缩
* @param zip 压缩文件流
* @param filepath 被压缩文件地址
* @throws IOException
*/
private void zip( ZipOutputStream zip,String filepath) throws IOException {
String[] fss = filepath.split("\\/");
zip.putNextEntry(new ZipEntry(fss[fss.length-1]));
//用字节方式读取源文件
InputStream is = null;
BufferedInputStream bis = null;
try {
is = new FileInputStream(filepath);
//创建一个缓存区
bis = new BufferedInputStream(is);
//字节数组,每次读取1024个字节
byte[] b = new byte[1024];
//循环读取,边读边写
while (bis.read(b) != -1) {
//写入压缩文件
zip.write(b);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭流
if(null != bis)
{
bis.close();
}
if(null != is)
{
is.close();
}
}
}
}
... ...
package com.zhonglai.luhui.lsy.plc.service.service;
import com.ruoyi.common.utils.GsonConstructor;
import com.zhonglai.luhui.device.analysis.comm.dao.BaseDao;
import com.zhonglai.luhui.device.analysis.comm.dto.DeviceSensorData;
import com.zhonglai.luhui.device.analysis.comm.dto.ServerDto;
import com.zhonglai.luhui.device.analysis.comm.factory.Topic;
import com.zhonglai.luhui.device.analysis.comm.util.TableUtil;
import com.zhonglai.luhui.lsy.plc.service.dto.AllPostDto;
import com.zhonglai.luhui.lsy.plc.service.dto.DeviceInfo;
import com.zhonglai.luhui.lsy.plc.service.dto.LogDeviceOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class PLCDataPersistenceService {
protected BaseDao baseDao = new BaseDao();
private static final Logger log = LoggerFactory.getLogger(PLCDataPersistenceService.class);
public void persistence(Topic topic, ServerDto serverDto)
{
log.info("更新数据{}",topic);
if(serverDto instanceof AllPostDto)
{
List<DeviceInfo> list = ((AllPostDto)serverDto).getDeviceInfoList();
if(null != list && list.size() != 0 )
{
for (DeviceInfo deviceInfo:list)
{
baseDao.update(deviceInfo);
}
}
}
//曲线数据入库
List<DeviceSensorData> dsdList = serverDto.getDeviceSensorDataList();
if(null != dsdList && dsdList.size() != 0)
{
baseDao.insertList(dsdList, TableUtil.getNowTableName("runing_fish_data","device_sensor_data",3));
}
//日志入库
List<com.zhonglai.luhui.device.analysis.comm.dto.LogDeviceOperation> doList = serverDto.getLogDeviceOperationList();
if(null != doList && doList.size() != 0)
{
List<LogDeviceOperation> loglist = new ArrayList<>();
for(com.zhonglai.luhui.device.analysis.comm.dto.LogDeviceOperation oldlog:doList)
{
LogDeviceOperation newLog = GsonConstructor.get().fromJson(GsonConstructor.get().toJson(oldlog),LogDeviceOperation.class);
newLog.setDeviceId(oldlog.getDeviceInfoId());
loglist.add(newLog);
}
baseDao.insertList(loglist, TableUtil.getNowTableName("runing_fish_device_operation","log_device_operation",3));
}
}
}
... ...
package com.zhonglai.luhui.lsy.plc.service.service.topic;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.GsonConstructor;
import com.ruoyi.common.utils.StringUtils;
import com.zhonglai.luhui.device.analysis.comm.config.SysParameter;
import com.zhonglai.luhui.device.analysis.comm.dto.DeviceOperationTypeEnum;
import com.zhonglai.luhui.device.analysis.comm.dto.DeviceSensorData;
import com.zhonglai.luhui.device.analysis.comm.dto.ServerDto;
import com.zhonglai.luhui.device.analysis.comm.dto.business.BusinessDto;
import com.zhonglai.luhui.device.analysis.comm.factory.BusinessAgreement;
import com.zhonglai.luhui.device.analysis.comm.factory.Topic;
import com.zhonglai.luhui.device.analysis.comm.util.ByteUtil;
import com.zhonglai.luhui.lsy.plc.service.comm.service.DeviceService;
import com.zhonglai.luhui.lsy.plc.service.dto.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
/**
* 全量上报数据,不需要返回
*/
@Service("ALL_POST")
public class AllPostTopic implements BusinessAgreement<AllPostDto> {
private static final Logger log = LoggerFactory.getLogger(AllPostTopic.class);
@Autowired
private DeviceService deviceService;
@Override
public ServerDto analysis(Topic topic, AllPostDto data) throws Exception {
if(null == data ) //数据和设备都没有不用解析
{
return null;
}
List<DeviceInfo> list = deviceService.getDeviceInfoList(topic.getClientid());
if(null == list || list.size() == 0)
{
log.info("设备列表{}不存在",topic.getClientid());
return null;
}
data.setDeviceInfoList(list);
if( null == data.getData()) //没有数据、但是有设备
{
return null;
}
List<DeviceInfo> deviceInfoList = data.getDeviceInfoList(); //数据库以添加的设备列表
JSONObject object = data.getData();
if(null != object && object.size() !=0)
{
List<DeviceDataConfig> deviceDataConfigList = DeviceProductProtocol.deviceDataConfigList; //获取点位表配置
if(null != deviceDataConfigList && deviceDataConfigList.size() !=0)
{
for (DeviceInfo deviceInfo:deviceInfoList)
{
String newAlrmCode = "00";
for (DeviceDataConfig deviceDataConfig:deviceDataConfigList)
{
String dttribute_name = deviceDataConfig.getAttribute_name();
if(object.containsKey(dttribute_name) && null != object.get(dttribute_name)) //点位值存在
{
String dttribute_value = object.get(dttribute_name).toString();
String newDataValue= ByteUtil.changerTwoStr(dttribute_value);
String deviceInfoId = deviceDataConfig.getDeviceInfoId(topic.getClientid()); //根据点位协议解析到设备id
if(deviceInfoId.equals(deviceInfo.getId()) || deviceInfoId.equals(topic.getClientid())) //点位匹配
{
switch (deviceDataConfig.getPlc_data_type())
{
case 故障代码:
if(newDataValue.equals(deviceDataConfig.getAlarmValue()))
{
newAlrmCode = deviceDataConfig.getAlarmCode();
}
break;
default:
String dataValue = deviceInfo.getDataValue();
JSONObject jsonObject = new JSONObject();
if(StringUtils.isNotEmpty(dataValue))
{
jsonObject = GsonConstructor.get().fromJson(dataValue,JSONObject.class);
}
String odlDataValue = (String) jsonObject.get(deviceDataConfig.getPlc_data_type().sensorDataType);
if(!newDataValue.equals(odlDataValue))
{
jsonObject.put(deviceDataConfig.getPlc_data_type().sensorDataType,newDataValue); //更新数据
deviceInfo.setDataValue(jsonObject.toJSONString());
String describe = deviceDataConfig.getAttribute_describe()+newDataValue;
//记录日志
if(null != deviceDataConfig.getDevice_type())
{
describe = deviceDataConfig.getSensor_numer()+deviceDataConfig.getDevice_type().name()+describe;
}
data.getLogDeviceOperationList().add(addLogDeviceOperation(topic.getClientid(),deviceDataConfig.getSensor_numer(),null,describe,newDataValue,odlDataValue,1));
}
break;
}
}
}
}
deviceInfo.setAlarmCode(newAlrmCode);
deviceInfo.setDataUpdateTime(DateUtils.getNowTimeMilly());
deviceInfo.setDeviceServiceIp(SysParameter.service_ip);
deviceInfo.setOnline("01");
}
}
}
return data;
}
@Override
public AllPostDto toData(BusinessDto data) {
AllPostDto serverDto = new AllPostDto();
serverDto.setDeviceInfoList(new ArrayList<>());
serverDto.setDeviceSensorDataList(new ArrayList<>());
serverDto.setLogDeviceOperationList(new ArrayList<>());
if(data.getContentData() instanceof JSONObject)
{
serverDto.setData((JSONObject) data.getContentData());
return serverDto;
}else if(data.getContentData() instanceof byte[])
{
serverDto.setData(JSONObject.parseObject(new String((byte[]) data.getContentData())));
return serverDto;
}
return null;
}
/**
* 添加设备操作日志记录
* @param deviceId 设备imei
* @param sensorNum 传感器或控制器编号
* @param operationInstruction 设备操作指令
* @param describe 设备操作描述
* @param newState 设备操作后的状态
* @param isStateChange 是否有状态改变(0否,1是)
*/
protected com.zhonglai.luhui.device.analysis.comm.dto.LogDeviceOperation addLogDeviceOperation(String deviceId, String sensorNum, String operationInstruction, String describe, String newState, String oldState, Integer isStateChange)
{
//更新设备操作日志记录
com.zhonglai.luhui.device.analysis.comm.dto.LogDeviceOperation logDeviceOperation = new com.zhonglai.luhui.device.analysis.comm.dto.LogDeviceOperation();
logDeviceOperation.setDeviceInfoId(deviceId);
logDeviceOperation.setSensorOrController(sensorNum);
logDeviceOperation.setDeviceOperationTime(DateUtils.getNowTimeMilly());
logDeviceOperation.setOperationInstruction(operationInstruction);
logDeviceOperation.setOperationDescribe(describe);
logDeviceOperation.setDeviceNewState(newState);
logDeviceOperation.setDeviceOldState(oldState);
logDeviceOperation.setDeviceOperationType(-1);
logDeviceOperation.setIsStateChange(isStateChange);
return logDeviceOperation ;
}
}
... ...
package com.zhonglai.luhui.lsy.plc.service.service.topic;
import com.alibaba.fastjson.JSONObject;
import com.zhonglai.luhui.device.analysis.comm.dto.ServerDto;
import com.zhonglai.luhui.device.analysis.comm.dto.business.BusinessDto;
import com.zhonglai.luhui.device.analysis.comm.factory.BusinessAgreement;
import com.zhonglai.luhui.device.analysis.comm.factory.Topic;
import com.zhonglai.luhui.device.analysis.dto.MessageCode;
import com.zhonglai.luhui.lsy.plc.service.dto.PutReqDto;
import com.zhonglai.luhui.lsy.plc.service.service.ClienNoticeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 更新数据的执行结果
*/
@Service("PUT_REQ")
public class PutReqTopic implements BusinessAgreement<PutReqDto> {
@Autowired
private ClienNoticeService clienNoticeService; //客户端通知服务
@Override
public ServerDto analysis(Topic topic, PutReqDto data) throws Exception {
clienNoticeService.replySendMessage(topic, message -> {
message.setData(data.getTime());
message.setCode(MessageCode.DEFAULT_FAIL_CODE);
message.setMessage(data.getMsg());
switch (data.getResult())
{
case "1":
message.setCode(MessageCode.DEFAULT_SUCCESS_CODE);
message.setMessage("成功");
break;
}
});
return null;
}
@Override
public PutReqDto toData(BusinessDto data) {
PutReqDto putReqDto = JSONObject.parseObject(((JSONObject) data.getContentData()).toJSONString(),PutReqDto.class);
return putReqDto;
}
}
... ...
##服务器配置
server:
tomcat:
uri-encoding: UTF-8
port: 4883
servlet:
context-path: /
spring:
messages:
encoding: UTF-8
mvc:
#出现错误时, 直接抛出异常
throw-exception-if-no-handler-found: true
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
default-property-inclusion: non_null
mqtt:
#链接地址
broker: tcp://47.112.163.61:1883
#唯一标识
clientId: ${random.uuid}
#公司id
roleid: 2
mqtt_usernames: PLC_004
#订阅的topic
topics: ALL_POST,PUT_REQ
sub_clientid: '#'
topicconfig: "/{{roleid}}/{{username}}/{{topicType}}/{{clientid}}"
top_return_map: '{"PUT":"PUT_REQ"}'
username: sysuser
password: "!@#1qaz"
client:
#客户端操作时间
operationTime: 10
sys:
redis:
field: "lh:mqttservice:"
isText: false
... ...
driverClassName=com.mysql.cj.jdbc.Driver
#url=jdbc:mysql://rm-wz9740un21f09iokuao.mysql.rds.aliyuncs.com:3306/mqtt_broker?useUnicode=true&characterEncoding=utf8&autoReconnect=true
#username=luhui
#password=Luhui586
url=jdbc:mysql://rm-wz9446bn79p0r80ew0o.mysql.rds.aliyuncs.com:3306/runing_fish?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghai
username=luhui
password=Luhui586
#\u6700\u5927\u8FDE\u63A5\u6570\u91CF
maxActive=100
#\u6700\u5927\u7A7A\u95F2\u8FDE\u63A5
maxIdle=-1
#\u6700\u5C0F\u7A7A\u95F2\u8FDE\u63A5
minIdle=10
#\u8D85\u65F6\u7B49\u5F85\u65F6\u95F4\u4EE5\u6BEB\u79D2\u4E3A\u5355\u4F4D 60000\u6BEB\u79D2/1000\u7B49\u4E8E60\u79D2
maxWait=60000
#removeAbandoned: \u662F\u5426\u81EA\u52A8\u56DE\u6536\u8D85\u65F6\u8FDE\u63A5
removeAbandoned=true
#removeAbandonedTimeout: \u8D85\u65F6\u65F6\u95F4(\u4EE5\u79D2\u6570\u4E3A\u5355\u4F4D)
removeAbandonedTimeout=120
testOnBorrow=false
logAbandoned=true
\ No newline at end of file
... ...
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/output.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/output.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>5</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="FILE" />
<appender-ref ref="CONSOLE" />
</root>
</configuration>
... ...
<?xml version="1.0" encoding="UTF-8"?>
<assembly>
<id>bin</id>
<!-- 最终打包成一个用于发布的zip文件 -->
<formats>
<format>zip</format>
</formats>
<!-- Adds dependencies to zip package under lib directory -->
<dependencySets>
<dependencySet>
<!--
不使用项目的artifact,第三方jar不要解压,打包进zip文件的lib目录
-->
<useProjectArtifact>false</useProjectArtifact>
<outputDirectory>lib</outputDirectory>
<unpack>false</unpack>
</dependencySet>
</dependencySets>
<fileSets>
<!-- 把项目相关的说明文件,打包进zip文件的根目录 -->
<fileSet>
<directory>${project.basedir}</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>README*</include>
<include>LICENSE*</include>
<include>NOTICE*</include>
</includes>
</fileSet>
<!-- 把项目的配置文件,打包进zip文件的config目录 -->
<fileSet>
<directory>${project.basedir}\src\main\resources\configs</directory>
<outputDirectory>../configs</outputDirectory>
<includes>
<include>*.properties</include>
</includes>
</fileSet>
<!-- 把项目的配置文件,提出来 -->
<fileSet>
<directory>${project.basedir}\src\main\resources</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>*.properties</include>
<include>*.yml</include>
</includes>
</fileSet>
<!-- 把项目的脚本文件目录( src/main/scripts )中的启动脚本文件,打包进zip文件的跟目录 -->
<fileSet>
<directory>${project.basedir}\bin</directory>
<outputDirectory></outputDirectory>
<includes>
<include>start.*</include>
<include>stop.*</include>
</includes>
</fileSet>
<!-- 把项目自己编译出来的jar文件,打包进zip文件的根目录 -->
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory></outputDirectory>
<includes>
<include>*.jar</include>
</includes>
</fileSet>
</fileSets>
</assembly>
\ No newline at end of file
... ...
... ... @@ -49,7 +49,7 @@ mqtt:
mqtt_usernames: 6_WP,12_BPQ,10_TLJ,NWDB_2023,WLJ_1,YWB_A700E,12_ZNZY
#订阅的topic
topics: ADD_POST,ALL_POST,DB_TOPIC_DISTRIBUTE,GET/+,online,PUT_REQ/+,READ_REQ/+
sub_clientid: '866838067733465'
sub_clientid: '866520063012785'
topicconfig: "/{{roleid}}/{{username}}/{{clientid}}/{{payloadtype}}/{{topicType}}/{{messageid}}"
top_return_map: '{"PUT":"PUT_REQ","READ":"READ_REQ"}'
username: sysuser
... ...
... ... @@ -3,6 +3,7 @@ package com.zhonglai.luhui.smart.feeder;
import com.zhonglai.luhui.smart.feeder.config.OpenCVConfig;
import com.zhonglai.luhui.smart.feeder.service.InitService;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
... ... @@ -12,7 +13,6 @@ public class Main {
public static void main(String[] args) {
logger.info("开始启动服务器");
OpenCVConfig.loadOpenCv(args);
//配置参数
logger.info("配置参数");
InitService.initConfig();
... ...
... ... @@ -14,22 +14,22 @@ import java.util.List;
public class CameraData {
/**
* 当前画面的亮度
* 当前画面的平均亮度
*/
private Double brightness;
/**
* 当前画面的反光
* 当前画面的平均反光
*/
private Double reflection;
/**
* 当前画面的透明度
* 当前画面的平均透明度
*/
private Double transparencyMeasure;
/**
* 当前画面的面积
* 当前画面的平均面积
*/
private Double area;
... ...
... ... @@ -16,9 +16,12 @@ public class FeederCommd10Request implements FeederCommd {
{
start_char = new Long(ByteUtil.bytesToLongDESC(data,0,2)).intValue();
register_number = new Long(ByteUtil.bytesToLongDESC(data,2,2)).intValue();
if (data.length>4)
{
byte_lenth = new Long(ByteUtil.bytesToLongDESC(data,4,2)).intValue();
data = ArrayUtils.subarray(data,6,6+byte_lenth);
}
}
public Integer getStart_char() {
return start_char;
... ...
... ... @@ -33,7 +33,7 @@ public class FeederCommdDto extends ModbusDto {
{
byte[] start_bytes = ByteUtil.intToBytesDESC(feederCommd10Response.getStart_char(),2);
byte[] number_bytes = ByteUtil.intToBytesDESC( feederCommd10Response.getRegister_number(),2);
byte[] lenth_bytes = ByteUtil.intToBytesDESC( feederCommd10Response.getByte_lenth(),2);
byte[] lenth_bytes = ByteUtil.intToBytesDESC( feederCommd10Response.getByte_lenth(),1);
byte[] data = feederCommd10Response.getData();
super.toModbusDto(0x01,0x10, ArrayUtil.addAll(start_bytes,number_bytes,lenth_bytes,data));
this.feederCommd = feederCommd10Response;
... ...
... ... @@ -15,30 +15,30 @@ public class FeederTimer {
public void setObjectValue(String field,long value)
{
switch (field)
switch (field.substring(field.indexOf("_")+1))
{
case "timer_start_m":
case "start_m":
timer_start_m = Integer.valueOf(Long.toString(value));
break;
case "timer_start_h":
case "start_h":
timer_start_h =Integer.valueOf(Long.toString(value));
break;
case "timer_if_start":
case "if_start":
timer_if_start =Integer.valueOf(Long.toString(value));
break;
case "timer_is_start":
case "is_start":
timer_is_start =Integer.valueOf(Long.toString(value));
break;
case "timer_close_m":
case "close_m":
timer_close_m =Integer.valueOf(Long.toString(value));
break;
case "timer_close_h":
case "close_h":
timer_close_h =Integer.valueOf(Long.toString(value));
break;
case "timer_if_close":
case "if_close":
timer_if_close =Integer.valueOf(Long.toString(value));
break;
case "timer_is_close":
case "is_close":
timer_is_close =Integer.valueOf(Long.toString(value));
break;
}
... ...
... ... @@ -13,5 +13,4 @@ public class Condata
private Integer interval; //时间间隔 1-18秒
private Integer runstate; //运行状态 1运行、3停止(平台可以设置0启动中,2关闭中,4异常)
private Integer stopfeedcnt; //手动投料倒计时时间 单位分
private Integer onoff; //运行状态 1运行、3停止(平台可以设置0启动中,2关闭中,4异常)
}
... ...
... ... @@ -90,7 +90,10 @@ public class FishGroupImageRecognitionService {
public void stop()
{
srsService.stop();
OperatingData.cameraData.setFishGroupImageRecognIsRun(false);
backgroundSubtractor.clear();
scheduledFuture.cancel(true);
while (!scheduledFuture.isCancelled())
{
... ... @@ -126,7 +129,7 @@ public class FishGroupImageRecognitionService {
{
isread = true;
}
logger.info("逐帧处理视频,开始处理的判断参数:鱼群图像识别是否开启 {}、摄像头是否可读取 {}",OperatingData.cameraConfig.getFishGroupImageRecognition(),isread);
// logger.info("逐帧处理视频,开始处理的判断参数:鱼群图像识别是否开启 {}、摄像头是否可读取 {}",OperatingData.cameraConfig.getFishGroupImageRecognition(),isread);
if(!isread )
{
logger.info("摄像头不可读取");
... ... @@ -286,6 +289,8 @@ public class FishGroupImageRecognitionService {
}
}
logger.info("当前画面的亮度:{},当前画面的反光:{},当前画面的透明度:{},当前画面的平均面积:{},鱼群规模:{},鱼群数量:{}",brightness,reflection,transparencyMeasure,area,fishSchoolSize, OperatingData.cameraData.getSize());
}
}
}
... ...
... ... @@ -100,6 +100,8 @@ public class ScaleStepMethodService {
stringBuffer.append(OperatingData.cameraData.getScaleAreaSumMax());
InitService.dateListenService.reportIntelligentFeeding(stringBuffer.toString());
}
System.out.println("尺度之内的面积之和:"+sum+";尺度之内的面积之和曲线的峰值:"+OperatingData.cameraData.getScaleAreaSumMax()+";尺度之内的面积之和占比:"+scaleAreaSumPercentage);
},0, OperatingData.cameraConfig.getScaleStep(), TimeUnit.SECONDS);
}
... ...
... ... @@ -113,7 +113,7 @@ public class SrsService {
}
}
public void close()
private void close()
{
if(null != recorder)
{
... ...
... ... @@ -10,6 +10,7 @@ import com.zhonglai.luhui.smart.feeder.dto.ModbusDto;
import com.zhonglai.luhui.smart.feeder.dto.SerialPortConfig;
import com.zhonglai.luhui.smart.feeder.dto.commd.FeederCommdDto;
import com.zhonglai.luhui.smart.feeder.service.ConfigurationParameterService;
import com.zhonglai.luhui.smart.feeder.service.InitService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -119,7 +120,9 @@ public class SerialPortService {
try {
Thread.sleep(500);
FeederCommdDto commdDto = new FeederCommdDto(readFromPort(port));
byte[] bytes = readFromPort(port);
logger.info("串口返回数据:"+ByteUtil.toHexString(bytes));
FeederCommdDto commdDto = new FeederCommdDto(bytes);
dataQueue.offer(commdDto); // 将数据添加到队列中// 处理串口返回的数据
} catch (Exception e) {
logger.error("返回数据处理异常",e);
... ... @@ -147,18 +150,19 @@ public class SerialPortService {
* @throws IOException
*/
public ModbusDto sendHexData(String hexStr) {
logger.info("串口写入:{}",hexStr);
byte[] bytes = ByteUtil.hexStringToByte(hexStr.replace(" ","").trim().toUpperCase());
return sendByte(bytes);
}
/**
* 发送支持中文的字符串
* @param str
* @throws IOException
*/
public ModbusDto sendStrData(String str) {
return sendByte(str.getBytes(StandardCharsets.UTF_8));
}
// /**
// * 发送支持中文的字符串
// * @param str
// * @throws IOException
// */
// public ModbusDto sendStrData(String str) {
// return sendByte(str.getBytes(StandardCharsets.UTF_8));
// }
/**
* 发送byte数组
... ... @@ -221,5 +225,4 @@ public class SerialPortService {
}
}
... ...
... ... @@ -5,6 +5,7 @@ import com.ruoyi.common.utils.StringUtils;
import com.zhonglai.luhui.smart.feeder.config.OperatingData;
import com.zhonglai.luhui.smart.feeder.dto.HCCameraRepose;
import com.zhonglai.luhui.smart.feeder.service.ConfigurationParameterService;
import com.zhonglai.luhui.smart.feeder.service.InitService;
import com.zhonglai.luhui.smart.feeder.service.PushVideo;
import com.zhonglai.luhui.smart.feeder.service.device.CameraHandle;
import org.bytedeco.ffmpeg.global.avutil;
... ... @@ -80,6 +81,22 @@ public class CameraRtspHandle implements CameraHandle {
while (isOpen() && !isclose) {
try {
mat = getMat();
int i=0;
while (null == mat && i<3)
{
logger.info("读取不到视频等待3秒,尝试第"+i+"次");
Thread.sleep(3000);
mat = getMat();
i++;
}
if(null == mat)
{
InitService.fishGroupImageRecognitionService.stop();
close();
Thread thread1 = new Thread(() -> init());
thread1.start();
}
} catch (Exception e) {
logger.error("抓取摄像头帧失败",e);
}
... ...
... ... @@ -27,6 +27,7 @@
<module>lh-server-ops</module>
<module>lh-http-service</module>
<module>lh-data-file-service</module>
<module>lh-lsy-plc-service</module>
</modules>
<properties>
... ...