Browse Source

中山站尝试用程序采集

dev-zs
yj 2 years ago
parent
commit
1a1dd17436
  1. 169
      device_gather/pom.xml
  2. 19
      device_gather/src/main/java/com/xr/device/DeviceGatherApplication.java
  3. 11
      device_gather/src/main/java/com/xr/device/common/configvalue/StaticPropProxy.java
  4. 26
      device_gather/src/main/java/com/xr/device/common/configvalue/StaticProperties.java
  5. 85
      device_gather/src/main/java/com/xr/device/common/utils/CharsetKit.java
  6. 1000
      device_gather/src/main/java/com/xr/device/common/utils/Convert.java
  7. 435
      device_gather/src/main/java/com/xr/device/common/utils/Files.java
  8. 167
      device_gather/src/main/java/com/xr/device/common/utils/ModbusUtils.java
  9. 205
      device_gather/src/main/java/com/xr/device/common/utils/PythonExecutor.java
  10. 151
      device_gather/src/main/java/com/xr/device/common/utils/SpringUtils.java
  11. 26
      device_gather/src/main/java/com/xr/device/common/utils/StaticPropUtil.java
  12. 90
      device_gather/src/main/java/com/xr/device/common/utils/StrFormatter.java
  13. 607
      device_gather/src/main/java/com/xr/device/common/utils/StringUtils.java
  14. 187
      device_gather/src/main/java/com/xr/device/common/utils/UploadUtil.java
  15. 80
      device_gather/src/main/java/com/xr/device/common/utils/ValueFormatUtil.java
  16. 126
      device_gather/src/main/java/com/xr/device/model/entity/DeviceCamera.java
  17. 141
      device_gather/src/main/java/com/xr/device/model/entity/FocalLengthConfig.java
  18. 183
      device_gather/src/main/java/com/xr/device/model/entity/MeterConfig.java
  19. 50
      device_gather/src/main/java/com/xr/device/model/entity/MeterInitialization.java
  20. 97
      device_gather/src/main/java/com/xr/device/model/entity/MeterReadingRecord.java
  21. 86
      device_gather/src/main/java/com/xr/device/model/entity/MeterType.java
  22. 20
      device_gather/src/main/java/com/xr/device/model/mapper/DeviceCameraMapper.java
  23. 20
      device_gather/src/main/java/com/xr/device/model/mapper/FocalLengthConfigMapper.java
  24. 24
      device_gather/src/main/java/com/xr/device/model/mapper/MeterConfigMapper.java
  25. 20
      device_gather/src/main/java/com/xr/device/model/mapper/MeterInitializationMapper.java
  26. 20
      device_gather/src/main/java/com/xr/device/model/mapper/MeterReadingRecordMapper.java
  27. 20
      device_gather/src/main/java/com/xr/device/model/mapper/MeterTypeMapper.java
  28. 13
      device_gather/src/main/java/com/xr/device/model/service/DeviceCameraService.java
  29. 13
      device_gather/src/main/java/com/xr/device/model/service/FocalLengthConfigService.java
  30. 17
      device_gather/src/main/java/com/xr/device/model/service/MeterConfigService.java
  31. 13
      device_gather/src/main/java/com/xr/device/model/service/MeterInitializationService.java
  32. 13
      device_gather/src/main/java/com/xr/device/model/service/MeterReadingRecordService.java
  33. 13
      device_gather/src/main/java/com/xr/device/model/service/MeterTypeService.java
  34. 24
      device_gather/src/main/java/com/xr/device/model/service/impl/DeviceCameraServiceImpl.java
  35. 24
      device_gather/src/main/java/com/xr/device/model/service/impl/FocalLengthConfigServiceImpl.java
  36. 30
      device_gather/src/main/java/com/xr/device/model/service/impl/MeterConfigServiceImpl.java
  37. 24
      device_gather/src/main/java/com/xr/device/model/service/impl/MeterInitializationServiceImpl.java
  38. 24
      device_gather/src/main/java/com/xr/device/model/service/impl/MeterReadingRecordServiceImpl.java
  39. 24
      device_gather/src/main/java/com/xr/device/model/service/impl/MeterTypeServiceImpl.java
  40. 204
      device_gather/src/main/java/com/xr/device/schedule/GetMeterSchedule.java
  41. 80
      device_gather/src/main/resources/application-dev.yml
  42. 80
      device_gather/src/main/resources/application-prod.yml
  43. 82
      device_gather/src/main/resources/application.yml
  44. 23
      device_gather/src/main/resources/banner.txt
  45. 51
      device_gather/src/main/resources/logback.xml
  46. 40
      device_gather/src/main/resources/mapper/DeviceCameraMapper.xml
  47. 43
      device_gather/src/main/resources/mapper/FocalLengthConfigMapper.xml
  48. 59
      device_gather/src/main/resources/mapper/MeterConfigMapper.xml
  49. 20
      device_gather/src/main/resources/mapper/MeterInitializationMapper.xml
  50. 32
      device_gather/src/main/resources/mapper/MeterReadingRecordMapper.xml
  51. 30
      device_gather/src/main/resources/mapper/MeterTypeMapper.xml

169
device_gather/pom.xml

@ -0,0 +1,169 @@
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.xr.device_net</groupId>
<artifactId>device_car</artifactId>
<version>1.0.1</version>
</parent>
<artifactId>device_gather</artifactId>
<name>${project.artifactId}</name>
<properties>
<java.version>1.8</java.version>
</properties>
<repositories>
<repository>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
<id>ias-snapshots</id>
<name>Infinite Automation Snapshot Repository</name>
<url>https://maven.mangoautomation.net/repository/ias-snapshot/</url>
</repository>
<repository>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>ias-releases</id>
<name>Infinite Automation Release Repository</name>
<url>https://maven.mangoautomation.net/repository/ias-release/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!--web 模块 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--tomcat容器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.28</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
<!-- netflix-eureka-client依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- spring cloud openfeign依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.78</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-discovery</groupId>
<artifactId>commons-discovery</artifactId>
<version>0.2</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>io.github.java-native</groupId>
<artifactId>jssc</artifactId>
<version>2.9.4</version>
</dependency>
<dependency>
<groupId>com.infiniteautomation</groupId>
<artifactId>modbus4j</artifactId>
<version>3.0.4</version>
</dependency>
<dependency>
<groupId>org.rxtx</groupId>
<artifactId>rxtx</artifactId>
<version>2.1.7</version>
</dependency>
<dependency>
<groupId>org.scream3r</groupId>
<artifactId>jssc</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.59</version>
</dependency>
<dependency>
<groupId>com.xr</groupId>
<artifactId>onvif-hk</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<includes>
<include>**/*</include>
<include>**/*.fxml</include>
<include>**/fxml/*.fxml</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.0.8.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

19
device_gather/src/main/java/com/xr/device/DeviceGatherApplication.java

@ -0,0 +1,19 @@
package com.xr.device;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.scheduling.annotation.EnableScheduling;
@EnableScheduling//开启定时任务
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class DeviceGatherApplication {
public static void main(String[] args) {
SpringApplication.run(DeviceGatherApplication.class, args);
}
}

11
device_gather/src/main/java/com/xr/device/common/configvalue/StaticPropProxy.java

@ -0,0 +1,11 @@
package com.xr.device.common.configvalue;
import com.xr.device.common.utils.StaticPropUtil;
import org.springframework.stereotype.Component;
@Component
public class StaticPropProxy {
public StaticPropProxy(StaticProperties staticProperties){
StaticPropUtil.initDingDingProp(staticProperties);
}
}

26
device_gather/src/main/java/com/xr/device/common/configvalue/StaticProperties.java

@ -0,0 +1,26 @@
package com.xr.device.common.configvalue;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
@Data
public class StaticProperties {
@Value("${upload.img.url}")
private String imgUrl;
@Value("${upload.img.path}")
private String imgPath;
@Value("${python.path}")
private String pythonPath;
@Value("${python.modelPath}")
private String modelPath;
@Value("${station.id}")
private Integer stationId;
}

85
device_gather/src/main/java/com/xr/device/common/utils/CharsetKit.java

@ -0,0 +1,85 @@
package com.xr.device.common.utils;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
/**
* 字符集工具类
*
* @author
*/
public class CharsetKit
{
/** ISO-8859-1 */
public static final String ISO_8859_1 = "ISO-8859-1";
/** UTF-8 */
public static final String UTF_8 = "UTF-8";
/** GBK */
public static final String GBK = "GBK";
/** ISO-8859-1 */
public static final Charset CHARSET_ISO_8859_1 = Charset.forName(ISO_8859_1);
/** UTF-8 */
public static final Charset CHARSET_UTF_8 = Charset.forName(UTF_8);
/** GBK */
public static final Charset CHARSET_GBK = Charset.forName(GBK);
/**
* 转换为Charset对象
*
* @param charset 字符集为空则返回默认字符集
* @return Charset
*/
public static Charset charset(String charset)
{
return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset);
}
/**
* 转换字符串的字符集编码
*
* @param source 字符串
* @param srcCharset 源字符集默认ISO-8859-1
* @param destCharset 目标字符集默认UTF-8
* @return 转换后的字符集
*/
public static String convert(String source, String srcCharset, String destCharset)
{
return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset));
}
/**
* 转换字符串的字符集编码
*
* @param source 字符串
* @param srcCharset 源字符集默认ISO-8859-1
* @param destCharset 目标字符集默认UTF-8
* @return 转换后的字符集
*/
public static String convert(String source, Charset srcCharset, Charset destCharset)
{
if (null == srcCharset)
{
srcCharset = StandardCharsets.ISO_8859_1;
}
if (null == destCharset)
{
destCharset = StandardCharsets.UTF_8;
}
if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset))
{
return source;
}
return new String(source.getBytes(srcCharset), destCharset);
}
/**
* @return 系统字符集编码
*/
public static String systemCharset()
{
return Charset.defaultCharset().name();
}
}

1000
device_gather/src/main/java/com/xr/device/common/utils/Convert.java

File diff suppressed because it is too large

435
device_gather/src/main/java/com/xr/device/common/utils/Files.java

@ -0,0 +1,435 @@
package com.xr.device.common.utils;
import org.apache.commons.io.FileUtils;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Encoder;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.Authenticator;
import java.net.PasswordAuthentication;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
public class Files {
/**
* 根据文件路径获取文件字节流
* @return
* filePath 文件路径
* @throws IOException
*/
public static byte[] toByteArray(String filePath) throws IOException {
File f = new File(filePath);
if (!f.exists()) {
throw new FileNotFoundException("文件不存在");
}
ByteArrayOutputStream bos = new ByteArrayOutputStream((int) f.length());
BufferedInputStream in = null;
try {
in = new BufferedInputStream(new FileInputStream(f));
int buf_size = 1024;
byte[] buffer = new byte[buf_size];
int len = 0;
while (-1 != (len = in.read(buffer, 0, buf_size))) {
bos.write(buffer, 0, len);
}
return bos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
throw e;
} finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
bos.close();
}
}
public static File multipartFileToFile(MultipartFile file) throws Exception {
File toFile = null;
if (file.equals("") || file.getSize() <= 0) {
file = null;
} else {
InputStream ins = null;
ins = file.getInputStream();
toFile = new File(file.getOriginalFilename());
inputStreamToFile(ins, toFile);
ins.close();
}
return toFile;
}
public static BufferedImage bytesTobufferedImage(byte[] bytes){
BufferedImage image = null;
try {
// 利用ByteArrayInputStream将字节数据转换成InputStream
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
// 使用ImageIO读取InputStream中的数据转换为BufferedImage
image = ImageIO.read(bais);
// 关闭ByteArrayInputStream
bais.close();
// 此时,image就是转换后的BufferedImage对象,可以进行显示或其他处理
// 例如显示图像:
// ImageIcon icon=new ImageIcon(image);
// JOptionPane.showMessageDialog(null, icon);
} catch (IOException e) {
e.printStackTrace();
}
return image;
}
public static String uploadImage(BufferedImage bufferedImage, Integer configId) throws Exception {
// 构建完整的路径
String fileName = configId+new Date().getTime()+".jpg";
SimpleDateFormat sim=new SimpleDateFormat("yyyy-MM-dd");
String date = sim.format(new Date());
String dates[] = date.split("-");
String year = dates[0];
String month = dates[1];
String day = dates[2];
//String fullPath = StaticPropUtil.imgPath + configId + File.separator + year + File.separator + month + File.separator + day + File.separator + fileName;
String fullPath = StaticPropUtil.imgPath + File.separator + fileName;
// 创建目录结构
//Path directoryPath = Paths.get(StaticPropUtil.imgPath, configId.toString(), year, month, day);
Path directoryPath = Paths.get(StaticPropUtil.imgPath);
if (!java.nio.file.Files.exists(directoryPath)) {
java.nio.file.Files.createDirectories(directoryPath);
}
// 创建文件并写入图像
File file = new File(fullPath);
ImageIO.write(bufferedImage, "jpg", file);
// 构建URL
String url = StaticPropUtil.imgUrl + configId + "/" + year + "/"+ month + "/" + day + "/" + fileName;
return url;
}
private static void inputStreamToFile(InputStream ins, File file) {
try {
OutputStream os = new FileOutputStream(file);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();
ins.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static BufferedImage urlByImage(String url,String username,String password) throws IOException {
BufferedImage bimg=null;
try {
// 设置身份验证
Authenticator.setDefault(new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password.toCharArray());
}
});
// 创建URL对象并打开连接
URL uri = new URL(url);
URLConnection connection = uri.openConnection();
// 获取输入流
InputStream inputStream = connection.getInputStream();
bimg= ImageIO.read(inputStream);
// 关闭流
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
return bimg;
}
public static BufferedImage urlByImage(String url) throws IOException {
URL urlfile = new URL(url);
InputStream is2 = urlfile.openStream();
BufferedImage uImg= ImageIO.read(is2);
return uImg;
}
public static String TransformPhotoToBase64Data(String path){
Base64.Encoder encoder= Base64.getEncoder(); //获取Base64编码器
byte [] ImgContainer = null ; //数据集缓存器
FileInputStream fileInputStream = null; //文件输入流
try {
System.out.println(path);
File file=new File(path);
fileInputStream = new FileInputStream(file); //到指定路径寻找文件
ImgContainer = new byte[fileInputStream.available()]; //设置图片字节数据缓冲区大小
fileInputStream.read(ImgContainer); //将数据流中的图片数据读进缓冲区
String Base64ImgData =encoder.encodeToString(ImgContainer); //将图片编码转换成Base64格式的数据集
fileInputStream.close(); //关闭数据流
return Base64ImgData; //将缓冲区数据转换成字符数据返回
} catch (FileNotFoundException e) {
return "找不到指定文件!";
} catch (IOException e) {
e.printStackTrace();
}
return "null";
}
public static String getBase64String(MultipartFile multiPartFile) throws IOException {
String baseStr = null;
//把MultipartFile转化为File
File file = new File(multiPartFile.getOriginalFilename());
FileUtils.copyInputStreamToFile(multiPartFile.getInputStream(), file);
/* System.out.println("文件名:"+file.getOriginalFilename( ));
System.out.println("文件类型:"+file.getContentType());
System.out.println("文件大小: "+file.getSize( ));
String dateDir = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
ClassPathResource PATHS = new ClassPathResource("static/files/");
File paths=new File(PATHS.getPath()+file.getOriginalFilename());
if (paths.getParentFile() != null && !paths.getParentFile().exists()) {
System.out.println("创建父路径");
paths.getParentFile().mkdirs();
}
com.xr.projsystem.common.utils.Base64Utils.decodeFile(
com.xr.projsystem.common.utils.Base64Utils.encode(file.getBytes()),paths);
mapData.put("url",serverConfig.getUrl()+paths.getPath().substring(paths.getPath().indexOf("files")));
System.out.println(serverConfig.getUrl()+paths.getPath().substring(paths.getPath().indexOf("files")));*/
try {//file转base64
FileInputStream inputStream = new FileInputStream(file);
byte[] buffer = new byte[(int) file.length()];
inputStream.read(buffer);
inputStream.close();
baseStr = new BASE64Encoder().encode(buffer);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
//删除临时文件
if (file.exists()) {
file.delete();
}
baseStr = baseStr.replaceAll("\r\n", "");
return baseStr;
}
public static String BufferedImageToBase64(BufferedImage bufferedImage) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();//io流
try {
ImageIO.write(bufferedImage, "png", baos);//写入流中
} catch (IOException e) {
e.printStackTrace();
}
byte[] bytes = baos.toByteArray();//转换成字节
BASE64Encoder encoder = new BASE64Encoder();
String png_base64 = encoder.encodeBuffer(bytes).trim();//转换成base64串
png_base64 = png_base64.replaceAll("\n", "").replaceAll("\r", "");//删除 \r\n
System.out.println("值为:" + "data:image/jpg;base64," + png_base64);
return "data:image/jpg;base64," + png_base64;
}
public static String ImageToBase64(BufferedImage bufferedImage) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();//io流
try {
ImageIO.write(bufferedImage, "png", baos);//写入流中
} catch (IOException e) {
e.printStackTrace();
}
byte[] bytes = baos.toByteArray();//转换成字节
BASE64Encoder encoder = new BASE64Encoder();
String png_base64 = encoder.encodeBuffer(bytes).trim();//转换成base64串
png_base64 = png_base64.replaceAll("\n", "").replaceAll("\r", "");//删除 \r\n
return png_base64;
}
/** *//**
* 旋转图片为指定角度
*
* @param file
* 目标图像
* @param degree
* 旋转角度
* @return
*/
public static BufferedImage rotateImage(File file,
int degree) throws Exception{
// if(degree<0){
// degree=Math.abs(degree);
// }else{
// degree=0-degree;
// }
BufferedImage bufferedimage = ImageIO.read(file);
int w= bufferedimage.getWidth();// 得到图片宽度。
int h= bufferedimage.getHeight();// 得到图片高度。
int type= bufferedimage.getColorModel().getTransparency();// 得到图片透明度。
BufferedImage img;// 空的图片。
Graphics2D graphics2d;// 空的画笔。
(graphics2d= (img= new BufferedImage(w, h, type))
.createGraphics()).setRenderingHint(
RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
graphics2d.rotate(Math.toRadians(degree),w/2,h/2);// 旋转,degree是整型,度数,比如垂直90度。
graphics2d.drawImage(bufferedimage, 0, 0, null);// 从bufferedimagecopy图片至img,0,0是img的坐标。
graphics2d.dispose();
return img;// 返回复制好的图片,原图片依然没有变,没有旋转,下次还可以使用。
}
public static BufferedImage rotateImage(BufferedImage bufferedimage,int degree){
int w= bufferedimage.getWidth();// 得到图片宽度。
int h= bufferedimage.getHeight();// 得到图片高度。
int type= bufferedimage.getColorModel().getTransparency();// 得到图片透明度。
BufferedImage img;// 空的图片。
Graphics2D graphics2d;// 空的画笔。
(graphics2d= (img= new BufferedImage(w, h, type))
.createGraphics()).setRenderingHint(
RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
graphics2d.rotate(Math.toRadians(degree), w / 2, h / 2);// 旋转,degree是整型,度数,比如垂直90度。
graphics2d.drawImage(bufferedimage, 0, 0, null);// 从bufferedimagecopy图片至img,0,0是img的坐标。
graphics2d.dispose();
return img;// 返回复制好的图片,原图片依然没有变,没有旋转,下次还可以使用。
}
public static BufferedImage scaledImage(BufferedImage bufferedimage,Double scaled){
int width =bufferedimage.getWidth();
int height = bufferedimage.getHeight();
return new BufferedImage(Double.valueOf(scaled*width).intValue(),Double.valueOf(scaled*height).intValue(),BufferedImage.TYPE_INT_RGB);
}
public static byte[] bufferedImageToByte(BufferedImage bufferedImage) throws IOException{
ByteArrayOutputStream os =new ByteArrayOutputStream();
ImageIO.write(bufferedImage,"jpg",os);
return os.toByteArray();
}
public static void savePathForImage(BufferedImage bufferedImage,String path){
File file=new File(path);
// 创建文件输出流
try {
ImageIO.write(bufferedImage, "png", file);
} catch (IOException e) {
e.printStackTrace();
}
}
public static String uploadImageForUrl(BufferedImage bufferedImage,String imgPath,String rqImg) throws IOException {
File file =new File(imgPath+rqImg);
if(!file.getParentFile().exists()){
file.getParentFile().mkdirs();
}
ImageIO.write(bufferedImage,"jpg",file);
rqImg=rqImg.replaceAll("\\\\","/");
return StaticPropUtil.imgUrl+rqImg;
}
public static String uploadImageForPath(BufferedImage bufferedImage,String imgPath,String rqImg) throws IOException {
File file =new File(imgPath+rqImg);
if(!file.getParentFile().exists()){
file.getParentFile().mkdirs();
}
ImageIO.write(bufferedImage,"jpg",file);
rqImg=(imgPath+rqImg).replace("\\","\\\\");
return rqImg;
}
public static BufferedImage drawRectangleAndText(BufferedImage image, double x1, double y1,double x2, double wid, double hei, String text1, String text2) {
// 创建一个Graphics2D对象
Graphics2D g2d = image.createGraphics();
// 设置抗锯齿
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// 创建一个Rectangle2D.Double对象
Rectangle2D.Double rect = new Rectangle2D.Double(x1, y1, wid, hei);
// 绘制红色框
g2d.setColor(Color.RED);
g2d.draw(rect);
// 设置粗线条
g2d.setStroke(new BasicStroke(3.0f * 30)); // 设置线条宽度为3.0f
// 设置字体和颜色
g2d.setFont(new Font("微软雅黑", Font.BOLD, 38)); // 使用支持中文的字体,增加字体大小
// 获取当前时间
String currentTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
// 获取文本的宽度和高度
FontMetrics fm = g2d.getFontMetrics();
// 绘制当前时间的背景矩形
int padding = 20;
int currentTimeWidth = fm.stringWidth(currentTime);
int currentTimeHeight = fm.getHeight();
int rectPadding = 5; // 背景矩形内边距
g2d.setColor(new Color(0, 0, 0, 50)); // 黑色半透明背景
g2d.fillRect(padding, padding, currentTimeWidth + 2 * rectPadding, currentTimeHeight + 2 * rectPadding);
// 绘制当前时间在左上角,内边距为20px
g2d.setColor(Color.WHITE);
int currentTimeX = padding + rectPadding + (currentTimeWidth + rectPadding - currentTimeWidth) / 2;
int currentTimeY = padding + rectPadding + fm.getAscent();
g2d.drawString(currentTime, currentTimeX, currentTimeY);
// 绘制文本2的背景矩形
int text2Width = fm.stringWidth(text2);
int text2Height = fm.getHeight();
g2d.setColor(new Color(0, 0, 0, 50)); // 黑色半透明背景
g2d.fillRect(padding, padding + currentTimeHeight + rectPadding * 2, text2Width + 2 * rectPadding, text2Height + 2 * rectPadding);
// 绘制文本2在时间的下面,内边距为20px
g2d.setColor(Color.WHITE);
int text2X = padding + rectPadding + (text2Width + rectPadding - text2Width) / 2;
int text2Y = padding + currentTimeHeight + rectPadding * 3 + fm.getAscent();
g2d.drawString(text2, text2X, text2Y);
// 计算文本1的右上角位置
int text1Width = fm.stringWidth(text1);
int text1X = (int) (x1 + wid); // 框的右上角位置
int text1Y = (int) (y1 + fm.getAscent()); // 框的右上角紧挨着框
g2d.setColor(Color.RED);
g2d.drawString(text1, text1X, text1Y);
// 释放资源
g2d.dispose();
return image;
}
public static void delFile(String url){
String filePath = url.replace(StaticPropUtil.imgUrl,StaticPropUtil.imgPath).replace("/","\\");
File file = new File(filePath);
if(file.exists()){
file.delete();
}
}
}

167
device_gather/src/main/java/com/xr/device/common/utils/ModbusUtils.java

@ -0,0 +1,167 @@
package com.xr.device.common.utils;
import com.serotonin.modbus4j.BatchRead;
import com.serotonin.modbus4j.BatchResults;
import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.exception.ErrorResponseException;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.serotonin.modbus4j.ip.IpParameters;
import com.serotonin.modbus4j.locator.BaseLocator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.Map;
import static java.lang.Thread.sleep;
public class ModbusUtils {
private static Logger log = LoggerFactory.getLogger(ModbusUtils.class);
private static Map<String,ModbusMaster> map=new HashMap<>();
/**
* 工厂
*/
static ModbusFactory modbusFactory;
static {
if (modbusFactory == null) {
modbusFactory = new ModbusFactory();
}
}
/**
* 获取master
*
* @return
* @throws ModbusInitException
*/
public static ModbusMaster getMaster(String host, int port) throws ModbusInitException {
IpParameters params = new IpParameters();
params.setHost(host);
params.setPort(port);
//
// modbusFactory.createRtuMaster(wapper); //RTU 协议
// modbusFactory.createUdpMaster(params);//UDP 协议
// modbusFactory.createAsciiMaster(wrapper);//ASCII 协议
ModbusMaster master = modbusFactory.createTcpMaster(params, false);// TCP 协议
master.init();
return master;
}
public static ModbusMaster getRtuIpMaster(String host, int port) throws ModbusInitException {
IpParameters params = new IpParameters();
params.setHost(host);
params.setPort(port);
params.setEncapsulated(true);
ModbusMaster master = modbusFactory.createTcpMaster(params, false);
try {
//设置超时时间
master.setTimeout(2000);
//设置重连次数
master.setRetries(2);
//初始化
master.init();
} catch (ModbusInitException e) {
e.printStackTrace();
}
return master;
}
/**
* 读取[01 Coil Status 0x]类型 开关数据
*
* @param slaveId 主机地址
* @param offset 寄存器地址
* @return 读取值
* @throws ModbusTransportException 异常
* @throws ErrorResponseException 异常
* @throws ModbusInitException 异常
*/
public static Boolean readCoilStatus(ModbusMaster master, int slaveId, int offset)
throws ModbusTransportException, ErrorResponseException, ModbusInitException {
// 01 Coil Status
BaseLocator<Boolean> loc = BaseLocator.coilStatus(slaveId, offset);
Boolean value = master.getValue(loc);
return value;
}
/**
* 读取[03 Holding Register类型 2x]模拟量数据
*
* @param slaveId 主机地址
* @param offset 寄存器地址
* @param dataType 数据类型,来自com.serotonin.modbus4j.code.DataType
* @return
* @throws ModbusTransportException 异常
* @throws ErrorResponseException 异常
* @throws ModbusInitException 异常
*/
public static Number readHoldingRegister(ModbusMaster master, int slaveId, int offset, int dataType)
throws ModbusTransportException, ErrorResponseException, ModbusInitException {
// 03 Holding Register类型数据读取
BaseLocator<Number> loc = BaseLocator.holdingRegister(slaveId, offset, dataType);
Number value = master.getValue(loc);
return value;
}
/**
* 读取[04 Input Registers 3x]类型 模拟量数据
*
* @param slaveId 主机地址
* @param offset 寄存器地址
* @param dataType 数据类型,来自com.serotonin.modbus4j.code.DataType
* @return 返回结果
* @throws ModbusTransportException 异常
* @throws ErrorResponseException 异常
* @throws ModbusInitException 异常
*/
public static Number readInputRegisters(ModbusMaster master, int slaveId, int offset, int dataType)
throws ModbusTransportException, ErrorResponseException, ModbusInitException {
// 04 Input Registers类型数据读取
BaseLocator<Number> loc = BaseLocator.inputRegister(slaveId, offset, dataType);
Number value = master.getValue(loc);
return value;
}
/**
* 批量读取使用寄存器数据
* @param master ModbusMaster对象
* @param batchRead 批量读取集合
* @throws ModbusTransportException
* @throws ErrorResponseException
* @throws ModbusInitException
*/
public static BatchResults<Integer> batchRead(ModbusMaster master, BatchRead<Integer> batchRead)throws Exception {
try {
batchRead.setContiguousRequests(false);
BatchResults<Integer> results = master.send(batchRead);
return results;
} catch (Exception e) {
log.error("批量读取使用寄存器数据出现异常"+e);
e.printStackTrace();
}
return null;
}
public static ModbusMaster getModbusMaster(String portName){
return map.get(portName);
}
public static void main(String[] args) {
try{
ModbusMaster modbusMaster= ModbusUtils.getMaster("192.168.1.105",1502);
while (true){
Number n = ModbusUtils.readHoldingRegister(modbusMaster, 1, 0, 4);
System.out.println(n);
sleep(1000);
}
}catch (Exception e){
e.printStackTrace();
}
}
}

205
device_gather/src/main/java/com/xr/device/common/utils/PythonExecutor.java

@ -0,0 +1,205 @@
package com.xr.device.common.utils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xr.device.model.entity.MeterInitialization;
import com.xr.device.model.service.MeterInitializationService;
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class PythonExecutor {
public static void main(String[] args) throws Exception {
try {
String pythonPath = StaticPropUtil.pythonPath;
ProcessBuilder processBuilder = new ProcessBuilder(pythonPath);
// 启动子进程
Process process = processBuilder.start();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
bw.write("import sys\n");
bw.write("sys.path.append(\"D:\\smartGrid\\smartGrid\\models\")\n");
bw.write("import indicatorLightStatus as ils\n");
bw.write("import switchRecognition as sr\n");
bw.write("import liquidLevel as ll\n");
bw.write("liquid_level_image_path = 'D:\\smartGrid\\smartGrid\\weights\\DIGITAL_METER (41).JPG'\n");
bw.write("ll.calculate_rgb_min_max([[112,\"D:\\smartGrid\\smartGrid\\weights\\DIGITAL_METER (41).JPG\"]])\n");
bw.write("print(\"Liquid level weights initialized.\")\n");
bw.write("liquid_level_image_path = 'D:\\smartGrid\\smartGrid\\weights\\DIGITAL_METER (10).JPG'\n");
bw.write("liquid_level = ll.calculate_liquid_level([112,liquid_level_image_path])\n");
bw.write("print(f\"Liquid level: {liquid_level}\")\n");
bw.close();
// 获取子进程的输出流
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
// 读取输出
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
// 等待进程执行完成
int exitCode = process.waitFor();
System.out.println("Exit Code: " + exitCode);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
private static boolean meterInit(String code) throws Exception {
String pythonPath = StaticPropUtil.pythonPath;
String modelPath = StaticPropUtil.modelPath;
ProcessBuilder processBuilder = new ProcessBuilder(pythonPath);
// 启动子进程
Process process = processBuilder.start();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
bw.write("import sys\n");
String imports = "sys.path.append(\"%s\")\n";
bw.write(String.format(imports, modelPath));
bw.write("import indicatorLightStatus as ils\n");
bw.write("import switchRecognition as sr\n");
bw.write("import liquidLevel as ll\n");
bw.write(code);
bw.write("print(\"success\")\n");
bw.close();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
List<String> list = new ArrayList<>();
String line;
// 读取输出
while ((line = reader.readLine()) != null) {
list.add(line);
}
// 等待进程执行完成
int exitCode = process.waitFor();
System.out.println("Exit Code: " + exitCode);
if (list.contains("success")) {
return true;
}
return false;
}
/**
* 初始化算法
* id 表计配置ID
* sfType 4 灯光 3 开关 5 液位计
*/
public static boolean meterInit(Integer id, String sfType) throws Exception {
MeterInitializationService meterInitializationService = SpringUtils.getBean(MeterInitializationService.class);
QueryWrapper<MeterInitialization> query = new QueryWrapper<>();
query.eq("meter_id", id);
query.orderByAsc("serial");
List<MeterInitialization> list = meterInitializationService.list(query);
List<String> path = list.stream().map(n -> n.getImgAddress()).collect(Collectors.toList());
String ph = "";
for (String str : path) {
str = str.replace("\\", "\\\\");
ph += "\"" + str + "\"" + ",";
}
ph = ph.substring(0, ph.length() - 1);
String code = "";
if (sfType.equals("4")) {
List<List<Object>> list1 = new ArrayList<>();
List<Object> list2 = new ArrayList<>();
list2.add(id);
List<String> list3 = new ArrayList<>();
list3.add(ph);
list2.add(list3);
list1.add(list2);
code = "ils.calculate_luminance_threshold(" + Arrays.toString(list1.toArray()) + ")\n";
}
if (sfType.equals("3")) {
List<String> list1 = new ArrayList<>();
path.add(0, id + "");
list1.add(ph);
code = "sr.initialize(" + Arrays.toString(list1.toArray()) + ")\n";
}
if (sfType.equals("5")) {
List<String> list1 = new ArrayList<>();
path.add(0, id + "");
list1.add(ph);
code = "ll.calculate_rgb_min_max(" + Arrays.toString(list1.toArray()) + ")\n";
}
return meterInit(code);
}
/**
* 读取结果
* id 表计id
* path 图片路径
* sfType 1 灯光 2 开关 3 液位计 4 指针
*/
public static String readNumber(Integer id, String path, String sfType) throws Exception {
String pythonPath = StaticPropUtil.pythonPath;
String modelPath = StaticPropUtil.modelPath;
ProcessBuilder processBuilder = new ProcessBuilder(pythonPath);
// 启动子进程
Process process = processBuilder.start();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
bw.write("import sys\n");
String imports = "sys.path.append(\"%s\")\n";
bw.write(String.format(imports, modelPath));
bw.write("import indicatorLightStatus as ils\n");
bw.write("import switchRecognition as sr\n");
bw.write("import liquidLevel as ll\n");
bw.write("indicator_light_image_path = '" + path + "'\n");
if (sfType.equals("4")) {
bw.write("value = ils.check_indicator_light_status(" + id + ",indicator_light_image_path)\n");
}
if (sfType.equals("3")) {
bw.write("value = sr.read_numbers(" + id + ",indicator_light_image_path)\n");
}
if (sfType.equals("5")) {
bw.write("value = ll.calculate_liquid_level([" + id + ",indicator_light_image_path])\n");
}
if (sfType.equals("0")) {
bw.write("rotate_angle, value = pr.getPointerAngleAndNum(" + id + ", indicator_light_image_path)\n");
}
bw.write("print(f\"value:{value}\")");
bw.close();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
List<String> list = new ArrayList<>();
String line;
// 读取输出
while ((line = reader.readLine()) != null) {
list.add(line);
}
// if(list.contains("value")){
// String value = list.get(list.indexOf("value")).split(":")[1];
// File file = new File(path);
// if(file.exists()){
// file.delete();
// }
// return value;
// }
for (String element : list) {
if (element.contains("value")) {
String[] parts = element.split(":");
File file = new File(path);
if (file.exists()) {
file.delete();
}
if (parts.length > 1) {
String result = parts[1].trim();
return result;
}
}
}
return null;
}
}

151
device_gather/src/main/java/com/xr/device/common/utils/SpringUtils.java

@ -0,0 +1,151 @@
package com.xr.device.common.utils;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class SpringUtils implements BeanFactoryPostProcessor, ApplicationContextAware {
/** Spring应用上下文环境 */
private static ConfigurableListableBeanFactory beanFactory;
private static ApplicationContext applicationContext;
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException
{
SpringUtils.beanFactory = beanFactory;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
{
SpringUtils.applicationContext = applicationContext;
}
/**
* 获取对象
*
* @param name
* @return Object 一个以所给名字注册的bean的实例
* @throws BeansException
*
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(String name) throws BeansException
{
return (T) beanFactory.getBean(name);
}
/**
* 获取类型为requiredType的对象
*
* @param clz
* @return
* @throws BeansException
*
*/
public static <T> T getBean(Class<T> clz) throws BeansException
{
T result = (T) beanFactory.getBean(clz);
return result;
}
/**
* 如果BeanFactory包含一个与所给名称匹配的bean定义则返回true
*
* @param name
* @return boolean
*/
public static boolean containsBean(String name)
{
return beanFactory.containsBean(name);
}
/**
* 判断以给定名字注册的bean定义是一个singleton还是一个prototype 如果与给定名字相应的bean定义没有被找到将会抛出一个异常NoSuchBeanDefinitionException
*
* @param name
* @return boolean
* @throws NoSuchBeanDefinitionException
*
*/
public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException
{
return beanFactory.isSingleton(name);
}
/**
* @param name
* @return Class 注册对象的类型
* @throws NoSuchBeanDefinitionException
*
*/
public static Class<?> getType(String name) throws NoSuchBeanDefinitionException
{
return beanFactory.getType(name);
}
/**
* 如果给定的bean名字在bean定义中有别名则返回这些别名
*
* @param name
* @return
* @throws NoSuchBeanDefinitionException
*
*/
public static String[] getAliases(String name) throws NoSuchBeanDefinitionException
{
return beanFactory.getAliases(name);
}
/**
* 获取aop代理对象
*
* @param invoker
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T getAopProxy(T invoker)
{
return (T) AopContext.currentProxy();
}
/**
* 获取当前的环境配置无配置返回null
*
* @return 当前的环境配置
*/
public static String[] getActiveProfiles()
{
return applicationContext.getEnvironment().getActiveProfiles();
}
/**
* 获取当前的环境配置当有多个环境配置时只获取第一个
*
* @return 当前的环境配置
*/
public static String getActiveProfile()
{
final String[] activeProfiles = getActiveProfiles();
return StringUtils.isNotEmpty(activeProfiles) ? activeProfiles[0] : null;
}
/**
* 获取配置文件中的值
*
* @param key 配置文件的key
* @return 当前的配置文件的值
*
*/
public static String getRequiredProperty(String key)
{
return applicationContext.getEnvironment().getRequiredProperty(key);
}
}

26
device_gather/src/main/java/com/xr/device/common/utils/StaticPropUtil.java

@ -0,0 +1,26 @@
package com.xr.device.common.utils;
import com.xr.device.common.configvalue.StaticProperties;
public class StaticPropUtil {
public static String imgUrl;
public static String imgPath;
public static String pythonPath;
public static String modelPath;
public static Integer stationId;
public static void initDingDingProp(StaticProperties dingProperties){
imgUrl = dingProperties.getImgUrl();
imgPath = dingProperties.getImgPath();
pythonPath = dingProperties.getPythonPath();
modelPath = dingProperties.getModelPath();
stationId = dingProperties.getStationId();
}
}

90
device_gather/src/main/java/com/xr/device/common/utils/StrFormatter.java

@ -0,0 +1,90 @@
package com.xr.device.common.utils;
/**
* 字符串格式化
*
* @author ruoyi
*/
public class StrFormatter
{
public static final String EMPTY_JSON = "{}";
public static final char C_BACKSLASH = '\\';
public static final char C_DELIM_START = '{';
public static final char C_DELIM_END = '}';
/**
* 格式化字符串<br>
* 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
* 如果想输出 {} 使用 \\转义 { 即可如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
* <br>
* 通常使用format("this is {} for {}", "a", "b") -> this is a for b<br>
* 转义{} format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
* 转义\ format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
*
* @param strPattern 字符串模板
* @param argArray 参数列表
* @return 结果
*/
public static String format(final String strPattern, final Object... argArray)
{
if (StringUtils.isEmpty(strPattern) || StringUtils.isEmpty(argArray))
{
return strPattern;
}
final int strPatternLength = strPattern.length();
// 初始化定义好的长度以获得更好的性能
StringBuilder sbuf = new StringBuilder(strPatternLength + 50);
int handledPosition = 0;
int delimIndex;// 占位符所在位置
for (int argIndex = 0; argIndex < argArray.length; argIndex++)
{
delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition);
if (delimIndex == -1)
{
if (handledPosition == 0)
{
return strPattern;
}
else
{ // 字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果
sbuf.append(strPattern, handledPosition, strPatternLength);
return sbuf.toString();
}
}
else
{
if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH)
{
if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH)
{
// 转义符之前还有一个转义符,占位符依旧有效
sbuf.append(strPattern, handledPosition, delimIndex - 1);
sbuf.append(Convert.utf8Str(argArray[argIndex]));
handledPosition = delimIndex + 2;
}
else
{
// 占位符被转义
argIndex--;
sbuf.append(strPattern, handledPosition, delimIndex - 1);
sbuf.append(C_DELIM_START);
handledPosition = delimIndex + 1;
}
}
else
{
// 正常占位符
sbuf.append(strPattern, handledPosition, delimIndex);
sbuf.append(Convert.utf8Str(argArray[argIndex]));
handledPosition = delimIndex + 2;
}
}
}
// 加入最后一个占位符后所有的字符
sbuf.append(strPattern, handledPosition, strPattern.length());
return sbuf.toString();
}
}

607
device_gather/src/main/java/com/xr/device/common/utils/StringUtils.java

@ -0,0 +1,607 @@
package com.xr.device.common.utils;
import org.springframework.util.AntPathMatcher;
import java.util.*;
/**
* 字符串工具类
*
* @author ruoyi
*/
public class StringUtils extends org.apache.commons.lang3.StringUtils
{
/** 空字符串 */
private static final String NULLSTR = "";
/** 下划线 */
private static final char SEPARATOR = '_';
/**
* 获取参数不为空值
*
* @param value defaultValue 要判断的value
* @return value 返回值
*/
public static <T> T nvl(T value, T defaultValue)
{
return value != null ? value : defaultValue;
}
/**
* * 判断一个Collection是否为空 包含ListSetQueue
*
* @param coll 要判断的Collection
* @return true为空 false非空
*/
public static boolean isEmpty(Collection<?> coll)
{
return isNull(coll) || coll.isEmpty();
}
/**
* * 判断一个Collection是否非空包含ListSetQueue
*
* @param coll 要判断的Collection
* @return true非空 false
*/
public static boolean isNotEmpty(Collection<?> coll)
{
return !isEmpty(coll);
}
/**
* * 判断一个对象数组是否为空
*
* @param objects 要判断的对象数组
** @return true为空 false非空
*/
public static boolean isEmpty(Object[] objects)
{
return isNull(objects) || (objects.length == 0);
}
/**
* * 判断一个对象数组是否非空
*
* @param objects 要判断的对象数组
* @return true非空 false
*/
public static boolean isNotEmpty(Object[] objects)
{
return !isEmpty(objects);
}
/**
* * 判断一个Map是否为空
*
* @param map 要判断的Map
* @return true为空 false非空
*/
public static boolean isEmpty(Map<?, ?> map)
{
return isNull(map) || map.isEmpty();
}
/**
* * 判断一个Map是否为空
*
* @param map 要判断的Map
* @return true非空 false
*/
public static boolean isNotEmpty(Map<?, ?> map)
{
return !isEmpty(map);
}
/**
* * 判断一个字符串是否为空串
*
* @param str String
* @return true为空 false非空
*/
public static boolean isEmpty(String str)
{
return isNull(str) || NULLSTR.equals(str.trim());
}
/**
* * 判断一个字符串是否为非空串
*
* @param str String
* @return true非空串 false空串
*/
public static boolean isNotEmpty(String str)
{
return !isEmpty(str);
}
/**
* * 判断一个对象是否为空
*
* @param object Object
* @return true为空 false非空
*/
public static boolean isNull(Object object)
{
return object == null;
}
/**
* * 判断一个对象是否非空
*
* @param object Object
* @return true非空 false
*/
public static boolean isNotNull(Object object)
{
return !isNull(object);
}
/**
* * 判断一个对象是否是数组类型Java基本型别的数组
*
* @param object 对象
* @return true是数组 false不是数组
*/
public static boolean isArray(Object object)
{
return isNotNull(object) && object.getClass().isArray();
}
/**
* 去空格
*/
public static String trim(String str)
{
return (str == null ? "" : str.trim());
}
/**
* 截取字符串
*
* @param str 字符串
* @param start 开始
* @return 结果
*/
public static String substring(final String str, int start)
{
if (str == null)
{
return NULLSTR;
}
if (start < 0)
{
start = str.length() + start;
}
if (start < 0)
{
start = 0;
}
if (start > str.length())
{
return NULLSTR;
}
return str.substring(start);
}
/**
* 截取字符串
*
* @param str 字符串
* @param start 开始
* @param end 结束
* @return 结果
*/
public static String substring(final String str, int start, int end)
{
if (str == null)
{
return NULLSTR;
}
if (end < 0)
{
end = str.length() + end;
}
if (start < 0)
{
start = str.length() + start;
}
if (end > str.length())
{
end = str.length();
}
if (start > end)
{
return NULLSTR;
}
if (start < 0)
{
start = 0;
}
if (end < 0)
{
end = 0;
}
return str.substring(start, end);
}
/**
* 格式化文本, {} 表示占位符<br>
* 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
* 如果想输出 {} 使用 \\转义 { 即可如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
* <br>
* 通常使用format("this is {} for {}", "a", "b") -> this is a for b<br>
* 转义{} format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
* 转义\ format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
*
* @param template 文本模板被替换的部分用 {} 表示
* @param params 参数值
* @return 格式化后的文本
*/
public static String format(String template, Object... params)
{
if (isEmpty(params) || isEmpty(template))
{
return template;
}
return StrFormatter.format(template, params);
}
/**
* 是否为http(s)://开头
*
* @param link 链接
* @return 结果
*/
public static boolean ishttp(String link)
{
return StringUtils.startsWithAny(link,"http://", "https://");
}
/**
* 字符串转set
*
* @param str 字符串
* @param sep 分隔符
* @return set集合
*/
public static final Set<String> str2Set(String str, String sep)
{
return new HashSet<String>(str2List(str, sep, true, false));
}
/**
* 字符串转list
*
* @param str 字符串
* @param sep 分隔符
* @param filterBlank 过滤纯空白
* @param trim 去掉首尾空白
* @return list集合
*/
public static final List<String> str2List(String str, String sep, boolean filterBlank, boolean trim)
{
List<String> list = new ArrayList<String>();
if (StringUtils.isEmpty(str))
{
return list;
}
// 过滤空白字符串
if (filterBlank && StringUtils.isBlank(str))
{
return list;
}
String[] split = str.split(sep);
for (String string : split)
{
if (filterBlank && StringUtils.isBlank(string))
{
continue;
}
if (trim)
{
string = string.trim();
}
list.add(string);
}
return list;
}
/**
* 判断给定的set列表中是否包含数组array 判断给定的数组array中是否包含给定的元素value
* @param array 给定的数组
* @return boolean 结果
*/
public static boolean containsAny(Collection<String> collection, String... array)
{
if (isEmpty(collection) || isEmpty(array))
{
return false;
}
else
{
for (String str : array)
{
if (collection.contains(str))
{
return true;
}
}
return false;
}
}
/**
* 查找指定字符串是否包含指定字符串列表中的任意一个字符串同时串忽略大小写
*
* @param cs 指定字符串
* @param searchCharSequences 需要检查的字符串数组
* @return 是否包含任意一个字符串
*/
public static boolean containsAnyIgnoreCase(CharSequence cs, CharSequence... searchCharSequences)
{
if (isEmpty(cs) || isEmpty(searchCharSequences))
{
return false;
}
for (CharSequence testStr : searchCharSequences)
{
if (containsIgnoreCase(cs, testStr))
{
return true;
}
}
return false;
}
/**
* 驼峰转下划线命名
*/
public static String toUnderScoreCase(String str)
{
if (str == null)
{
return null;
}
StringBuilder sb = new StringBuilder();
// 前置字符是否大写
boolean preCharIsUpperCase = true;
// 当前字符是否大写
boolean curreCharIsUpperCase = true;
// 下一字符是否大写
boolean nexteCharIsUpperCase = true;
for (int i = 0; i < str.length(); i++)
{
char c = str.charAt(i);
if (i > 0)
{
preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1));
}
else
{
preCharIsUpperCase = false;
}
curreCharIsUpperCase = Character.isUpperCase(c);
if (i < (str.length() - 1))
{
nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1));
}
if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase)
{
sb.append(SEPARATOR);
}
else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase)
{
sb.append(SEPARATOR);
}
sb.append(Character.toLowerCase(c));
}
return sb.toString();
}
/**
* 是否包含字符串
*
* @param str 验证字符串
* @param strs 字符串组
* @return 包含返回true
*/
public static boolean inStringIgnoreCase(String str, String... strs)
{
if (str != null && strs != null)
{
for (String s : strs)
{
if (str.equalsIgnoreCase(trim(s)))
{
return true;
}
}
}
return false;
}
/**
* 将下划线大写方式命名的字符串转换为驼峰式如果转换前的下划线大写方式命名的字符串为空则返回空字符串 例如HELLO_WORLD->HelloWorld
*
* @param name 转换前的下划线大写方式命名的字符串
* @return 转换后的驼峰式命名的字符串
*/
public static String convertToCamelCase(String name)
{
StringBuilder result = new StringBuilder();
// 快速检查
if (name == null || name.isEmpty())
{
// 没必要转换
return "";
}
else if (!name.contains("_"))
{
// 不含下划线,仅将首字母大写
return name.substring(0, 1).toUpperCase() + name.substring(1);
}
// 用下划线将原始字符串分割
String[] camels = name.split("_");
for (String camel : camels)
{
// 跳过原始字符串中开头、结尾的下换线或双重下划线
if (camel.isEmpty())
{
continue;
}
// 首字母大写
result.append(camel.substring(0, 1).toUpperCase());
result.append(camel.substring(1).toLowerCase());
}
return result.toString();
}
/**
* 驼峰式命名法
* 例如user_name->userName
*/
public static String toCamelCase(String s)
{
if (s == null)
{
return null;
}
if (s.indexOf(SEPARATOR) == -1)
{
return s;
}
s = s.toLowerCase();
StringBuilder sb = new StringBuilder(s.length());
boolean upperCase = false;
for (int i = 0; i < s.length(); i++)
{
char c = s.charAt(i);
if (c == SEPARATOR)
{
upperCase = true;
}
else if (upperCase)
{
sb.append(Character.toUpperCase(c));
upperCase = false;
}
else
{
sb.append(c);
}
}
return sb.toString();
}
/**
* 查找指定字符串是否匹配指定字符串列表中的任意一个字符串
*
* @param str 指定字符串
* @param strs 需要检查的字符串数组
* @return 是否匹配
*/
public static boolean matches(String str, List<String> strs)
{
if (isEmpty(str) || isEmpty(strs))
{
return false;
}
for (String pattern : strs)
{
if (isMatch(pattern, str))
{
return true;
}
}
return false;
}
/**
* 判断url是否与规则配置:
* ? 表示单个字符;
* * 表示一层路径内的任意字符串不可跨层级;
* ** 表示任意层路径;
*
* @param pattern 匹配规则
* @param url 需要匹配的url
* @return
*/
public static boolean isMatch(String pattern, String url)
{
AntPathMatcher matcher = new AntPathMatcher();
return matcher.match(pattern, url);
}
@SuppressWarnings("unchecked")
public static <T> T cast(Object obj)
{
return (T) obj;
}
/**
* 数字左边补齐0使之达到指定长度注意如果数字转换为字符串后长度大于size则只保留 最后size个字符
*
* @param num 数字对象
* @param size 字符串指定长度
* @return 返回数字的字符串格式该字符串为指定长度
*/
public static final String padl(final Number num, final int size)
{
return padl(num.toString(), size, '0');
}
/**
* 字符串左补齐如果原始字符串s长度大于size则只保留最后size个字符
*
* @param s 原始字符串
* @param size 字符串指定长度
* @param c 用于补齐的字符
* @return 返回指定长度的字符串由原字符串左补齐或截取得到
*/
public static final String padl(final String s, final int size, final char c)
{
final StringBuilder sb = new StringBuilder(size);
if (s != null)
{
final int len = s.length();
if (s.length() <= size)
{
for (int i = size - len; i > 0; i--)
{
sb.append(c);
}
sb.append(s);
}
else
{
return s.substring(len - size, len);
}
}
else
{
for (int i = size; i > 0; i--)
{
sb.append(c);
}
}
return sb.toString();
}
}

187
device_gather/src/main/java/com/xr/device/common/utils/UploadUtil.java

@ -0,0 +1,187 @@
package com.xr.device.common.utils;
import org.apache.poi.ss.usermodel.Workbook;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Date;
public class UploadUtil {
public static String uploadExcel(Workbook workbook,String path,String url1,String fileName) throws Exception{
FileOutputStream outputStream =new FileOutputStream(path+fileName);
workbook.write(outputStream);
outputStream.close();
String url = url1+fileName;
return url;
}
public static String uploadImage(String clentIp,Integer configId,String fileName) throws Exception {
// 构建完整的路径
String url = "http://"+clentIp+":8080/tao/snapshot";
SimpleDateFormat sim=new SimpleDateFormat("yyyy-MM-dd-HH");
String date = sim.format(new Date());
String dates[] = date.split("-");
String year = dates[0];
String month = dates[1];
String day = dates[2];
String ho = dates[3];
String fullPath = StaticPropUtil.imgPath+configId + File.separator + year + File.separator + month + File.separator + day + File.separator +ho+File.separator+ fileName;
// 创建目录结构
Path directoryPath = Paths.get(StaticPropUtil.imgPath,configId.toString(), year, month, day,ho);
if (!Files.exists(directoryPath)) {
Files.createDirectories(directoryPath);
}
downloadImage(url,fullPath);
// 构建URL
String url1 = StaticPropUtil.imgUrl+ configId + "/" + year + "/"+ month + "/" + day + "/" +ho+"/"+ fileName;
return url1;
}
public static String uploadImage(BufferedImage buffer,Integer configId,String fileName) throws Exception {
// 构建完整的路径
SimpleDateFormat sim=new SimpleDateFormat("yyyy-MM-dd-HH");
String date = sim.format(new Date());
String dates[] = date.split("-");
String year = dates[0];
String month = dates[1];
String day = dates[2];
String ho = dates[3];
String fullPath = StaticPropUtil.imgPath+configId + File.separator + year + File.separator + month + File.separator + day + File.separator +ho+File.separator+ fileName;
// 创建目录结构
Path directoryPath = Paths.get(StaticPropUtil.imgPath,configId.toString(), year, month, day,ho);
if (!Files.exists(directoryPath)) {
Files.createDirectories(directoryPath);
}
downloadImage(buffer,fullPath);
// 构建URL
String url1 = StaticPropUtil.imgUrl+ configId + "/" + year + "/"+ month + "/" + day + "/" +ho+"/"+ fileName;
return url1;
}
public static BufferedImage urlByImage(String url) throws IOException {
URL urlfile = new URL(url);
InputStream is2 = urlfile.openStream();
BufferedImage uImg= ImageIO.read(is2);
return uImg;
}
public static void delFile(String path,String url,String fileUrl){
String filePath = fileUrl.replace(url,path).replace("/","\\");
File file = new File(filePath);
if(file.exists()){
file.delete();
}
}
public static void downloadImage(String imageUrl, String destinationPath) throws IOException {
URL url = new URL(imageUrl);
try (InputStream in = url.openStream();
FileOutputStream out = new FileOutputStream(destinationPath)) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
}
}
public static void downloadImage(BufferedImage bufferedImage, String destinationPath) throws IOException {
File file = new File(destinationPath);
ImageIO.write(bufferedImage,"jpg",file);
}
public static BufferedImage drawRectangleAndText(BufferedImage image, double x1, double y1,double x2, double wid, double hei, String text1, String text2) {
// 创建一个Graphics2D对象
Graphics2D g2d = image.createGraphics();
// 设置抗锯齿
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// 创建一个Rectangle2D.Double对象
Rectangle2D.Double rect = new Rectangle2D.Double(x1, y1, wid, hei);
// 绘制红色框
g2d.setColor(Color.RED);
g2d.draw(rect);
// 设置粗线条
g2d.setStroke(new BasicStroke(3.0f * 30)); // 设置线条宽度为3.0f
// 设置字体和颜色
g2d.setFont(new Font("微软雅黑", Font.BOLD, 38)); // 使用支持中文的字体,增加字体大小
// 获取当前时间
String currentTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
// 获取文本的宽度和高度
FontMetrics fm = g2d.getFontMetrics();
// 绘制当前时间的背景矩形
int padding = 20;
int currentTimeWidth = fm.stringWidth(currentTime);
int currentTimeHeight = fm.getHeight();
int rectPadding = 5; // 背景矩形内边距
g2d.setColor(new Color(0, 0, 0, 50)); // 黑色半透明背景
g2d.fillRect(padding, padding, currentTimeWidth + 2 * rectPadding, currentTimeHeight + 2 * rectPadding);
// 绘制当前时间在左上角,内边距为20px
g2d.setColor(Color.WHITE);
int currentTimeX = padding + rectPadding + (currentTimeWidth + rectPadding - currentTimeWidth) / 2;
int currentTimeY = padding + rectPadding + fm.getAscent();
g2d.drawString(currentTime, currentTimeX, currentTimeY);
// 绘制文本2的背景矩形
if(text2!=null){
int text2Width = fm.stringWidth(text2);
int text2Height = fm.getHeight();
g2d.setColor(new Color(0, 0, 0, 50)); // 黑色半透明背景
g2d.fillRect(padding, padding + currentTimeHeight + rectPadding * 2, text2Width + 2 * rectPadding, text2Height + 2 * rectPadding);
// 绘制文本2在时间的下面,内边距为20px
g2d.setColor(Color.WHITE);
int text2X = padding + rectPadding + (text2Width + rectPadding - text2Width) / 2;
int text2Y = padding + currentTimeHeight + rectPadding * 3 + fm.getAscent();
g2d.drawString(text2, text2X, text2Y);
}
// 计算文本1的右上角位置
int text1X = (int) (x1 + wid); // 框的右上角位置
int text1Y = (int) (y1 + fm.getAscent()); // 框的右上角紧挨着框
g2d.setColor(Color.RED);
g2d.drawString(text1, text1X, text1Y);
// 释放资源
g2d.dispose();
return image;
}
}

80
device_gather/src/main/java/com/xr/device/common/utils/ValueFormatUtil.java

@ -0,0 +1,80 @@
package com.xr.device.common.utils;
import com.xr.device.model.entity.MeterConfig;
import com.xr.device.model.service.MeterConfigService;
public class ValueFormatUtil {
/*
* 处理AI分析的计数器数值针对可以识别到但偶尔有错误结果出现的情况
* 1.抄写基准值
* 2.与基准值比较如果比基准值大于1可能计数器跳1更新基准值并返回结果
* 反之返回基准值结果为识别结果
* 3.如果未设基准值去0后保存结果
* */
public static String getNumBerJx(float getVal, MeterConfig config, MeterConfigService meterConfigService){
int s = (int) getVal;
Integer jz = Integer.valueOf(config.getJzVal())+1;
if(StringUtils.isNotEmpty(config.getJzVal())){
if(s==jz){
config.setJzVal(jz+"");
meterConfigService.updateById(config);
return jz+"";
}else{
return config.getJzVal();
}
}else{
return s+"";
}
}
public static String getYwj(float f,MeterConfig config){//处理液位计识别结果
if((f == 0 || f>1)&& StringUtils.isNotEmpty(config.getJzVal())){
return config.getJzVal();
}else{
return String.format("%.2f", f*100)+"%";
}
}
public static String getZZl(float f,MeterConfig config){//处理指针类识别结果
if(f ==0 && StringUtils.isNotEmpty(config.getJzVal())){
return config.getJzVal();
}else{
return String.format("%.2f", f);
}
}
public static String getDw(float f){
int s = Math.round(f);
if(s>8){
int t = s-8;
if(t<9){
return t+"";
}
if(t == 9){
return "9A";
}
if(t == 10){
return "9B";
}
if(t == 11){
return "9C";
}
if(t>11){
return t-2+"";
}
}
return s+"";
}
public static String getfdjsq(float f){
int s = Math.round(f);
if(s>=10){
return 0+"";
}else {
return s+"";
}
}
}

126
device_gather/src/main/java/com/xr/device/model/entity/DeviceCamera.java

@ -0,0 +1,126 @@
package com.xr.device.model.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDateTime;
import lombok.Data;
/**
*
* @TableName device_camera
*/
@TableName(value ="device_camera")
@Data
public class DeviceCamera implements Serializable {
/**
* 主键
*/
@TableId(type = IdType.AUTO)
private Integer id;
/**
* 摄像头编号
*/
private String deviceNo;
/**
* 类型(1 usb 2 mipi 3 球机 4 枪机)
*/
private String deviceType;
/**
* IP
*/
private String deviceIp;
/**
* 端口
*/
private String devicePort;
/**
* 账号
*/
private String account;
/**
* 密码
*/
private String password;
/**
* x轴
*/
private String x;
/**
* y轴
*/
private String y;
/**
* z轴
*/
private String z;
/**
* 摄像头型号
*/
private String deviceModel;
/**
* 安装位置
*/
private String position;
/**
* 品牌
*/
private String brand;
/**
* 备注
*/
private String remarks;
/**
* 状态(0未使用 1已使用)
*/
private String status;
/**
* 创建人
*/
private String createUser;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 修改人
*/
private String updateUser;
/**
* 修改时间
*/
private LocalDateTime updateTime;
/**
* 传输间隔
*/
private Integer transmissionInterval;
/**
* 对焦时间
*/
private Integer warmup;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}

141
device_gather/src/main/java/com/xr/device/model/entity/FocalLengthConfig.java

@ -0,0 +1,141 @@
package com.xr.device.model.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDateTime;
import lombok.Data;
/**
*
* @TableName focal_length_config
*/
@TableName(value ="focal_length_config")
@Data
public class FocalLengthConfig implements Serializable {
/**
* 主键
*/
@TableId(type = IdType.AUTO)
private Integer id;
/**
* 表计配置编号
*/
private Integer configId;
/**
* 焦距名称
*/
private String focalName;
/**
* 焦距tabs下标
*/
private String focalIndex;
/**
* 截图框宽
*/
private Double copperWid;
/**
* 截图框高
*/
private Double copperHei;
/**
* 截图框X坐标
*/
private Double copperX;
/**
*
*/
private Double copperX2;
/**
* 截图框Y坐标
*/
private Double copperY;
/**
*
*/
private Double copperY2;
/**
* 1指针表计,2数字表计,3状态类
*/
private String configType;
/**
* 指针最小值
*/
private Double meterMin;
/**
* 指针最大值
*/
private Double meterMax;
/**
* 旋转角度
*/
private Integer rotate;
/**
* 缩放倍数
*/
private Double scale;
/**
* 状态类状态数量
*/
private Integer stateNum;
/**
* 保存状态类多个状态的结果集
*/
private String parameter;
/**
* 解析得测试结果
*/
private String result;
/**
* 算法0圆形表计1扇形表计
*/
private Integer algorithm;
/**
* 创建人
*/
private String createUser;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 修改人
*/
private String updateUser;
/**
* 修改时间
*/
private LocalDateTime updateTime;
/**
* 焦距图片
*/
private byte[] focalPicture;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}

183
device_gather/src/main/java/com/xr/device/model/entity/MeterConfig.java

@ -0,0 +1,183 @@
package com.xr.device.model.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Date;
import lombok.Data;
/**
*
* @TableName meter_config
*/
@TableName(value ="meter_config")
@Data
public class MeterConfig implements Serializable {
/**
* 主键
*/
@TableId(type = IdType.AUTO)
private Integer id;
/**
* ids5000表id
*/
private Integer ids5000Id;
/**
* 间隔类型 1 分钟 2 小时 3
*/
private Integer intervalType;
/**
* 电压等级(1安全电压2低压3高压4超高压5特高压)
*/
private String voltageClass;
/**
* 所属间隔
*/
private String owningInterval;
/**
* 识别间隔
*/
private String identificationInterval;
/**
* 所属设备
*/
private String deviceName;
/**
* y坐标
*/
private Double locationY;
/**
* x坐标
*/
private Double locationX;
/**
* 设备类型
*/
private String deviceType;
/**
* 表计编号
*/
private String meterCode;
/**
* 表计名称
*/
private String meterName;
/**
* 所属摄像头
*/
private Integer cameraId;
/**
* 告警最小值
*/
private Double warningMax;
/**
* 告警最大值
*/
private Double warningMin;
/**
* 表计类型配置编号
*/
private Integer typeId;
/**
* 状态(0停用1启用)
*/
private Integer status;
/**
* 首次识别时间
*/
private Date firstTime;
/**
* 算法类型 1usb2mipi 3内部算法
*/
private String algorithmType;
/**
* 执行间隔时间
*/
private Integer intervalTime;
/**
* 焦距数量
*/
private Integer focalNumber;
/**
* 超参配置
*/
private String parameterConfig;
/**
* 备注
*/
private String remarks;
/**
* 61850读数模型
*/
private String iec61850mx;
/**
* 1校准 其他不校准
*/
private Integer isJz;
/**
* 校准值
*/
private String jzVal;
/**
* 0 未初始化 1已初始化
*/
private String initStatus;
/**
* 创建人
*/
private String createUser;
/**
* 创建时间
*/
private Date createTime;
/**
* 修改人
*/
private String updateUser;
/**
* 修改时间
*/
private Date updateTime;
@TableField(exist = false)
private String deviceIp;
@TableField(exist = false)
private String meterType;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}

50
device_gather/src/main/java/com/xr/device/model/entity/MeterInitialization.java

@ -0,0 +1,50 @@
package com.xr.device.model.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import lombok.Data;
/**
* 表计算法初始化
* @TableName meter_initialization
*/
@TableName(value ="meter_initialization")
@Data
public class MeterInitialization implements Serializable {
/**
* id
*/
@TableId(type = IdType.AUTO)
private Integer id;
/**
* 请求图片路径
*/
private String img;
/**
* 盘符路径
*/
private String imgAddress;
/**
* 常量值
*/
private String value;
/**
* 表计id
*/
private Integer meterId;
/**
* 序号(从0开始)
*/
private Integer serial;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}

97
device_gather/src/main/java/com/xr/device/model/entity/MeterReadingRecord.java

@ -0,0 +1,97 @@
package com.xr.device.model.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Date;
import lombok.Data;
/**
*
* @TableName meter_reading_record
*/
@TableName(value ="meter_reading_record")
@Data
public class MeterReadingRecord implements Serializable {
/**
* 主键id
*/
@TableId(type = IdType.AUTO)
private Integer id;
/**
* 表计id
*/
private Integer meterId;
/**
* 表计编号
*/
private String meterCode;
/**
* 表计类型id
*/
private Integer meterTypeId;
/**
* 表计类型名称
*/
private String meterTypeName;
/**
* 所属间隔
*/
private String owningInterval;
/**
* 读数时间
*/
private Date readingTime;
/**
* 读数类型1 一体化电源 2 AI摄像头 3 串口
*/
private Integer readingType;
/**
* 0 遥控 1遥信 2遥测
*/
private Integer dataType;
/**
* 读数值
*/
private String readingValue;
/**
* 表计照片
*/
private String readingUrl;
/**
* 创建人
*/
private String createUser;
/**
* 创建时间
*/
private Date createTime;
/**
* 修改人
*/
private String updateUser;
/**
* 修改时间
*/
private Date updateTime;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}

86
device_gather/src/main/java/com/xr/device/model/entity/MeterType.java

@ -0,0 +1,86 @@
package com.xr.device.model.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDateTime;
import lombok.Data;
/**
* 表计类型表
* @TableName meter_type
*/
@TableName(value ="meter_type")
@Data
public class MeterType implements Serializable {
/**
* 主键
*/
@TableId(type = IdType.AUTO)
private Integer id;
/**
* 表计类型名称
*/
private String meterType;
/**
* 表计形状(0圆形指针1扇形指针2数字类表计3开关类表计4灯类表计5液位计)
*/
private String meterShape;
/**
* 表计超参(对应的参数)
*/
private String typeDescription;
/**
* 表计类型传输标识
*/
private String typeIdentification;
/**
* 备注
*/
private String remarks;
/**
* 读数单位
*/
private String readingUnit;
/**
* 表计类型别名
*/
private String typeAlias;
/**
* 0停用1启用
*/
private String status;
/**
* 创建人
*/
private String createUser;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 修改人
*/
private String updateUser;
/**
* 修改时间
*/
private LocalDateTime updateTime;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}

20
device_gather/src/main/java/com/xr/device/model/mapper/DeviceCameraMapper.java

@ -0,0 +1,20 @@
package com.xr.device.model.mapper;
import com.xr.device.model.entity.DeviceCamera;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* @author 范亚杰
* @description 针对表device_camera的数据库操作Mapper
* @createDate 2024-06-25 17:30:54
* @Entity com.xr.device.model.entity.DeviceCamera
*/
@Mapper
public interface DeviceCameraMapper extends BaseMapper<DeviceCamera> {
}

20
device_gather/src/main/java/com/xr/device/model/mapper/FocalLengthConfigMapper.java

@ -0,0 +1,20 @@
package com.xr.device.model.mapper;
import com.xr.device.model.entity.FocalLengthConfig;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* @author 范亚杰
* @description 针对表focal_length_config的数据库操作Mapper
* @createDate 2024-06-25 17:31:06
* @Entity com.xr.device.model.entity.FocalLengthConfig
*/
@Mapper
public interface FocalLengthConfigMapper extends BaseMapper<FocalLengthConfig> {
}

24
device_gather/src/main/java/com/xr/device/model/mapper/MeterConfigMapper.java

@ -0,0 +1,24 @@
package com.xr.device.model.mapper;
import com.xr.device.model.entity.MeterConfig;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* @author 范亚杰
* @description 针对表meter_config的数据库操作Mapper
* @createDate 2024-06-25 17:30:43
* @Entity com.xr.device.model.entity.MeterConfig
*/
@Mapper
public interface MeterConfigMapper extends BaseMapper<MeterConfig> {
List<MeterConfig> getMeterList(Integer stationId);
}

20
device_gather/src/main/java/com/xr/device/model/mapper/MeterInitializationMapper.java

@ -0,0 +1,20 @@
package com.xr.device.model.mapper;
import com.xr.device.model.entity.MeterInitialization;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* @author 范亚杰
* @description 针对表meter_initialization(表计算法初始化)的数据库操作Mapper
* @createDate 2024-07-02 17:22:01
* @Entity com.xr.device.model.entity.MeterInitialization
*/
@Mapper
public interface MeterInitializationMapper extends BaseMapper<MeterInitialization> {
}

20
device_gather/src/main/java/com/xr/device/model/mapper/MeterReadingRecordMapper.java

@ -0,0 +1,20 @@
package com.xr.device.model.mapper;
import com.xr.device.model.entity.MeterReadingRecord;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* @author 范亚杰
* @description 针对表meter_reading_record的数据库操作Mapper
* @createDate 2024-06-25 17:30:30
* @Entity com.xr.device.model.entity.MeterReadingRecord
*/
@Mapper
public interface MeterReadingRecordMapper extends BaseMapper<MeterReadingRecord> {
}

20
device_gather/src/main/java/com/xr/device/model/mapper/MeterTypeMapper.java

@ -0,0 +1,20 @@
package com.xr.device.model.mapper;
import com.xr.device.model.entity.MeterType;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* @author 范亚杰
* @description 针对表meter_type(表计类型表)的数据库操作Mapper
* @createDate 2024-07-02 17:29:04
* @Entity com.xr.device.model.entity.MeterType
*/
@Mapper
public interface MeterTypeMapper extends BaseMapper<MeterType> {
}

13
device_gather/src/main/java/com/xr/device/model/service/DeviceCameraService.java

@ -0,0 +1,13 @@
package com.xr.device.model.service;
import com.xr.device.model.entity.DeviceCamera;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author 范亚杰
* @description 针对表device_camera的数据库操作Service
* @createDate 2024-06-25 17:30:54
*/
public interface DeviceCameraService extends IService<DeviceCamera> {
}

13
device_gather/src/main/java/com/xr/device/model/service/FocalLengthConfigService.java

@ -0,0 +1,13 @@
package com.xr.device.model.service;
import com.xr.device.model.entity.FocalLengthConfig;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author 范亚杰
* @description 针对表focal_length_config的数据库操作Service
* @createDate 2024-06-25 17:31:06
*/
public interface FocalLengthConfigService extends IService<FocalLengthConfig> {
}

17
device_gather/src/main/java/com/xr/device/model/service/MeterConfigService.java

@ -0,0 +1,17 @@
package com.xr.device.model.service;
import com.xr.device.model.entity.MeterConfig;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* @author 范亚杰
* @description 针对表meter_config的数据库操作Service
* @createDate 2024-06-25 17:30:43
*/
public interface MeterConfigService extends IService<MeterConfig> {
List<MeterConfig> getMeterList(Integer station);
}

13
device_gather/src/main/java/com/xr/device/model/service/MeterInitializationService.java

@ -0,0 +1,13 @@
package com.xr.device.model.service;
import com.xr.device.model.entity.MeterInitialization;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author 范亚杰
* @description 针对表meter_initialization(表计算法初始化)的数据库操作Service
* @createDate 2024-07-02 17:22:01
*/
public interface MeterInitializationService extends IService<MeterInitialization> {
}

13
device_gather/src/main/java/com/xr/device/model/service/MeterReadingRecordService.java

@ -0,0 +1,13 @@
package com.xr.device.model.service;
import com.xr.device.model.entity.MeterReadingRecord;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author 范亚杰
* @description 针对表meter_reading_record的数据库操作Service
* @createDate 2024-06-25 17:30:30
*/
public interface MeterReadingRecordService extends IService<MeterReadingRecord> {
}

13
device_gather/src/main/java/com/xr/device/model/service/MeterTypeService.java

@ -0,0 +1,13 @@
package com.xr.device.model.service;
import com.xr.device.model.entity.MeterType;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author 范亚杰
* @description 针对表meter_type(表计类型表)的数据库操作Service
* @createDate 2024-07-02 17:29:04
*/
public interface MeterTypeService extends IService<MeterType> {
}

24
device_gather/src/main/java/com/xr/device/model/service/impl/DeviceCameraServiceImpl.java

@ -0,0 +1,24 @@
package com.xr.device.model.service.impl;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xr.device.model.entity.DeviceCamera;
import com.xr.device.model.service.DeviceCameraService;
import com.xr.device.model.mapper.DeviceCameraMapper;
import org.springframework.stereotype.Service;
/**
* @author 范亚杰
* @description 针对表device_camera的数据库操作Service实现
* @createDate 2024-06-25 17:30:54
*/
@Service
@DS("db2")
public class DeviceCameraServiceImpl extends ServiceImpl<DeviceCameraMapper, DeviceCamera>
implements DeviceCameraService{
}

24
device_gather/src/main/java/com/xr/device/model/service/impl/FocalLengthConfigServiceImpl.java

@ -0,0 +1,24 @@
package com.xr.device.model.service.impl;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xr.device.model.entity.FocalLengthConfig;
import com.xr.device.model.service.FocalLengthConfigService;
import com.xr.device.model.mapper.FocalLengthConfigMapper;
import org.springframework.stereotype.Service;
/**
* @author 范亚杰
* @description 针对表focal_length_config的数据库操作Service实现
* @createDate 2024-06-25 17:31:06
*/
@Service
@DS("db2")
public class FocalLengthConfigServiceImpl extends ServiceImpl<FocalLengthConfigMapper, FocalLengthConfig>
implements FocalLengthConfigService{
}

30
device_gather/src/main/java/com/xr/device/model/service/impl/MeterConfigServiceImpl.java

@ -0,0 +1,30 @@
package com.xr.device.model.service.impl;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xr.device.model.entity.MeterConfig;
import com.xr.device.model.service.MeterConfigService;
import com.xr.device.model.mapper.MeterConfigMapper;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author 范亚杰
* @description 针对表meter_config的数据库操作Service实现
* @createDate 2024-06-25 17:30:43
*/
@Service
@DS("db2")
public class MeterConfigServiceImpl extends ServiceImpl<MeterConfigMapper, MeterConfig>
implements MeterConfigService{
@Override
public List<MeterConfig> getMeterList(Integer stationId) {
return ((MeterConfigMapper)this.baseMapper).getMeterList(stationId);
}
}

24
device_gather/src/main/java/com/xr/device/model/service/impl/MeterInitializationServiceImpl.java

@ -0,0 +1,24 @@
package com.xr.device.model.service.impl;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xr.device.model.entity.MeterInitialization;
import com.xr.device.model.service.MeterInitializationService;
import com.xr.device.model.mapper.MeterInitializationMapper;
import org.springframework.stereotype.Service;
/**
* @author 范亚杰
* @description 针对表meter_initialization(表计算法初始化)的数据库操作Service实现
* @createDate 2024-07-02 17:22:01
*/
@Service
@DS("db2")
public class MeterInitializationServiceImpl extends ServiceImpl<MeterInitializationMapper, MeterInitialization>
implements MeterInitializationService{
}

24
device_gather/src/main/java/com/xr/device/model/service/impl/MeterReadingRecordServiceImpl.java

@ -0,0 +1,24 @@
package com.xr.device.model.service.impl;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xr.device.model.entity.MeterReadingRecord;
import com.xr.device.model.service.MeterReadingRecordService;
import com.xr.device.model.mapper.MeterReadingRecordMapper;
import org.springframework.stereotype.Service;
/**
* @author 范亚杰
* @description 针对表meter_reading_record的数据库操作Service实现
* @createDate 2024-06-25 17:30:30
*/
@Service
@DS("db2")
public class MeterReadingRecordServiceImpl extends ServiceImpl<MeterReadingRecordMapper, MeterReadingRecord>
implements MeterReadingRecordService{
}

24
device_gather/src/main/java/com/xr/device/model/service/impl/MeterTypeServiceImpl.java

@ -0,0 +1,24 @@
package com.xr.device.model.service.impl;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xr.device.model.entity.MeterType;
import com.xr.device.model.service.MeterTypeService;
import com.xr.device.model.mapper.MeterTypeMapper;
import org.springframework.stereotype.Service;
/**
* @author 范亚杰
* @description 针对表meter_type(表计类型表)的数据库操作Service实现
* @createDate 2024-07-02 17:29:04
*/
@Service
@DS("db2")
public class MeterTypeServiceImpl extends ServiceImpl<MeterTypeMapper, MeterType>
implements MeterTypeService{
}

204
device_gather/src/main/java/com/xr/device/schedule/GetMeterSchedule.java

@ -0,0 +1,204 @@
package com.xr.device.schedule;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.code.DataType;
import com.serotonin.modbus4j.exception.ErrorResponseException;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.serotonin.modbus4j.ip.IpParameters;
import com.xr.device.common.utils.*;
import com.xr.device.model.entity.*;
import com.xr.device.model.service.*;
import com.xr.onvifhk.entity.BallheadPT;
import com.xr.onvifhk.entity.DeviceInfo;
import com.xr.onvifhk.util.HkComUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@Component
@RequiredArgsConstructor
@Slf4j
public class GetMeterSchedule {
private final MeterConfigService meterConfigService;
private final FocalLengthConfigService focalLengthConfigService;
private final MeterReadingRecordService meterReadingRecordService;
private final DeviceCameraService deviceCameraService;
private final MeterTypeService meterTypeService;
@Scheduled(cron = "0 0 9,15 * * ?")//每天9点和下午三点执行
public void getMeterSchedule(){
List<MeterConfig> configs = meterConfigService.getMeterList(StaticPropUtil.stationId);
int pageSize = 10; // 每页的设备数量
int totalDevices = configs.size(); // 总设备数量
int totalPages = (int) Math.ceil((double) totalDevices / pageSize); // 总页数
for (int pageNumber = 0; pageNumber < totalPages; pageNumber++) {
List<MeterConfig> devices = new ArrayList<>();
for (int i = pageNumber * pageSize; i < (pageNumber + 1) * pageSize && i < totalDevices; i++) {
devices.add(configs.get(i));
}
ExecutorService executorService = Executors.newFixedThreadPool(pageSize);
for (MeterConfig device : devices) {
executorService.submit(() -> collectDataFromDevice(device));
}
// 关闭线程池,等待所有任务完成
executorService.shutdown();
try {
if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
executorService.shutdownNow();
}
} catch (InterruptedException e) {
executorService.shutdownNow();
Thread.currentThread().interrupt();
}
}
}
//采集方法
private void collectDataFromDevice(MeterConfig config) {
// 实现采集逻辑
try {
MeterType meterType=meterTypeService.getById(config.getTypeId());
float f = 0;
if(config.getAlgorithmType().equals("3")){
DeviceCamera deviceCamera=deviceCameraService.getById(config.getCameraId());
QueryWrapper<FocalLengthConfig> query=new QueryWrapper<>();
query.eq("config_id",config.getId());
FocalLengthConfig config1 = focalLengthConfigService.getOne(query);
BallheadPT ball=null;
if(deviceCamera.getDeviceType().equals("3")){
ball=new BallheadPT();
ball.setX(deviceCamera.getX());
ball.setY(deviceCamera.getY());
ball.setZ(deviceCamera.getZ());
}
DeviceInfo deviceInfo=new DeviceInfo();
deviceInfo.setPort(1502);
deviceInfo.setIp(deviceCamera.getDeviceIp());
deviceInfo.setAccount(deviceCamera.getAccount());
deviceInfo.setPassword(deviceCamera.getPassword());
String url = HkComUtil.getBole(deviceInfo,null);
BufferedImage image = Files.urlByImage(url);
//获取已截图的图片
String path = getAnalysis(config1,image);
String value=PythonExecutor.readNumber(config.getId(),path,meterType.getMeterShape());
f = Float.valueOf(value);
}else{
ModbusMaster master= ModbusUtils.getMaster(config.getDeviceIp(),1502);
master.init();
MeterReadingRecord meterReadingRecord=new MeterReadingRecord();
meterReadingRecord.setMeterId(config.getId());
meterReadingRecord.setReadingType(2);
if(config.getTypeId() == 5 || config.getTypeId() == 7 || config.getTypeId() == 3 || config.getTypeId() == 8 || config.getTypeId() == 10){
Number number = ModbusUtils.readHoldingRegister(master,1,0, DataType.FOUR_BYTE_INT_SIGNED);
f = number.floatValue()*0.0001f;
}
if(config.getTypeId() == 4 ){//开关计数器
Number number = ModbusUtils.readHoldingRegister(master,1,0, DataType.TWO_BYTE_INT_SIGNED);
f = number.floatValue();
}
if(config.getTypeId() == 11){//泄漏电流表数字
Number number = ModbusUtils.readHoldingRegister(master,1,10, DataType.TWO_BYTE_INT_SIGNED);
f = number.floatValue();
}
master.destroy();
}
saveMeterReading(config,f);
} catch (Exception e) {
e.printStackTrace();
log.error(e.getMessage());
}
}
public void saveMeterReading(MeterConfig config,float f) throws Exception {
MeterReadingRecord meterReadingRecord=new MeterReadingRecord();
meterReadingRecord.setMeterId(config.getId());
meterReadingRecord.setReadingType(2);
String value = "";
if(config.getTypeId() == 5 || config.getTypeId() == 7){
value = ValueFormatUtil.getZZl(f,config);
}
if(config.getTypeId() == 3 ){
value = ValueFormatUtil.getYwj(f,config);
}
if(config.getTypeId() == 4 || config.getTypeId() == 11){//开关计数器
value= ValueFormatUtil.getNumBerJx(f,config,meterConfigService);
}
if(config.getTypeId() == 8){//档位数据处理
//处理为整数
value = ValueFormatUtil.getDw(f);
}
if(config.getTypeId() == 10){//放电计数器
value=ValueFormatUtil.getfdjsq(f);
}
if(config.getIsJz()!=null && config.getIsJz() == 1){
value = config.getJzVal();
}
meterReadingRecord.setReadingValue(value);
QueryWrapper<FocalLengthConfig> query=new QueryWrapper<>();
query.eq("config_id",config.getId());
FocalLengthConfig fa= focalLengthConfigService.getOne(query);
String fileName = config.getId()+new Date().getTime()+".jpg";
String url = "http://"+config.getDeviceIp()+":8080/tao/snapshot";
BufferedImage bufferedImage = UploadUtil.urlByImage(url);
BufferedImage buffer = UploadUtil.drawRectangleAndText(bufferedImage,
fa.getCopperX(),fa.getCopperY(),fa.getCopperX2(),fa.getCopperWid(),fa.getCopperHei(),meterReadingRecord.getReadingValue(),config.getMeterName());
String url1 = UploadUtil.uploadImage(buffer,config.getId(),fileName);
meterReadingRecord.setMeterTypeName(config.getMeterType());
meterReadingRecord.setMeterCode(config.getMeterCode());
meterReadingRecord.setReadingTime(new Date());
meterReadingRecord.setCreateUser("SYSTEM");
meterReadingRecord.setCreateTime(new Date());
meterReadingRecord.setReadingUrl(url1);
meterReadingRecord.setMeterTypeId(config.getTypeId());
meterReadingRecord.setOwningInterval(config.getOwningInterval());
meterReadingRecordService.save(meterReadingRecord);
}
//截取图片并保存为url
public String getAnalysis(FocalLengthConfig focal,BufferedImage pic) throws IOException {
Date date = new Date();
SimpleDateFormat sfm = new SimpleDateFormat("yyyy-MM-dd");
if(focal.getRotate()!=null && focal.getRotate()!=0){
pic= Files.rotateImage(pic,focal.getRotate());
}
int widthInt = (int) Math.round(focal.getCopperWid());
int heightInt = (int) Math.round(focal.getCopperHei());
double copperx = focal.getCopperX();
double coppery = focal.getCopperY();
BufferedImage pic2 = pic.getSubimage((int) copperx, (int) coppery, widthInt, heightInt);
//将截取的子图另行存储
Image _img = pic2.getScaledInstance(widthInt, heightInt, Image.SCALE_DEFAULT);
BufferedImage image = new BufferedImage(widthInt, heightInt, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = image.createGraphics();
graphics.drawImage(_img, 0, 0, null);
graphics.dispose();
return Files.uploadImageForPath(image, StaticPropUtil.imgPath,sfm.format(date)+"\\\\"+date.getTime()+".jpg");
}
}

80
device_gather/src/main/resources/application-dev.yml

@ -0,0 +1,80 @@
server:
port: 8173
servlet:
context-path: /cars-api
#context-path: /
spring:
datasource:
dynamic:
primary: db1
strict: false
datasource:
db1:
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.zaxxer.hikari.HikariDataSource
url: jdbc:mysql://116.196.120.81:3306/device_system?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&serverTimezone=Asia/Shanghai&useSSL=false
username: root
password: 5ea47c0bdd7146ebbd53020eca@672307
db2:
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.zaxxer.hikari.HikariDataSource
url: jdbc:mysql://116.196.120.81:3306/image_analysix_wz?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&serverTimezone=Asia/Shanghai&useSSL=false
username: root
password: 5ea47c0bdd7146ebbd53020eca@672307
#Hikari连接池配置
hikari:
#池中维护的最小空闲连接数
minimum-idle: 5
#池中最大连接数,包括闲置和使用中的连接
maximum-pool-size: 15
#自动提交从池中返回的连接
auto-commit: true
#连接允许在池中闲置的最长时间
idle-timeout: 30000
#连接池的用户定义名称,主要出现在日志记录和JMX管理控制台中以识别池和池配置
pool-name: DatebookHikariCP
#池中连接最长生命周期
max-lifetime: 18000000
#等待来自池的连接的最大毫秒数
connection-timeout: 30000
#验证该连接是否是有效的查询语句
connection-test-query: select 1 from dual
cloud:
inetutils:
timeout-seconds: 1000
config:
enabled: false
# redis 相关
redis:
host: ${REDIS_URL:localhost}
port: ${REDIS_PORT:6379}
password: ${REDIS_PWD:111111}
timeout: 10000
jedis:
pool:
max-active: 1000
max-wait: -1ms
max-idle: 10
min-idle: 5
swagger:
show: true
analysis:
url: http://192.168.1.123:9000/vi/syncrec
upload:
img:
url: http://192.168.1.83:18081/file/img/zs/
path: D:\\service\\fileService\\img\\zs\\
python:
path: C:\\Users\\admin\\Anaconda3\\envs\\myconda310\\python.exe
modelPath: D:\\smartGrid\\smartGrid\\models
eureka:
instance:
instance-id: ${spring.cloud.client.ip-address}:${server.port}
prefer-ip-address: true
client:
healthcheck:
enabled: true
service-url:
defaultZone: http://localhost:8084/eureka

80
device_gather/src/main/resources/application-prod.yml

@ -0,0 +1,80 @@
server:
port: 8173
servlet:
context-path: /cars-api
#context-path: /
spring:
datasource:
dynamic:
primary: db1
strict: false
datasource:
db1:
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.zaxxer.hikari.HikariDataSource
url: jdbc:mysql://192.168.1.94:3306/device_system?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&serverTimezone=Asia/Shanghai&useSSL=false
username: root
password: 123456
db2:
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.zaxxer.hikari.HikariDataSource
url: jdbc:mysql://192.168.1.94:3306/image_analysix_wz?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&serverTimezone=Asia/Shanghai&useSSL=false
username: root
password: 123456
#Hikari连接池配置
hikari:
#池中维护的最小空闲连接数
minimum-idle: 5
#池中最大连接数,包括闲置和使用中的连接
maximum-pool-size: 15
#自动提交从池中返回的连接
auto-commit: true
#连接允许在池中闲置的最长时间
idle-timeout: 30000
#连接池的用户定义名称,主要出现在日志记录和JMX管理控制台中以识别池和池配置
pool-name: DatebookHikariCP
#池中连接最长生命周期
max-lifetime: 18000000
#等待来自池的连接的最大毫秒数
connection-timeout: 30000
#验证该连接是否是有效的查询语句
connection-test-query: select 1 from dual
cloud:
inetutils:
timeout-seconds: 1000
config:
enabled: false
# redis 相关
redis:
host: ${REDIS_URL:localhost}
port: ${REDIS_PORT:6379}
password: ${REDIS_PWD:111111}
timeout: 10000
jedis:
pool:
max-active: 1000
max-wait: -1ms
max-idle: 10
min-idle: 5
swagger:
show: true
analysis:
url: http://192.168.1.123:9000/vi/syncrec
upload:
img:
url: http://192.168.1.94:18081/file/img/zs/
path: D:\\service\\fileService\\img\\zs\\
python:
path: C:\\Users\\admin\\Anaconda3\\envs\\myconda310\\python.exe
modelPath: D:\\smartGrid\\smartGrid\\models
eureka:
instance:
instance-id: ${spring.cloud.client.ip-address}:${server.port}
prefer-ip-address: true
client:
healthcheck:
enabled: true
service-url:
defaultZone: http://localhost:8084/eureka

82
device_gather/src/main/resources/application.yml

@ -0,0 +1,82 @@
spring:
profiles:
#active: dev #开发环境
# active: test #测试环境5
active: dev
# active: prod #生产环境
application:
name: gather
devtools:
restart:
log-condition-evaluation-delta: false
security:
user:
name: admin
password: admin
servlet:
multipart:
max-file-size: 500MB
max-request-size: 500MB
jackson:
date-format: yyyy-MM-dd
time-zone: GMT+8
default-property-inclusion: non_null
mybatis-plus:
mapper-locations: classpath:mapper/*Mapper.xml
type-aliases-package: com.xr.device
# 在查询语句的是否,对Map或者是entity进行映射赋值的时候null也进行映射。默认false,不进行映射
configuration:
map-underscore-to-camel-case: true
call-setters-on-nulls: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 设置更新或者修改的时候的策略,不进行校验,否则如果是null则不会进行更新或者插入,当然在@TableField注解进行指定单个字段
global-config:
db-config:
insert-strategy: ignored
update-strategy: ignored
logging:
level:
root: info
com.xr: debug
org:
springframework:
boot:
autoconfigure: error
### Ribbon 配置
ribbon:
# 连接超时
ConnectTimeout: 100000
# 响应超时
ReadTimeout: 100000
### Feign 配置
feign:
# 开启断路器(熔断器)
hystrix:
enabled: true
### Hystrix 配置
hystrix:
# 这样将会自动配置一个 Hystrix 并发策略插件的 hook,这个 hook 会将 SecurityContext 从主线程传输到 Hystrix 的命令。
# 因为 Hystrix 不允许注册多个 Hystrix 策略,所以可以声明 HystrixConcurrencyStrategy
# 为一个 Spring bean 来实现扩展。Spring Cloud 会在 Spring 的上下文中查找你的实现,并将其包装在自己的插件中。
shareSecurityContext: true
command:
default:
circuitBreaker:
# 当在配置时间窗口内达到此数量的失败后,进行短路。默认20个
requestVolumeThreshold: 100
# 触发短路的时间值,当该值设为5000时,则当触发 circuit break 后的5000毫秒内都会拒绝request
# 也就是5000毫秒后才会关闭circuit。默认5000
sleepWindowInMilliseconds: 5000
# 强制打开熔断器,如果打开这个开关,那么拒绝所有request,默认false
forceOpen: false
# 强制关闭熔断器 如果这个开关打开,circuit将一直关闭且忽略,默认false
forceClosed: false
execution:
isolation:
thread:
# 熔断器超时时间,默认:1000/毫秒
timeoutInMilliseconds: 20000

23
device_gather/src/main/resources/banner.txt

@ -0,0 +1,23 @@
==================================================================
// _ooOoo_ //
// o8888888o //
// 88" . "88 //
// (| ^_^ |) //
// O\ = /O //
// ____/`---'\____ //
// .' \\| |// `. //
// / \\||| : |||// \ //
// / _||||| -:- |||||- \ //
// | | \\\ - /// | | //
// | \_| ''\---/'' | | //
// \ .-\__ `-` ___/-. / //
// ___`. .' /--.--\ `. . ___ //
// ."" '< `.___\_<|>_/___.' >'"". //
// | | : `- \`.;`\ _ /`;.`/ - ` : | | //
// \ \ `-. \_ __\ /__ _/ .-` / / //
// ========`-.____`-.___\_____/___.-`____.-'======== //
// `=---=' //
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //
// 佛祖保佑 永不宕机 永无BUG //
\\\\ ////
=============================================================

51
device_gather/src/main/resources/logback.xml

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
<property name="LOG_HOME" value="/home" />
<!--控制台日志, 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度,%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<!--文件日志, 按照每天生成日志文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<FileNamePattern>${LOG_HOME}/deviceCar.log.%d{yyyy-MM-dd}.log</FileNamePattern>
<!--日志文件保留天数-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
<!--日志文件最大的大小-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender>
<!-- show parameters for hibernate sql 专为 Hibernate 定制 -->
<logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE" />
<logger name="org.hibernate.type.descriptor.sql.BasicExtractor" level="DEBUG" />
<logger name="org.hibernate.SQL" level="DEBUG" />
<logger name="org.hibernate.engine.QueryParameters" level="DEBUG" />
<logger name="org.hibernate.engine.query.HQLQueryPlan" level="DEBUG" />
<!--myibatis log configure-->
<logger name="com.apache.mybatis" level="TRACE"/>
<logger name="java.sql.Connection" level="DEBUG"/>
<logger name="java.sql.Statement" level="DEBUG"/>
<logger name="java.sql.PreparedStatement" level="DEBUG"/>
<!-- 日志输出级别 -->
<root level="DEBUG">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE"/>
</root>
</configuration>

40
device_gather/src/main/resources/mapper/DeviceCameraMapper.xml

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xr.device.model.mapper.DeviceCameraMapper">
<resultMap id="BaseResultMap" type="com.xr.device.model.entity.DeviceCamera">
<id property="id" column="id" jdbcType="INTEGER"/>
<result property="deviceNo" column="device_no" jdbcType="VARCHAR"/>
<result property="deviceType" column="device_type" jdbcType="VARCHAR"/>
<result property="deviceIp" column="device_ip" jdbcType="VARCHAR"/>
<result property="devicePort" column="device_port" jdbcType="VARCHAR"/>
<result property="account" column="account" jdbcType="VARCHAR"/>
<result property="password" column="password" jdbcType="VARCHAR"/>
<result property="x" column="x" jdbcType="VARCHAR"/>
<result property="y" column="y" jdbcType="VARCHAR"/>
<result property="z" column="z" jdbcType="VARCHAR"/>
<result property="deviceModel" column="device_model" jdbcType="VARCHAR"/>
<result property="position" column="position" jdbcType="VARCHAR"/>
<result property="brand" column="brand" jdbcType="VARCHAR"/>
<result property="remarks" column="remarks" jdbcType="VARCHAR"/>
<result property="status" column="status" jdbcType="VARCHAR"/>
<result property="createUser" column="create_user" jdbcType="VARCHAR"/>
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
<result property="updateUser" column="update_user" jdbcType="VARCHAR"/>
<result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
<result property="transmissionInterval" column="transmission_interval" jdbcType="INTEGER"/>
<result property="warmup" column="warmup" jdbcType="INTEGER"/>
</resultMap>
<sql id="Base_Column_List">
id,device_no,device_type,
device_ip,device_port,account,
password,x,y,
z,device_model,position,
brand,remarks,status,
create_user,create_time,update_user,
update_time,transmission_interval,warmup
</sql>
</mapper>

43
device_gather/src/main/resources/mapper/FocalLengthConfigMapper.xml

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xr.device.model.mapper.FocalLengthConfigMapper">
<resultMap id="BaseResultMap" type="com.xr.device.model.entity.FocalLengthConfig">
<id property="id" column="id" jdbcType="INTEGER"/>
<result property="configId" column="config_id" jdbcType="INTEGER"/>
<result property="focalName" column="focal_name" jdbcType="VARCHAR"/>
<result property="focalIndex" column="focal_index" jdbcType="VARCHAR"/>
<result property="copperWid" column="copper_wid" jdbcType="DOUBLE"/>
<result property="copperHei" column="copper_hei" jdbcType="DOUBLE"/>
<result property="copperX" column="copper_x" jdbcType="DOUBLE"/>
<result property="copperX2" column="copper_x2" jdbcType="DOUBLE"/>
<result property="copperY" column="copper_y" jdbcType="DOUBLE"/>
<result property="copperY2" column="copper_y2" jdbcType="DOUBLE"/>
<result property="configType" column="config_type" jdbcType="VARCHAR"/>
<result property="meterMin" column="meter_min" jdbcType="DOUBLE"/>
<result property="meterMax" column="meter_max" jdbcType="DOUBLE"/>
<result property="rotate" column="rotate" jdbcType="INTEGER"/>
<result property="scale" column="scale" jdbcType="DOUBLE"/>
<result property="stateNum" column="state_num" jdbcType="INTEGER"/>
<result property="parameter" column="parameter" jdbcType="VARCHAR"/>
<result property="result" column="result" jdbcType="VARCHAR"/>
<result property="algorithm" column="algorithm" jdbcType="INTEGER"/>
<result property="createUser" column="create_user" jdbcType="VARCHAR"/>
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
<result property="updateUser" column="update_user" jdbcType="VARCHAR"/>
<result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
</resultMap>
<sql id="Base_Column_List">
id,config_id,focal_name,
focal_index,copper_wid,copper_hei,
copper_x,copper_x2,copper_y,
copper_y2,config_type,meter_min,
meter_max,rotate,scale,
state_num,parameter,result,
algorithm,create_user,create_time,
update_user,update_time,focal_picture
</sql>
</mapper>

59
device_gather/src/main/resources/mapper/MeterConfigMapper.xml

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xr.device.model.mapper.MeterConfigMapper">
<resultMap id="BaseResultMap" type="com.xr.device.model.entity.MeterConfig">
<id property="id" column="id" jdbcType="INTEGER"/>
<result property="ids5000Id" column="ids5000_id" jdbcType="INTEGER"/>
<result property="intervalType" column="interval_type" jdbcType="INTEGER"/>
<result property="voltageClass" column="voltage_class" jdbcType="VARCHAR"/>
<result property="owningInterval" column="owning_interval" jdbcType="VARCHAR"/>
<result property="identificationInterval" column="identification_interval" jdbcType="VARCHAR"/>
<result property="deviceName" column="device_name" jdbcType="VARCHAR"/>
<result property="locationY" column="location_y" jdbcType="DOUBLE"/>
<result property="locationX" column="location_x" jdbcType="DOUBLE"/>
<result property="deviceType" column="device_type" jdbcType="VARCHAR"/>
<result property="meterCode" column="meter_code" jdbcType="VARCHAR"/>
<result property="meterName" column="meter_name" jdbcType="VARCHAR"/>
<result property="cameraId" column="camera_id" jdbcType="INTEGER"/>
<result property="warningMax" column="warning_max" jdbcType="DOUBLE"/>
<result property="warningMin" column="warning_min" jdbcType="DOUBLE"/>
<result property="typeId" column="type_id" jdbcType="INTEGER"/>
<result property="status" column="status" jdbcType="INTEGER"/>
<result property="firstTime" column="first_time" jdbcType="TIMESTAMP"/>
<result property="algorithmType" column="algorithm_type" jdbcType="VARCHAR"/>
<result property="intervalTime" column="interval_time" jdbcType="INTEGER"/>
<result property="focalNumber" column="focal_number" jdbcType="INTEGER"/>
<result property="parameterConfig" column="parameter_config" jdbcType="VARCHAR"/>
<result property="remarks" column="remarks" jdbcType="VARCHAR"/>
<result property="iec61850mx" column="iec61850mx" jdbcType="VARCHAR"/>
<result property="isJz" column="is_jz" jdbcType="INTEGER"/>
<result property="jzVal" column="jz_val" jdbcType="VARCHAR"/>
<result property="initStatus" column="init_status" jdbcType="VARCHAR"/>
<result property="createUser" column="create_user" jdbcType="VARCHAR"/>
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
<result property="updateUser" column="update_user" jdbcType="VARCHAR"/>
<result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
</resultMap>
<sql id="Base_Column_List">
id,ids5000_id,interval_type,
voltage_class,owning_interval,identification_interval,
device_name,location_y,location_x,
device_type,meter_code,meter_name,
camera_id,warning_max,warning_min,
type_id,status,first_time,
algorithm_type,interval_time,focal_number,
parameter_config,remarks,iec61850mx,
is_jz,jz_val,init_status,
create_user,create_time,update_user,
update_time
</sql>
<select id="getMeterList" resultType="com.xr.device.model.entity.MeterConfig">
select a.*,b.device_ip from meter_config a left join device_camera b
on a.camera_id = b.id where a.status = 1 and a.station_id = #{stationId}
</select>
</mapper>

20
device_gather/src/main/resources/mapper/MeterInitializationMapper.xml

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xr.device.model.mapper.MeterInitializationMapper">
<resultMap id="BaseResultMap" type="com.xr.device.model.entity.MeterInitialization">
<id property="id" column="id" jdbcType="INTEGER"/>
<result property="img" column="img" jdbcType="VARCHAR"/>
<result property="imgAddress" column="img_address" jdbcType="VARCHAR"/>
<result property="value" column="value" jdbcType="VARCHAR"/>
<result property="meterId" column="meter_id" jdbcType="INTEGER"/>
<result property="serial" column="serial" jdbcType="INTEGER"/>
</resultMap>
<sql id="Base_Column_List">
id,img,img_address,
value,meter_id,serial
</sql>
</mapper>

32
device_gather/src/main/resources/mapper/MeterReadingRecordMapper.xml

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xr.device.model.mapper.MeterReadingRecordMapper">
<resultMap id="BaseResultMap" type="com.xr.device.model.entity.MeterReadingRecord">
<id property="id" column="id" jdbcType="INTEGER"/>
<result property="meterId" column="meter_id" jdbcType="INTEGER"/>
<result property="meterCode" column="meter_code" jdbcType="VARCHAR"/>
<result property="meterTypeId" column="meter_type_id" jdbcType="INTEGER"/>
<result property="meterTypeName" column="meter_type_name" jdbcType="VARCHAR"/>
<result property="owningInterval" column="owning_interval" jdbcType="VARCHAR"/>
<result property="readingTime" column="reading_time" jdbcType="TIMESTAMP"/>
<result property="readingType" column="reading_type" jdbcType="INTEGER"/>
<result property="dataType" column="data_type" jdbcType="INTEGER"/>
<result property="readingValue" column="reading_value" jdbcType="VARCHAR"/>
<result property="readingUrl" column="reading_url" jdbcType="VARCHAR"/>
<result property="createUser" column="create_user" jdbcType="VARCHAR"/>
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
<result property="updateUser" column="update_user" jdbcType="VARCHAR"/>
<result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
</resultMap>
<sql id="Base_Column_List">
id,meter_id,meter_code,
meter_type_id,meter_type_name,owning_interval,
reading_time,reading_type,data_type,
reading_value,reading_url,create_user,
create_time,update_user,update_time
</sql>
</mapper>

30
device_gather/src/main/resources/mapper/MeterTypeMapper.xml

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xr.device.model.mapper.MeterTypeMapper">
<resultMap id="BaseResultMap" type="com.xr.device.model.entity.MeterType">
<id property="id" column="id" jdbcType="INTEGER"/>
<result property="meterType" column="meter_type" jdbcType="VARCHAR"/>
<result property="meterShape" column="meter_shape" jdbcType="VARCHAR"/>
<result property="typeDescription" column="type_description" jdbcType="VARCHAR"/>
<result property="typeIdentification" column="type_identification" jdbcType="VARCHAR"/>
<result property="remarks" column="remarks" jdbcType="VARCHAR"/>
<result property="readingUnit" column="reading_unit" jdbcType="VARCHAR"/>
<result property="typeAlias" column="type_alias" jdbcType="VARCHAR"/>
<result property="status" column="status" jdbcType="VARCHAR"/>
<result property="createUser" column="create_user" jdbcType="VARCHAR"/>
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
<result property="updateUser" column="update_user" jdbcType="VARCHAR"/>
<result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
</resultMap>
<sql id="Base_Column_List">
id,meter_type,meter_shape,
type_description,type_identification,remarks,
reading_unit,type_alias,status,
create_user,create_time,update_user,
update_time
</sql>
</mapper>
Loading…
Cancel
Save