若依微服务1.1.0版本:

1、tdengine服务增加获取在线设备信息接口
2、字典数据完善
3、数据处理服务:完成数据解析保存(判断base64),另外电子围栏判断保存
dev 1.1.0
xins 1 year ago
parent 631970c21c
commit 0af59e14d2

@ -213,6 +213,13 @@
<version>${ruoyi.version}</version>
</dependency>
<!-- tdegin接口 -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>hw-api-tdengine</artifactId>
<version>${ruoyi.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

@ -0,0 +1,63 @@
package com.ruoyi.tdengine.api.domain;
import com.ruoyi.common.core.web.domain.BaseEntity;
/**
* @Description:
* @ClassName: DeviceStatus
* @Author : xins
* @Date :2023-09-05 11:35
* @Version :1.0
*/
public class DeviceStatus extends BaseEntity {
private Long ts;
private String deviceCode;
private int deviceType;
private int onlineStatus;
private Long sceneId;
public Long getTs() {
return ts;
}
public void setTs(Long ts) {
this.ts = ts;
}
public String getDeviceCode() {
return deviceCode;
}
public void setDeviceCode(String deviceCode) {
this.deviceCode = deviceCode;
}
public int getDeviceType() {
return deviceType;
}
public void setDeviceType(int deviceType) {
this.deviceType = deviceType;
}
public int getOnlineStatus() {
return onlineStatus;
}
public void setOnlineStatus(int onlineStatus) {
this.onlineStatus = onlineStatus;
}
public Long getSceneId() {
return sceneId;
}
public void setSceneId(Long sceneId) {
this.sceneId = sceneId;
}
}

@ -18,4 +18,12 @@ public class HwDictConstants {
public static final String DEFAULT_FUNCTION_LONGITUDE_IDENTIFIER = "longitude";//经度标识符
public static final String DEFAULT_FUNCTION_LATITUDE_IDENTIFIER = "latitude";//纬度标识符
public static final String ELECTRONIC_FENCE_TRIGGER_STATUS_EXIT = "1";//电子围栏触发状态:出界
public static final String ELECTRONIC_FENCE_TRIGGER_STATUS_ENTRY = "2";//电子围栏触发状态:入界
public static final String ALARM_INFO_TYPE_DEVICE = "1";//设备报警
public static final String ALARM_INFO_TYPE_MONITOR_UNIT = "2";//监控单元
public static final String ALARM_INFO_TYPE_OFFLINE = "3";//离线报警
public static final String ALARM_INFO_TYPE_ELECTRONIC_FENCE = "4";//电子围栏
}

@ -1,8 +1,76 @@
package com.ruoyi.common.core.constant;
import java.util.HashMap;
import java.util.Map;
/**
* @Description: TdEngine
* @ClassName: TdEngineConstants
* @Author : xins
* @Date :2023-09-05 9:47
* @Version :1.0
*/
public class TdEngineConstants {
public static final String DEFAULT_FIRST_FIELD_NAME = "ts";
public static final String DEFAULT_FIRST_FIELD_NAME = "ts";//timestamp格式首字段必须
public static final String DEFAULT_ORDER_BY_MODE = "desc";//默认排序方式,逆序
public static final String PAYLOAD_TS = "timestamp";//协议上传ts的key
public static final String PAYLOAD_PARAM = "param";//协议上传的param key
public static final String PAYLOAD_DATAVALUE = "datavalue";//协议上传数据的key
public static final String PAYLOAD_DEVICE_CODE = "uid";//协议上传设备编号的key
public static final String DEFAULT_DB_NAME_PREFIX = "db_scene_";//数据库名称前缀
public static final String DEFAULT_TABLE_NAME_PREFIX = "t_device_";//数据表名称前缀
public static final String DEFAULT_DEVICE_STATUS_SUPER_TABLE_NAME_PREFIX = "st_ds";//设备状态超级表名称
public static final String DEFAULT_DEVICE_STATUS_TABLE_NAME_PREFIX = "t_ds_";//设备状态数据表名称前缀
/**
* key
*/
public static final Map<String, String> TDENGINE_KEY_TRANSFER_MAP = new HashMap<String, String>();
static {
TDENGINE_KEY_TRANSFER_MAP.put("value", "value1");
}
/**
* @return String
* @param: sceneId
* @description
* @author xins
* @date 2023-09-05 9:42
*/
public static String getDatabaseName(Long sceneId) {
return DEFAULT_DB_NAME_PREFIX + sceneId;
}
/**
* @param: deviceId
* @return String
* @description
* @author xins
* @date 2023-09-05 9:42
*/
public static String getDeviceDataTableName(Long deviceId) {
return DEFAULT_TABLE_NAME_PREFIX + deviceId;
}
/**
* @param: sceneId
* @return String
* @description
* @author xins
* @date 2023-09-05 9:42
*/
public static String getDeviceStatusSuperTableName(Long sceneId) {
return DEFAULT_DEVICE_STATUS_SUPER_TABLE_NAME_PREFIX + sceneId;
}
public static final String DEFAULT_ORDER_BY_MODE = "desc";
}

@ -0,0 +1,35 @@
package com.ruoyi.common.core.enums;
/**
* @Description:
* @ClassName: ResultEnums
* @Author : xins
* @Date :2023-09-01 13:40
* @Version :1.0
*/
public enum ResultEnums {
SUCCESS(200,"成功"),FAIL(500,"失败");
public Integer code;
public String message;
ResultEnums(Integer code, String message) {
this.code = code;
this.message = message;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-modules</artifactId>
<version>3.6.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-modules-dataprocess</artifactId>
<description>
ruoyi-modules-dataprocess数据处理模块
</description>
<dependencies>
<!-- SpringCloud Alibaba Nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- SpringCloud Alibaba Nacos Config -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- SpringCloud Alibaba Sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- SpringBoot Actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Swagger UI -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.fox.version}</version>
</dependency>
<!-- Mysql Connector -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<!-- RuoYi Common DataSource -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-datasource</artifactId>
</dependency>
<!-- RuoYi Common DataScope -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-datascope</artifactId>
</dependency>
<!-- RuoYi Common Log -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-log</artifactId>
</dependency>
<!-- RuoYi Common Swagger -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-swagger</artifactId>
</dependency>
<!--Mica-Mqtt-->
<dependency>
<groupId>net.dreamlu</groupId>
<artifactId>mica-mqtt-client-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
<!-- HW API TDENGINE-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>hw-api-tdengine</artifactId>
</dependency>
<dependency>
<groupId>org.locationtech.jts</groupId>
<artifactId>jts-core</artifactId>
<version>1.19.0</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,34 @@
package com.ruoyi.dataprocess;
import com.ruoyi.common.security.annotation.EnableCustomConfig;
import com.ruoyi.common.security.annotation.EnableRyFeignClients;
import com.ruoyi.common.swagger.annotation.EnableCustomSwagger2;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
*
*
* @author xins
*/
@EnableCustomConfig
@EnableCustomSwagger2
@EnableRyFeignClients
@SpringBootApplication
public class HwDataProcessApplication
{
public static void main(String[] args)
{
SpringApplication.run(HwDataProcessApplication.class, args);
System.out.println("(♥◠‿◠)ノ゙ 数据处理模块启动成功 ლ(´ڡ`ლ)゙ \n" +
" .-------. ____ __ \n" +
" | _ _ \\ \\ \\ / / \n" +
" | ( ' ) | \\ _. / ' \n" +
" |(_ o _) / _( )_ .' \n" +
" | (_,_).' __ ___(_ o _)' \n" +
" | |\\ \\ | || |(_,_)' \n" +
" | | \\ `' /| `-' / \n" +
" | | \\ / \\ / \n" +
" ''-' `'-' `-..-' ");
}
}

@ -0,0 +1,46 @@
package com.ruoyi.dataprocess.amap;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;
/**
* @Description: list
* @ClassName: LocationVo
* @Author : xins
* @Date :2023-09-02 11:22
* @Version :1.0
*/
@Data
public class LocationVo implements Serializable {
private static final long serialVersionUID = 1L;
public static final int MARKER_TYPE_POLYGON = 1;//多边形
public static final int MARKER_TYPE_CIRCULAR = 2;//圆形
//经度
private Double longitude;
//纬度
private Double latitude;
/**
*
*/
// @ApiModelProperty(value = "半径")
private Double radius;
/**
* 12
*/
// @ApiModelProperty(value = "标记类型1圆2多边形")
private int markerType;
/**
*
*/
private List<List<PositionVo>> polygonList;
}

@ -0,0 +1,185 @@
package com.ruoyi.dataprocess.amap;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Point;
import org.locationtech.jts.geom.Polygon;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
public class PositionUtils {
/**
* @return boolean
* @param: locationVo
* @param: lng
* @param: lat
* @description LocationVo
* @author xins
* @date 2023-09-02 12:47
*/
public static boolean checkAddressInLocation(LocationVo locationVo, Double lng, Double lat) {
if (locationVo == null) {
return false;
}
if (lng != null && lat != null && lng.compareTo(0.000000000000) > 0 && lat.compareTo(0.000000000000) > 0) {
if (locationVo.getMarkerType() == LocationVo.MARKER_TYPE_CIRCULAR) {//如果是圆
double distance = calculateLineDistance(lng,lat,locationVo.getLongitude(), locationVo.getLatitude());
System.out.println("dis:"+distance);
return (distance - locationVo.getRadius()) <=0;
} else if (locationVo.getMarkerType() == LocationVo.MARKER_TYPE_POLYGON) {
//多个多边形点集合字符串
List<List<PositionVo>> coordinates = locationVo.getPolygonList();
if (coordinates == null || coordinates.isEmpty()) {
return false;
}
//可以传好几个多边形
for (List<PositionVo> positionVos : coordinates) {
Coordinate[] coordinates1 = new Coordinate[positionVos.size() + 1];
for (int i = 0; i < positionVos.size(); i++) {
BigDecimal longitudeB = positionVos.get(i).getLongitude();
BigDecimal latitudeB = positionVos.get(i).getLatitude();
if (longitudeB == null || latitudeB == null) {//数据异常
return false;
}
Double longitude = longitudeB.doubleValue();
Double latitude = latitudeB.doubleValue();
Coordinate coordinate = new Coordinate(longitude, latitude);
coordinates1[i] = coordinate;
}
//是起点也是终点
coordinates1[positionVos.size()] = new Coordinate(positionVos.get(0).getLongitude().doubleValue(),
positionVos.get(0).getLatitude().doubleValue());
if (isPointInPolygon(lat.doubleValue(), lng.doubleValue(), coordinates1)) {
return true;//只需要定位在其中一个的多边形范围内
}
}
return false;
}
return false;
} else {
return false;
}
}
// public static boolean checkWithinTheCircula(LocationVo circulaVo, Double lng, Double lat) {//判断点与圆心之间的距离和圆半径的关系
//
// System.out.println(lng.subtract(circulaVo.getLongitude()).doubleValue());
// System.out.println(lat.subtract(circulaVo.getLatitude()).doubleValue());
// double d2 = Math.hypot(lng.subtract(circulaVo.getLongitude()), lat.subtract(circulaVo.getLatitude()).doubleValue());
//
// System.out.println("d2==" + d2);
//
// double r = circulaVo.getRadius();
// //圆外
// if (d2 > r) {
// return false;
// } else {//圆内或圆上
// return true;
// }
// }
/**
*
* Android
*
* @param longitude
* @param latitude
* @param centerLon
* @param centerLat
* @return
*/
public static Double calculateLineDistance(double longitude, double latitude, double centerLon, double centerLat) {
if (longitude == 0 || latitude == 0 || centerLat == 0 || centerLon == 0) {
return -1.0;
}
longitude *= 0.01745329251994329;
latitude *= 0.01745329251994329;
centerLon *= 0.01745329251994329;
centerLat *= 0.01745329251994329;
double var10 = Math.sin(longitude);
double var12 = Math.sin(latitude);
double var14 = Math.cos(longitude);
double var16 = Math.cos(latitude);
double var18 = Math.sin(centerLon);
double var20 = Math.sin(centerLat);
double var22 = Math.cos(centerLon);
double var24 = Math.cos(centerLat);
double[] var28 = new double[3];
double[] var29 = new double[3];
var28[0] = var16 * var14;
var28[1] = var16 * var10;
var28[2] = var12;
var29[0] = var24 * var22;
var29[1] = var24 * var18;
var29[2] = var20;
double distance = Math.asin(Math.sqrt((var28[0] - var29[0]) * (var28[0] - var29[0]) + (var28[1] - var29[1]) * (var28[1] - var29[1]) + (var28[2] - var29[2]) * (var28[2] - var29[2])) / 2.0) * 1.27420015798544E7;
return distance;
}
/**
*
*
* @param latitude
* @param longitude
* @param polygonCoordinates
* @return
*/
public static boolean isPointInPolygon(double latitude, double longitude, Coordinate[] polygonCoordinates) {
GeometryFactory geometryFactory = new GeometryFactory();
Point point = geometryFactory.createPoint(new Coordinate(longitude, latitude));
Polygon polygon = geometryFactory.createPolygon(polygonCoordinates);
return polygon.touches(point) || polygon.contains(point);
}
public static void main(String[] args) {
LocationVo locationVo = new LocationVo();
locationVo.setMarkerType(LocationVo.MARKER_TYPE_POLYGON);
List<List<PositionVo>> polygonList = new ArrayList<>();
List<PositionVo> postionList = new ArrayList<>();
//林和西地铁站
postionList.add(new PositionVo(new BigDecimal("113.323947"), new BigDecimal("23.141525")));
//五羊邨地铁站
postionList.add(new PositionVo(new BigDecimal(113.314119), new BigDecimal(23.119977)));
//体育中心南地铁站
postionList.add(new PositionVo(new BigDecimal(113.324247), new BigDecimal(23.134501)));
//猎德地铁站
postionList.add(new PositionVo(new BigDecimal(113.331972), new BigDecimal(23.118477)));
polygonList.add(postionList);
locationVo.setPolygonList(polygonList);
// boolean check1 = checkAddressInLocation(locationVo,new BigDecimal(113.323239),new BigDecimal(23.135428));
// System.out.println(check1);
// check1 = checkAddressInLocation(locationVo,new BigDecimal(113.321522),new BigDecimal(23.13381));
// System.out.println(check1);
// check1 = checkAddressInLocation(locationVo,new BigDecimal(113.324462),new BigDecimal(23.127002));
// System.out.println(check1);
// check1 = checkAddressInLocation(locationVo,new BigDecimal(113.324247),new BigDecimal(23.116188));
// System.out.println(check1);
// check1 = checkAddressInLocation(locationVo,new BigDecimal(113.319773),new BigDecimal(23.121664));
// System.out.println(check1);
// check1 = checkAddressInLocation(locationVo,new BigDecimal(113.307757),new BigDecimal(23.127249));
// System.out.println(check1);
LocationVo circulrVo = new LocationVo();
circulrVo.setRadius(9.0056);
circulrVo.setLongitude(116.404172);
circulrVo.setLatitude(39.916605);
circulrVo.setMarkerType(LocationVo.MARKER_TYPE_CIRCULAR);
boolean check2 = checkAddressInLocation(circulrVo, 116.404072, 39.916605);
System.out.println(check2);
}
}

@ -0,0 +1,24 @@
package com.ruoyi.dataprocess.amap;
import lombok.Data;
import java.math.BigDecimal;
/**
* @Description:
* @ClassName: PositionUtils.Postion
* @Author : xins
* @Date :2023-09-02 12:11
* @Version :1.0
*/
@Data
public class PositionVo{
private BigDecimal longitude;
private BigDecimal latitude;
public PositionVo(BigDecimal longitude, BigDecimal latitude) {
this.longitude = longitude;
this.latitude = latitude;
}
}

@ -0,0 +1,155 @@
package com.ruoyi.dataprocess.common;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.uuid.UUID;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
/**
* @Description:
* @ClassName: ImageUtils
* @Author : xins
* @Date :2023-09-04 15:57
* @Version :1.0
*/
public class ImageUtils {
public static final String BASE64_PREFIX = "data:image/";//base64图片前缀
public static final String BASE64_SUFFIX = ";base64";//base64图片后缀
/**
* @param imagePatternArr
* @return String
* @param: base64Str
* @description base64,
* @author xins
* @date 2023-09-04 16:05
*/
public static String getImageType(String base64Str, String[] imagePatternArr) {
for (String imagePattern : imagePatternArr) {
String base64Pattern = BASE64_PREFIX + imagePattern + BASE64_SUFFIX;
if (base64Str.indexOf(base64Pattern) > -1) {
return imagePattern;
}
}
return "";
}
/**
* @return String
* @param: imageFileName
* @description base64
* @author xins
* @date 2023-09-04 15:58
*/
public static String convertImageToBase64(String imageFileName) {
ByteArrayOutputStream baos = null;
try {
//获取图片类型
String suffix = imageFileName.substring(imageFileName.lastIndexOf(".") + 1);
//构建文件
File imageFile = new File(imageFileName);
//通过ImageIO把文件读取成BufferedImage对象
BufferedImage bufferedImage = ImageIO.read(imageFile);
//构建字节数组输出流
baos = new ByteArrayOutputStream();
//写入流
ImageIO.write(bufferedImage, suffix, baos);
//通过字节数组流获取字节数组
byte[] bytes = baos.toByteArray();
//获取JDK8里的编码器Base64.Encoder转为base64字符
return Base64.getEncoder().encodeToString(bytes);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (baos != null) {
baos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
/**
* @param: base64
* @param: imageFileName
* @description base64
* @author xins
* @date 2023-09-04 15:59
*/
public static String convertBase64ToImage(String base64Str, String imagePath, String imageType, Long deviceId) {
// 解密
try {
String fileName = UUID.randomUUID().toString().concat(".").concat(imageType);
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
Date date = new Date();
String dateStr = format.format(date);
String fullPath = imagePath + File.separator + deviceId
+ File.separator + dateStr;
File file = new File(fullPath);
if (!file.exists()) {
file.mkdirs();
}
// 去掉base64前缀 data:image/jpeg;base64,
String imageFileName = fullPath + File.separator + fileName;
base64Str = base64Str.substring(base64Str.indexOf(",", 1) + 1);
// 解密解密的结果是一个byte数组
Base64.Decoder decoder = Base64.getDecoder();
byte[] imgbytes = decoder.decode(base64Str);
for (int i = 0; i < imgbytes.length; ++i) {
if (imgbytes[i] < 0) {
imgbytes[i] += 256;
}
}
// 保存图片
OutputStream out = new FileOutputStream(imageFileName);
out.write(imgbytes);
out.flush();
out.close();
// 返回图片的相对路径 = 图片分类路径+图片名+图片后缀
return imageFileName;
} catch (IOException e) {
return null;
}
}
public static String getFileContent(FileInputStream fis, String encoding) throws IOException {
try (BufferedReader br = new BufferedReader(new InputStreamReader(fis, encoding))) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
return sb.toString();
}
}
public static void main(String[] args) throws IOException {
// 从txt文件中读取base64字符串
FileInputStream fis = new FileInputStream("e://base64test/base64test5.txt");
String base64Str = getFileContent(fis, "UTF-8");
String[] imagePatternArr = {"png", "jpg", "jpeg"};
String imageType = ImageUtils.getImageType(base64Str, imagePatternArr);
ImageUtils.convertBase64ToImage(base64Str,"images",imageType,2L);
// 将base64字符串翻译成图片
}
}

@ -0,0 +1,77 @@
package com.ruoyi.dataprocess.common;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;
@Service
public class SpringBeanUtils implements ApplicationContextAware, DisposableBean {
private static ApplicationContext applicationContext = null;
/**
* ApplicationContext.
*/
public static ApplicationContext getApplicationContext() {
assertContextInjected();
return applicationContext;
}
/**
* applicationContextBean, .
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(String name) {
// log.debug("从SpringContextHolder中取出Bean:" + name);
assertContextInjected();
return (T) applicationContext.getBean(name);
}
/**
* applicationContextBean, .
*/
public static <T> T getBean(Class<T> requiredType) {
assertContextInjected();
return applicationContext.getBean(requiredType);
}
/**
* SpringContextHolderApplicationContextNull.
*/
public static void clearHolder() {
// log.debug("清除SpringContextHolder中的ApplicationContext:"
// + applicationContext);
applicationContext = null;
}
/**
* ApplicationContextAware, Context.
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
if (SpringBeanUtils.applicationContext != null) {
// log.warn("SpringContextHolder中的ApplicationContext被覆盖, 原有ApplicationContext为:" + SpringContextHolder.applicationContext);
}
SpringBeanUtils.applicationContext = applicationContext; // NOSONAR
}
/**
* DisposableBean, Context.
*/
@Override
public void destroy() throws Exception {
SpringBeanUtils.clearHolder();
}
/**
* ApplicationContext.
*/
private static void assertContextInjected() {
if (applicationContext == null) {
throw new IllegalStateException("applicaitonContext属性未注入, 请在applicationContext.xml中定义SpringBeanUtils.");
}
}
}

@ -0,0 +1,38 @@
package com.ruoyi.dataprocess.config;
import com.ruoyi.dataprocess.listener.RedisMessageListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import java.util.Arrays;
import java.util.List;
@Configuration
public class RedisMessageListenerConfig {
@Autowired
private RedisMessageListener redisMessageListener;
@Autowired
private RedisConnectionFactory redisConnectionFactory;
/**
*
*/
@Bean
public RedisMessageListenerContainer container() {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(redisConnectionFactory);
//订阅频道
List<PatternTopic> topicList = Arrays.asList(new PatternTopic("life.*"),new PatternTopic("*.life"));
container.addMessageListener(redisMessageListener, topicList);
return container;
}
}

@ -0,0 +1,257 @@
package com.ruoyi.dataprocess.domain;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.core.annotation.Excel;
import com.ruoyi.common.core.web.domain.BaseEntity;
/**
* hw_alarm_info
*
* @author xins
* @date 2023-09-04
*/
public class HwAlarmInfo extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 报警信息ID */
private Long alarmInfoId;
/** 报警信息类型1、设备报警2、监控单元报警3、离线报警4、电子围栏 */
@Excel(name = "报警信息类型", readConverterExp = "1=、设备报警2、监控单元报警3、离线报警4、电子围栏")
private String alarmInfoType;
/** 1alarm_rulealarm_rule_id
3hw_offline_ruleoffline_rule_id
4hw_electronic_fenceelectronic_fence_id */
@Excel(name = "报警信息类型是1关联表alarm_rule的字段alarm_rule_id" +
"报警信息类型是3关联表hw_offline_rule的字段offline_rule_id " +
"报警信息类型是4关联表hw_electronic_fence的字段electronic_fence_id。")
private Long alarmReleatedId;
/** 报警设备ID关联hw_device表的device_id字段 */
@Excel(name = "报警设备ID关联hw_device表的device_id字段")
private Long deviceId;
/** 所属监控单元Id关联表hw_monitor_unit字段monitor_unit_id */
@Excel(name = "所属监控单元Id关联表hw_monitor_unit字段monitor_unit_id")
private Long monitorUnitId;
/** 所属场景ID关联hw_scene的scene_id */
@Excel(name = "所属场景ID关联hw_scene的scene_id")
private Long sceneId;
/** 报警级别关联hw_alarm_level的字段alarm_level_id报警信息类型为1、2和3时保存 */
@Excel(name = "报警级别关联hw_alarm_level的字段alarm_level_id报警信息类型为1、2和3时保存")
private Long alarmLevelId;
/** 报警类型关联hw_alarm_type的字段alarm_type_id报警信息类型为1和2时保存 */
@Excel(name = "报警类型关联hw_alarm_type的字段alarm_type_id报警信息类型为1和2时保存")
private Long alarmTypeId;
/** 设备模型功能ID */
@Excel(name = "设备模型功能ID")
private Long modeFunctionId;
/** 功能名称 */
@Excel(name = "功能名称")
private String functionName;
/** 标识符 */
@Excel(name = "标识符")
private String functionIdentifier;
/** 最新的值如果是电子围栏则存经度_纬度 */
@Excel(name = "最新的值如果是电子围栏则存经度_纬度")
private String functionValue;
/** 触发状态1、出界2、入界3、双向报警信息类型为4时保存 */
@Excel(name = "触发状态", readConverterExp = "1=、出界2、入界3、双向")
private String triggerStatus;
/** 处理状态0、未处理 1、已处理 */
@Excel(name = "处理状态", readConverterExp = "0=、未处理,1=、已处理")
private String handleStatus;
/** 实际报警时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "实际报警时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date alarmTime;
/** 预留字段 */
@Excel(name = "预留字段")
private String alarmInfoField;
public void setAlarmInfoId(Long alarmInfoId)
{
this.alarmInfoId = alarmInfoId;
}
public Long getAlarmInfoId()
{
return alarmInfoId;
}
public void setAlarmInfoType(String alarmInfoType)
{
this.alarmInfoType = alarmInfoType;
}
public String getAlarmInfoType()
{
return alarmInfoType;
}
public void setAlarmReleatedId(Long alarmReleatedId)
{
this.alarmReleatedId = alarmReleatedId;
}
public Long getAlarmReleatedId()
{
return alarmReleatedId;
}
public void setDeviceId(Long deviceId)
{
this.deviceId = deviceId;
}
public Long getDeviceId()
{
return deviceId;
}
public void setMonitorUnitId(Long monitorUnitId)
{
this.monitorUnitId = monitorUnitId;
}
public Long getMonitorUnitId()
{
return monitorUnitId;
}
public void setSceneId(Long sceneId)
{
this.sceneId = sceneId;
}
public Long getSceneId()
{
return sceneId;
}
public void setAlarmLevelId(Long alarmLevelId)
{
this.alarmLevelId = alarmLevelId;
}
public Long getAlarmLevelId()
{
return alarmLevelId;
}
public void setAlarmTypeId(Long alarmTypeId)
{
this.alarmTypeId = alarmTypeId;
}
public Long getAlarmTypeId()
{
return alarmTypeId;
}
public void setModeFunctionId(Long modeFunctionId)
{
this.modeFunctionId = modeFunctionId;
}
public Long getModeFunctionId()
{
return modeFunctionId;
}
public void setFunctionName(String functionName)
{
this.functionName = functionName;
}
public String getFunctionName()
{
return functionName;
}
public void setFunctionIdentifier(String functionIdentifier)
{
this.functionIdentifier = functionIdentifier;
}
public String getFunctionIdentifier()
{
return functionIdentifier;
}
public void setFunctionValue(String functionValue)
{
this.functionValue = functionValue;
}
public String getFunctionValue()
{
return functionValue;
}
public void setTriggerStatus(String triggerStatus)
{
this.triggerStatus = triggerStatus;
}
public String getTriggerStatus()
{
return triggerStatus;
}
public void setHandleStatus(String handleStatus)
{
this.handleStatus = handleStatus;
}
public String getHandleStatus()
{
return handleStatus;
}
public void setAlarmTime(Date alarmTime)
{
this.alarmTime = alarmTime;
}
public Date getAlarmTime()
{
return alarmTime;
}
public void setAlarmInfoField(String alarmInfoField)
{
this.alarmInfoField = alarmInfoField;
}
public String getAlarmInfoField()
{
return alarmInfoField;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("alarmInfoId", getAlarmInfoId())
.append("alarmInfoType", getAlarmInfoType())
.append("alarmReleatedId", getAlarmReleatedId())
.append("deviceId", getDeviceId())
.append("monitorUnitId", getMonitorUnitId())
.append("sceneId", getSceneId())
.append("alarmLevelId", getAlarmLevelId())
.append("alarmTypeId", getAlarmTypeId())
.append("modeFunctionId", getModeFunctionId())
.append("functionName", getFunctionName())
.append("functionIdentifier", getFunctionIdentifier())
.append("functionValue", getFunctionValue())
.append("triggerStatus", getTriggerStatus())
.append("handleStatus", getHandleStatus())
.append("alarmTime", getAlarmTime())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("alarmInfoField", getAlarmInfoField())
.toString();
}
}

@ -0,0 +1,341 @@
package com.ruoyi.dataprocess.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.core.annotation.Excel;
import com.ruoyi.common.core.web.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.util.Date;
/**
* hw_device
*
* @author xins
* @date 2023-08-24
*/
public class HwDevice extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 设备ID */
private Long deviceId;
/** 设备编号 */
@Excel(name = "设备编号")
private String deviceCode;
/** 设备名称 */
@Excel(name = "设备名称")
private String deviceName;
/** 所属场景关联hw_scene表的scene_id字段 */
@Excel(name = "所属场景关联hw_scene表的scene_id字段")
private Long sceneId;
/** 所属监控单元关联表hw_monitor_unit字段monitor_unit_id */
@Excel(name = "所属监控单元关联表hw_monitor_unit字段monitor_unit_id")
private Long monitorUnitId;
/** 设备类型1网关设备2网关子设备3直连设备 */
@Excel(name = "设备类型", readConverterExp = "1=网关设备2网关子设备3直连设备")
private String deviceType;
/** 联网方式(1:Wi-Fi2、蜂窝(2G/3G/4G/5G),3、以太网4、其他) */
@Excel(name = "联网方式(1:Wi-Fi2、蜂窝(2G/3G/4G/5G),3、以太网4、其他)")
private String networkingMode;
/** 接入协议1、MQTT */
@Excel(name = "接入协议", readConverterExp = "1=、MQTT")
private Long accessProtocol;
/** 数据格式1、Json */
@Excel(name = "数据格式", readConverterExp = "1=、Json")
private Long dataFormat;
/** 关联设备hw_device表中国的device_id */
@Excel(name = "关联设备hw_device表中国的device_id")
private Long releatedDeviceId;
/** 设备模型关联表hw_device_mode的字段device_mode_id */
@Excel(name = "设备模型关联表hw_device_mode的字段device_mode_id")
private Long deviceModeId;
/** 1Modbus
OPC-UA,Modbus */
@Excel(name = "接入网关协议", readConverterExp = "1=、Modbus")
private Long accessGwProtocol;
/** 激活状态1、激活0、未激活 */
@Excel(name = "激活状态", readConverterExp = "1=、激活0、未激活")
private String activeStatus;
/** 设备状态0、测试1、发布9、删除 */
@Excel(name = "设备状态", readConverterExp = "0=、测试1、发布9、删除")
private String deviceStatus;
/** 设备激活时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "设备激活时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date activeTime;
/** 设备图片地址(如果为空则可以使用设备模型图片) */
@Excel(name = "设备图片地址", readConverterExp = "如=果为空则可以使用设备模型图片")
private String devicePic;
/** 网络地址 */
@Excel(name = "网络地址")
private String ipAddress;
/** 预留字段设备所在区域ID关联表hw_area字段area_id) */
@Excel(name = "预留字段设备所在区域ID关联表hw_area字段area_id)")
private Long areaId;
/** 预留字段设备位置手动定位在地图上选择设备所在的固定位置自动定位设备自动定位位置关联网关自动定位位置。目前仅G780V2(固件版本V2.2.0之后)、PLCNET510、G800 V2和ModbusRTU(云端轮询)定位型变量支持选择自动定位功能)) */
@Excel(name = "预留字段,设备位置", readConverterExp = "手=动定位(在地图上选择设备所在的固定位置")
private String deviceLocation;
/** 当前固件版本(Linux系统) */
@Excel(name = "当前固件版本(Linux系统)")
private String currentModuleVersion;
/** 当前单片机固件版本 */
@Excel(name = "当前单片机固件版本")
private String currentSinglechipVersion;
/** 预留字段 */
@Excel(name = "预留字段")
private String deviceField;
public void setDeviceId(Long deviceId)
{
this.deviceId = deviceId;
}
public Long getDeviceId()
{
return deviceId;
}
public void setDeviceCode(String deviceCode)
{
this.deviceCode = deviceCode;
}
public String getDeviceCode()
{
return deviceCode;
}
public void setDeviceName(String deviceName)
{
this.deviceName = deviceName;
}
public String getDeviceName()
{
return deviceName;
}
public void setSceneId(Long sceneId)
{
this.sceneId = sceneId;
}
public Long getSceneId()
{
return sceneId;
}
public void setMonitorUnitId(Long monitorUnitId)
{
this.monitorUnitId = monitorUnitId;
}
public Long getMonitorUnitId()
{
return monitorUnitId;
}
public void setDeviceType(String deviceType)
{
this.deviceType = deviceType;
}
public String getDeviceType()
{
return deviceType;
}
public void setNetworkingMode(String networkingMode)
{
this.networkingMode = networkingMode;
}
public String getNetworkingMode()
{
return networkingMode;
}
public void setAccessProtocol(Long accessProtocol)
{
this.accessProtocol = accessProtocol;
}
public Long getAccessProtocol()
{
return accessProtocol;
}
public void setDataFormat(Long dataFormat)
{
this.dataFormat = dataFormat;
}
public Long getDataFormat()
{
return dataFormat;
}
public void setReleatedDeviceId(Long releatedDeviceId)
{
this.releatedDeviceId = releatedDeviceId;
}
public Long getReleatedDeviceId()
{
return releatedDeviceId;
}
public void setDeviceModeId(Long deviceModeId)
{
this.deviceModeId = deviceModeId;
}
public Long getDeviceModeId()
{
return deviceModeId;
}
public void setAccessGwProtocol(Long accessGwProtocol)
{
this.accessGwProtocol = accessGwProtocol;
}
public Long getAccessGwProtocol()
{
return accessGwProtocol;
}
public void setActiveStatus(String activeStatus)
{
this.activeStatus = activeStatus;
}
public String getActiveStatus()
{
return activeStatus;
}
public void setDeviceStatus(String deviceStatus)
{
this.deviceStatus = deviceStatus;
}
public String getDeviceStatus()
{
return deviceStatus;
}
public void setActiveTime(Date activeTime)
{
this.activeTime = activeTime;
}
public Date getActiveTime()
{
return activeTime;
}
public void setDevicePic(String devicePic)
{
this.devicePic = devicePic;
}
public String getDevicePic()
{
return devicePic;
}
public void setIpAddress(String ipAddress)
{
this.ipAddress = ipAddress;
}
public String getIpAddress()
{
return ipAddress;
}
public void setAreaId(Long areaId)
{
this.areaId = areaId;
}
public Long getAreaId()
{
return areaId;
}
public void setDeviceLocation(String deviceLocation)
{
this.deviceLocation = deviceLocation;
}
public String getDeviceLocation()
{
return deviceLocation;
}
public void setCurrentModuleVersion(String currentModuleVersion)
{
this.currentModuleVersion = currentModuleVersion;
}
public String getCurrentModuleVersion()
{
return currentModuleVersion;
}
public void setCurrentSinglechipVersion(String currentSinglechipVersion)
{
this.currentSinglechipVersion = currentSinglechipVersion;
}
public String getCurrentSinglechipVersion()
{
return currentSinglechipVersion;
}
public void setDeviceField(String deviceField)
{
this.deviceField = deviceField;
}
public String getDeviceField()
{
return deviceField;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("deviceId", getDeviceId())
.append("deviceCode", getDeviceCode())
.append("deviceName", getDeviceName())
.append("sceneId", getSceneId())
.append("monitorUnitId", getMonitorUnitId())
.append("deviceType", getDeviceType())
.append("networkingMode", getNetworkingMode())
.append("accessProtocol", getAccessProtocol())
.append("dataFormat", getDataFormat())
.append("releatedDeviceId", getReleatedDeviceId())
.append("deviceModeId", getDeviceModeId())
.append("accessGwProtocol", getAccessGwProtocol())
.append("activeStatus", getActiveStatus())
.append("deviceStatus", getDeviceStatus())
.append("activeTime", getActiveTime())
.append("devicePic", getDevicePic())
.append("ipAddress", getIpAddress())
.append("areaId", getAreaId())
.append("deviceLocation", getDeviceLocation())
.append("currentModuleVersion", getCurrentModuleVersion())
.append("currentSinglechipVersion", getCurrentSinglechipVersion())
.append("remark", getRemark())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("deviceField", getDeviceField())
.toString();
}
}

@ -0,0 +1,205 @@
package com.ruoyi.dataprocess.domain;
import com.ruoyi.common.core.annotation.Excel;
import com.ruoyi.common.core.web.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
public class HwElectronicFence extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 电子围栏ID */
private Long electronicFenceId;
/** 电子围栏名称 */
@Excel(name = "电子围栏名称")
private String electronicFenceName;
/** 所属场景 */
@Excel(name = "所属场景")
private Long sceneId;
/** 规则类型 */
@Excel(name = "规则类型")
private Long fenceType;
/** 生效时间标识 */
@Excel(name = "生效时间标识")
private String effectiveTimeFlag;
/** 生效时间开始时间_结束时间_状态多个用|隔开例如00:00_05:00_1|06:00_08:00_0,状态1、开启、2、关闭 */
@Excel(name = "生效时间开始时间_结束时间_状态多个用|隔开", readConverterExp = "例=如00:00_05:00_1|06:00_08:00_0")
private String effectiveTime;
/** 触发状态0、关闭1、出界2、入界3、双向 */
@Excel(name = "触发状态", readConverterExp = "0=、关闭1、出界2、入界3、双向")
private String triggerStatus;
/** 区域形状1、多边形2、圆形 */
@Excel(name = "区域形状", readConverterExp = "1=、多边形2、圆形")
private String areaShapeFlag;
/** 区域范围为多边形时保存格式经度_纬度多个以|隔开;为圆形时的中心点和半径,下划线隔开 */
@Excel(name = "区域范围", readConverterExp = "为多边形时保存格式为经度_纬度多个以|隔开;为圆形时的中心点和半径,下划线")
private String areaRange;
/** 报警推送标识(1、是0、否 */
@Excel(name = "报警推送标识(1、是0、否")
private Long fencePushFlag;
/** 报警推送内容 */
@Excel(name = "报警推送内容")
private String fencePushContent;
/** 恢复正常推送内容 */
@Excel(name = "恢复正常推送内容")
private String fenceRecoverContent;
/** 预留字段 */
@Excel(name = "预留字段")
private String fenceField;
public void setElectronicFenceId(Long electronicFenceId)
{
this.electronicFenceId = electronicFenceId;
}
public Long getElectronicFenceId()
{
return electronicFenceId;
}
public void setElectronicFenceName(String electronicFenceName)
{
this.electronicFenceName = electronicFenceName;
}
public String getElectronicFenceName()
{
return electronicFenceName;
}
public void setSceneId(Long sceneId)
{
this.sceneId = sceneId;
}
public Long getSceneId()
{
return sceneId;
}
public void setFenceType(Long fenceType)
{
this.fenceType = fenceType;
}
public Long getFenceType()
{
return fenceType;
}
public void setEffectiveTimeFlag(String effectiveTimeFlag)
{
this.effectiveTimeFlag = effectiveTimeFlag;
}
public String getEffectiveTimeFlag()
{
return effectiveTimeFlag;
}
public void setEffectiveTime(String effectiveTime)
{
this.effectiveTime = effectiveTime;
}
public String getEffectiveTime()
{
return effectiveTime;
}
public void setTriggerStatus(String triggerStatus)
{
this.triggerStatus = triggerStatus;
}
public String getTriggerStatus()
{
return triggerStatus;
}
public void setAreaShapeFlag(String areaShapeFlag)
{
this.areaShapeFlag = areaShapeFlag;
}
public String getAreaShapeFlag()
{
return areaShapeFlag;
}
public void setAreaRange(String areaRange)
{
this.areaRange = areaRange;
}
public String getAreaRange()
{
return areaRange;
}
public void setFencePushFlag(Long fencePushFlag)
{
this.fencePushFlag = fencePushFlag;
}
public Long getFencePushFlag()
{
return fencePushFlag;
}
public void setFencePushContent(String fencePushContent)
{
this.fencePushContent = fencePushContent;
}
public String getFencePushContent()
{
return fencePushContent;
}
public void setFenceRecoverContent(String fenceRecoverContent)
{
this.fenceRecoverContent = fenceRecoverContent;
}
public String getFenceRecoverContent()
{
return fenceRecoverContent;
}
public void setFenceField(String fenceField)
{
this.fenceField = fenceField;
}
public String getFenceField()
{
return fenceField;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("electronicFenceId", getElectronicFenceId())
.append("electronicFenceName", getElectronicFenceName())
.append("sceneId", getSceneId())
.append("fenceType", getFenceType())
.append("effectiveTimeFlag", getEffectiveTimeFlag())
.append("effectiveTime", getEffectiveTime())
.append("triggerStatus", getTriggerStatus())
.append("areaShapeFlag", getAreaShapeFlag())
.append("areaRange", getAreaRange())
.append("fencePushFlag", getFencePushFlag())
.append("fencePushContent", getFencePushContent())
.append("fenceRecoverContent", getFenceRecoverContent())
.append("remark", getRemark())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("fenceField", getFenceField())
.toString();
}
}

@ -0,0 +1,30 @@
package com.ruoyi.dataprocess.listener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class RedisMessageListener implements MessageListener {
@Autowired
private RedisTemplate redisTemplate;
@Override
public void onMessage(Message message, byte[] pattern) {
RedisSerializer keySerializer = redisTemplate.getKeySerializer();
RedisSerializer valueSerializer = redisTemplate.getValueSerializer();
log.info("----------Life接收到发布者消息----------");
log.info("|频道:{}",keySerializer.deserialize(message.getChannel()));
log.info("|当前监听器绑定的pattern:{}",new String(pattern));
log.info("|消息内容:{}",valueSerializer.deserialize(message.getBody()));
log.info("---------------------------------");
}
}

@ -0,0 +1,20 @@
package com.ruoyi.dataprocess.mapper;
import com.ruoyi.dataprocess.domain.HwAlarmInfo;
/**
* Mapper
*
* @author xins
* @date 2023-09-04
*/
public interface HwAlarmInfoMapper {
/**
*
*
* @param hwAlarmInfo
* @return
*/
public int insertHwAlarmInfo(HwAlarmInfo hwAlarmInfo);
}

@ -0,0 +1,25 @@
package com.ruoyi.dataprocess.mapper;
import com.ruoyi.dataprocess.domain.HwDevice;
import java.util.List;
/**
* Mapper
*
* @author xins
* @date 2023-08-24
*/
public interface HwDeviceMapper
{
/**
*
*
* @param deviceCode
* @return
*/
public HwDevice selectHwDeviceByDeviceCode(String deviceCode);
}

@ -0,0 +1,50 @@
package com.ruoyi.dataprocess.mapper;
import com.ruoyi.dataprocess.domain.HwElectronicFence;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @Description:
* @ClassName: HwElectronicFenceMapper
* @Author : xins
* @Date :2023-09-03 11:48
* @Version :1.0
*/
public interface HwElectronicFenceMapper {
public List<HwElectronicFence> selectSuitableElectronicFenceList(@Param("deviceId") Long deviceId,
@Param("monitorUnitId") Long monitorUnitId,
@Param("sceneId") Long sceneId);
/**
* @param: deviceId
* @description ID
* @author xins
* @date 2023-09-03 12:10
* @return List<HwElectronicFence>
*/
public List<HwElectronicFence> selectElectronicFencesByDeviceId(Long deviceId);
/**
* @param: monitorUnitId
* @description ID
* @author xins
* @date 2023-09-03 12:11
* @return List<HwElectronicFence>
*/
public List<HwElectronicFence> selectElectronicFencesByMonitorUnitId(Long monitorUnitId);
/**
* @param: sceneId
* @description Id
* @author xins
* @date 2023-09-03 12:11
* @return List<HwElectronicFence>
*/
public List<HwElectronicFence> selectElectronicFencesBySceneId(Long sceneId);
}

@ -0,0 +1,239 @@
package com.ruoyi.dataprocess.mqtt.client.config;
import com.ruoyi.dataprocess.mqtt.client.listener.MqttClientConnectListener;
import com.ruoyi.dataprocess.service.IDataProcessService;
import com.ruoyi.dataprocess.service.IDeviceStatusService;
import net.dreamlu.iot.mqtt.codec.MqttPublishMessage;
import net.dreamlu.iot.mqtt.codec.MqttQoS;
import net.dreamlu.iot.mqtt.codec.MqttSubAckMessage;
import net.dreamlu.iot.mqtt.core.client.IMqttClientMessageListener;
import net.dreamlu.iot.mqtt.core.client.MqttClient;
import net.dreamlu.iot.mqtt.core.client.MqttClientCreator;
import net.dreamlu.iot.mqtt.spring.client.MqttClientCustomizer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.tio.core.ChannelContext;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
//mqtt:
// client:
// enabled: true # 是否开启客户端默认false 使用到的场景有限,非必要请不要启用
// ip: 127.0.0.1 # 连接的服务端 ip 默认127.0.0.1
// port: 1883 # 端口默认1883
// name: Mica-Mqtt-Client # 名称默认Mica-Mqtt-Client
// clientId: 000001 # 客户端Id非常重要一般为设备 sn不可重复
// user-name: mica # 认证的用户名
// password: 123456 # 认证的密码
// timeout: 5 # 超时时间单位默认5秒
// reconnect: true # 是否重连默认true
// re-interval: 5000 # 重连时间,默认 5000 毫秒
// version: MQTT_5 # mqtt 协议版本默认3.1.1
// read-buffer-size: 8KB # 接收数据的 buffer size默认8k
// max-bytes-in-message: 10MB # 消息解析最大 bytes 长度默认10M
// buffer-allocator: heap # 堆内存和堆外内存,默认:堆内存
// keep-alive-secs: 60 # keep-alive 时间,单位:秒
// clean-session: true # mqtt clean session默认true
// use-ssl: false # 是否启用 ssl默认false
//todo:read-buffer-size
@Configuration
public class MqttConfiguration {
private static final Logger logger = LoggerFactory.getLogger(MqttConfiguration.class);
@Value("${mqtt.client.ip}")
String ip;
@Value("${mqtt.client.port}")
int port;
@Value("${mqtt.client.username}")
String username;
@Value("${mqtt.client.password}")
String password;
@Value("${mqtt.client.clientId}")
String clientId;
@Value("${mqtt.client.timeout}")
int timeOut;
@Value("${mqtt.client.keepalive}")
int keepAlive;
@Value("${mqtt.client.qos}")
int qos;
@Value("${mqtt.client.dataTopicFilter}")
String dataTopicFilter;
@Value("${mqtt.client.deviceStatusTopic}")
String deviceStatusTopic;
@Value("${mqtt.client.imagePath}")
String imagePath;
@Value("${mqtt.client.imagePatterns}")
String imagePatterns;
@Autowired
private IDataProcessService dataProcessService;
@Autowired
private IDeviceStatusService deviceStatusService;
@Bean//注入spring
public MqttClientCustomizer mqttClientCustomizer() {
return new MqttClientCustomizer() {
@Override
public void customize(MqttClientCreator creator) {
// 此处可自定义配置 creator会覆盖 yml 中的配置
System.out.println("----------------MqttServerCustomizer-----------------");
MqttClient client = creator.ip(ip)
.port(port)
.username(username)
.password(password)
.timeout(timeOut)
.keepAliveSecs(keepAlive)
// 如果包体过大,建议将此参数设置和 maxBytesInMessage 一样大
// .readBufferSize(1024 * 10)
// 最大包体长度,如果包体过大需要设置此参数
// .maxBytesInMessage(1024 * 10)
// .version(MqttVersion.MQTT_5)
// 连接监听
.connectListener(new MqttClientConnectListener())
.willMessage(builder -> {
builder.topic("/test/offline")
.messageText("down")
.retain(false)
.qos(MqttQoS.AT_MOST_ONCE); // 遗嘱消息
})
// 同步连接,也可以使用 connect() 异步(可以避免 broker 没启动照成启动卡住),但是下面的订阅和发布可能还没连接成功。
.connectSync();
String[] topicArr = {dataTopicFilter, deviceStatusTopic};
client.subscribe(topicArr, MqttQoS.valueOf(qos), new IMqttClientMessageListener() {
@Override
public void onSubscribed(ChannelContext context, String topicFilter, MqttQoS mqttQoS, MqttSubAckMessage message) {
IMqttClientMessageListener.super.onSubscribed(context, topicFilter, mqttQoS, message);
}
@Override
public void onSubscribed(ChannelContext context, String topicFilter, MqttQoS mqttQoS) {
IMqttClientMessageListener.super.onSubscribed(context, topicFilter, mqttQoS);
}
@Override
public void onMessage(ChannelContext channelContext, String topic, MqttPublishMessage mqttPublishMessage, ByteBuffer payload) {
System.out.println("dataprocessservice:" + dataProcessService);
String payloadString = new String(payload.array(), StandardCharsets.UTF_8);
System.out.println("paa:" + topic);
logger.info("topic:{} payload:{}", topic, payloadString);
System.out.println(topic+"----"+dataTopicFilter);
System.out.println(topic.startsWith(dataTopicFilter));
if (topic.startsWith(dataTopicFilter.replace("#",""))) {
dataProcessService.processBusinessData(payloadString, imagePath, imagePatterns);
} else if (topic.equals(deviceStatusTopic)) {
deviceStatusService.handleDeviceStatus();
}
}
});
// client.subscribe(topicArr,MqttQoS.valueOf(1),new MqttClientMessageListener());
// client.subQos0(dataTopic,new MqttClientMessageListener());
}
};
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public int getTimeOut() {
return timeOut;
}
public void setTimeOut(int timeOut) {
this.timeOut = timeOut;
}
public int getKeepAlive() {
return keepAlive;
}
public void setKeepAlive(int keepAlive) {
this.keepAlive = keepAlive;
}
public int getQos() {
return qos;
}
public void setQos(int qos) {
this.qos = qos;
}
public String getDataTopicFilter() {
return dataTopicFilter;
}
public void setDataTopicFilter(String dataTopicFilter) {
this.dataTopicFilter = dataTopicFilter;
}
public String getDeviceStatusTopic() {
return deviceStatusTopic;
}
public void setDeviceStatusTopic(String deviceStatusTopic) {
this.deviceStatusTopic = deviceStatusTopic;
}
public String getImagePath() {
return imagePath;
}
public void setImagePath(String imagePath) {
this.imagePath = imagePath;
}
public String getImagePatterns() {
return imagePatterns;
}
public void setImagePatterns(String imagePatterns) {
this.imagePatterns = imagePatterns;
}
}

@ -0,0 +1,29 @@
//package com.ruoyi.dataprocess.mqtt.client.controller;
//
//import com.ruoyi.dataprocess.mqtt.client.service.ClientService;
//import io.swagger.v3.oas.annotations.Operation;
//import io.swagger.v3.oas.annotations.tags.Tag;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.web.bind.annotation.*;
//
//@Tag(name = "Mqtt::客户端")
//@RequestMapping("/mqtt/client")
//@RestController
//public class ClientController {
//
// @Autowired
// private ClientService service;
//
// @Operation(summary = "publish")
// @PostMapping("/publish")
// public boolean publish(@RequestBody String body) {
// return service.publish(body);
// }
//
// @Operation(summary = "sub")
// @GetMapping("/sub")
// public boolean sub() {
// return service.sub();
// }
//
//}

@ -0,0 +1,48 @@
/*
* Copyright (c) 2019-2029, Dreamlu (596392912@qq.com & dreamlu.net).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.ruoyi.dataprocess.mqtt.client.listener;
import net.dreamlu.iot.mqtt.core.client.IMqttClientConnectListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.tio.core.ChannelContext;
/**
*
*
* @author L.cm
*/
@Service
public class MqttClientConnectListener implements IMqttClientConnectListener {
private static final Logger logger = LoggerFactory.getLogger(MqttClientConnectListener.class);
@Override
public void onConnected(ChannelContext context, boolean isReconnect) {
if (isReconnect) {
logger.info("重连 mqtt 服务器重连成功...");
} else {
logger.info("连接 mqtt 服务器成功...");
}
}
@Override
public void onDisconnect(ChannelContext channelContext, Throwable throwable, String remark, boolean isRemove) {
logger.error("mqtt 链接断开 remark:{} isRemove:{}", remark, isRemove, throwable);
}
}

@ -0,0 +1,67 @@
//package com.ruoyi.dataprocess.mqtt.client.listener;
//
//import com.alibaba.fastjson.JSONArray;
//import com.alibaba.fastjson.JSONObject;
//import com.ruoyi.common.core.constant.TdEngineConstants;
//import com.ruoyi.common.core.domain.R;
//import com.ruoyi.common.core.enums.ResultEnums;
//import com.ruoyi.common.core.utils.SpringUtils;
//import com.ruoyi.common.core.utils.StringUtils;
//import com.ruoyi.dataprocess.common.SpringBeanUtils;
//import com.ruoyi.dataprocess.mapper.HwDeviceMapper;
//import com.ruoyi.dataprocess.mqtt.client.config.MqttConfiguration;
//import com.ruoyi.dataprocess.service.IDataProcessService;
//import com.ruoyi.system.api.RemoteFileService;
//import com.ruoyi.system.api.factory.RemoteFileFallbackFactory;
//import com.ruoyi.tdengine.api.RemoteTdEngineService;
//import com.ruoyi.tdengine.api.domain.TdField;
//import net.dreamlu.iot.mqtt.codec.MqttPublishMessage;
//import net.dreamlu.iot.mqtt.core.client.IMqttClientMessageListener;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Component;
//import org.springframework.stereotype.Controller;
//import org.springframework.stereotype.Service;
//import org.tio.core.ChannelContext;
//
//import javax.annotation.PostConstruct;
//import javax.annotation.Resource;
//import java.nio.ByteBuffer;
//import java.nio.charset.StandardCharsets;
//import java.util.List;
//
///**
// * 客户端消息监听的另一种方式
// *
// * @author L.cm
// */
//@Service
//public class MqttClientMessageListener implements IMqttClientMessageListener {
// private static final Logger logger = LoggerFactory.getLogger(MqttClientMessageListener.class);
//
// private IDataProcessService dataProcessService;
//
//// @PostConstruct
//// public void init() {
//// remoteTdEngineService = SpringBeanUtils.getBean(RemoteTdEngineService.class);
//// System.out.println("--***-"+remoteTdEngineService);
////
//// }
//
// @Override
// public void onMessage(ChannelContext context, String topic, MqttPublishMessage message, ByteBuffer payload) {
// String payloadString = new String(payload.array(), StandardCharsets.UTF_8);
// System.out.println("paa:" + topic);
//// System.out.println("data"+dataProcessService);
// if(dataProcessService == null){
// dataProcessService = SpringBeanUtils.getBean(IDataProcessService.class);
// }
//// if(topic.startsWith(MqttConfiguration))
// dataProcessService.processBusinessData(payloadString);
// logger.info("topic:{} payload:{}", topic, payloadString);
// }
//
//
//}
//

@ -0,0 +1,45 @@
//package com.ruoyi.dataprocess.mqtt.client.service;
//
//import com.ruoyi.dataprocess.mqtt.client.config.MqttConfiguration;
//import com.ruoyi.dataprocess.mqtt.client.listener.MqttClientConnectListener;
//import com.ruoyi.dataprocess.mqtt.client.listener.MqttClientMessageListener;
//import net.dreamlu.iot.mqtt.codec.MqttQoS;
//import net.dreamlu.iot.mqtt.core.client.MqttClient;
//import net.dreamlu.iot.mqtt.spring.client.MqttClientTemplate;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Component;
//import org.springframework.stereotype.Service;
//
//import javax.annotation.PostConstruct;
//import java.nio.charset.StandardCharsets;
//import java.util.Arrays;
//
///**
// * @Description: MQTT客户端服务
// * @ClassName: ClientService
// * @Author : xins
// * @Date :2023-08-31 14:33
// * @Version :1.0
// */
//public class ClientService {
// private static final Logger logger = LoggerFactory.getLogger(ClientService.class);
//
// private MqttClientTemplate client;
//
// public boolean publish(String body) {
// client.publish("/test/client", body.getBytes(StandardCharsets.UTF_8));
// return true;
// }
//
// public boolean sub(String topic) {
// client.subQos0(topic, new MqttClientMessageListener());
//// String[] topicsArr = topics.split(",");
//// Arrays.asList(topicsArr).forEach(topicFilter ->
//// client.subQos0(topicFilter, new MqttClientMessageListener())
//// );
// return true;
// }
//
//}

@ -0,0 +1,15 @@
package com.ruoyi.dataprocess.service;
public interface IDataProcessService {
/**
* @param: jsonData
* @param imagePath
* @param imagePatterns
* @description
* @author xins
* @date 2023-08-31 16:16
*/
public void processBusinessData(String jsonData,String imagePath,String imagePatterns);
}

@ -0,0 +1,13 @@
package com.ruoyi.dataprocess.service;
/**
* @Description:
* @ClassName: IDeviceStatusService
* @Author : xins
* @Date :2023-09-04 15:32
* @Version :1.0
*/
public interface IDeviceStatusService {
public void handleDeviceStatus();
}

@ -0,0 +1,294 @@
package com.ruoyi.dataprocess.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.constant.HwDictConstants;
import com.ruoyi.common.core.constant.TdEngineConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.enums.ResultEnums;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.dataprocess.amap.LocationVo;
import com.ruoyi.dataprocess.amap.PositionUtils;
import com.ruoyi.dataprocess.amap.PositionVo;
import com.ruoyi.dataprocess.common.ImageUtils;
import com.ruoyi.dataprocess.domain.HwAlarmInfo;
import com.ruoyi.dataprocess.domain.HwDevice;
import com.ruoyi.dataprocess.domain.HwElectronicFence;
import com.ruoyi.dataprocess.mapper.HwAlarmInfoMapper;
import com.ruoyi.dataprocess.mapper.HwDeviceMapper;
import com.ruoyi.dataprocess.mapper.HwElectronicFenceMapper;
import com.ruoyi.dataprocess.service.IDataProcessService;
import com.ruoyi.tdengine.api.RemoteTdEngineService;
import com.ruoyi.tdengine.api.domain.TdField;
import com.ruoyi.tdengine.api.domain.TdTableVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* @Description:
* @ClassName: DataProcessServiceImpl
* @Author : xins
* @Date :2023-09-04 8:58
* @Version :1.0
*/
@Service
public class DataProcessServiceImpl implements IDataProcessService {
private static final Logger logger = LoggerFactory.getLogger(DataProcessServiceImpl.class);
@Resource
private RemoteTdEngineService remoteTdEngineService;
@Autowired
private HwDeviceMapper hwDeviceMapper;
@Autowired
private HwElectronicFenceMapper hwElectronicFenceMapper;
@Autowired
private HwAlarmInfoMapper hwAlarmInfoMapper;
/**
* @param imagePath
* @param imagePatterns
* @param: jsonData
* @description
* @author xins
* @date 2023-08-31 16:16
*/
@Override
public void processBusinessData(String jsonData, String imagePath, String imagePatterns) {
JSONObject json = JSON.parseObject(jsonData);
Long ts = json.getLong(TdEngineConstants.PAYLOAD_TS);
String tsStr = String.valueOf(ts);
if (tsStr.length() == 10) {
ts = ts * 1000;
}
JSONArray paramArr = json.getJSONArray(TdEngineConstants.PAYLOAD_PARAM);
// System.out.println(this.hwDeviceMapper);
// System.out.println(this.remoteTdEngineService);
for (int i = 0; i < paramArr.size(); i++) {
JSONObject paramJson = paramArr.getJSONObject(i);
JSONObject dataValueJson = paramJson.getJSONObject(TdEngineConstants.PAYLOAD_DATAVALUE);
String deviceCode = dataValueJson.getString(TdEngineConstants.PAYLOAD_DEVICE_CODE);
HwDevice hwDevice = hwDeviceMapper.selectHwDeviceByDeviceCode(deviceCode);
Long sceneId = hwDevice.getSceneId();
Long deviceId = hwDevice.getDeviceId();
Long monitorUnitId = hwDevice.getMonitorUnitId();
String databaseName = TdEngineConstants.DEFAULT_DB_NAME_PREFIX + sceneId;
String tableName = TdEngineConstants.DEFAULT_TABLE_NAME_PREFIX + deviceId;
dataValueJson.remove(TdEngineConstants.PAYLOAD_DEVICE_CODE);
TdTableVo tdTableVo = new TdTableVo();
List<TdField> schemaFields = new ArrayList<>();
//添加timestamp字段默认字段名称是ts协议上传的key是timestamp
TdField firstTdField = new TdField();
firstTdField.setFieldName(TdEngineConstants.DEFAULT_FIRST_FIELD_NAME);
firstTdField.setFieldValue(ts);
schemaFields.add(firstTdField);
Object longitude = null;
Object latitude = null;
for (Map.Entry<String, Object> entry : dataValueJson.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
/**
* keykeyvaluevalue1
*/
key = TdEngineConstants.TDENGINE_KEY_TRANSFER_MAP.get(key) == null ? key
: TdEngineConstants.TDENGINE_KEY_TRANSFER_MAP.get(key);
System.out.println(key + "---" + value);
if (value instanceof String) {
String valueStr = (String) value;
if (StringUtils.isNotBlank(valueStr)) {
/**
* ,
*/
String[] imagePatternArr = imagePatterns.split(",");
String imageType = ImageUtils.getImageType(valueStr, imagePatternArr);
if (StringUtils.isNotBlank(imageType)) {
//保存图片,并返回图片详细地址进行赋值保存
String imageFileName = ImageUtils.convertBase64ToImage(valueStr, imagePath, imageType, deviceId);
if (StringUtils.isNotBlank(imageFileName)) {
value = imageFileName;
} else {
continue;
}
}
TdField tdField = new TdField();
tdField.setFieldName(key);
tdField.setFieldValue(value);
schemaFields.add(tdField);
}
} else {
TdField tdField = new TdField();
tdField.setFieldName(key);
tdField.setFieldValue(value);
schemaFields.add(tdField);
//经纬度判断
if (key.equalsIgnoreCase(HwDictConstants.DEFAULT_FUNCTION_LONGITUDE_IDENTIFIER)) {
longitude = value;
} else if (key.equalsIgnoreCase(HwDictConstants.DEFAULT_FUNCTION_LATITUDE_IDENTIFIER)) {
latitude = value;
}
}
}
System.out.println(databaseName + "---" + tableName);
tdTableVo.setDatabaseName(databaseName);
tdTableVo.setTableName(tableName);
tdTableVo.setSchemaFields(schemaFields);
System.out.println("longtitude:" + longitude + "latit:" + latitude);
final R<?> insertResult = this.remoteTdEngineService.insertTable(tdTableVo);
if (insertResult.getCode() == ResultEnums.SUCCESS.getCode()) {
logger.info("Insert data result: {}", insertResult.getMsg());
} else {
logger.error("Insert data Exception: {},data:{}", insertResult.getMsg(), jsonData);
}
if (longitude != null && latitude != null) {
checkElectronicFence(deviceId, monitorUnitId, sceneId, longitude, latitude, ts);
}
}
}
/**
* @param: deviceId
* @param: monitorUnitId
* @param: sceneId
* @param: longitude
* @param: latitude
* @param: ts
* @description
* @author xins
* @date 2023-09-04 14:04
*/
private void checkElectronicFence(Long deviceId, Long monitorUnitId, Long sceneId, Object longitude, Object latitude, Long ts) {
List<HwElectronicFence> hwElectronicFences = hwElectronicFenceMapper.selectElectronicFencesByDeviceId(deviceId);
if (StringUtils.isEmpty(hwElectronicFences)) {
System.out.println("---------");
hwElectronicFences = hwElectronicFenceMapper.selectElectronicFencesByMonitorUnitId(monitorUnitId);
}
if (StringUtils.isEmpty(hwElectronicFences)) {
hwElectronicFences = hwElectronicFenceMapper.selectElectronicFencesBySceneId(sceneId);
System.out.println("---------33333");
}
if (StringUtils.isNotEmpty(hwElectronicFences)) {
hwElectronicFences.forEach(hwElectronicFence -> {
String effectiveTimeFlag = hwElectronicFence.getEffectiveTimeFlag();
String triggerStatus = hwElectronicFence.getTriggerStatus();
boolean isAlarmed = false;//是否报警
if (effectiveTimeFlag.equals(HwDictConstants.EFFECTIVE_TIME_FLAG_LONG)) {
String areaShapeFlag = hwElectronicFence.getAreaShapeFlag();
String areaRange = hwElectronicFence.getAreaRange();
if (areaShapeFlag.equals(HwDictConstants.AREA_SHAPE_FLAG_POLYGN)) {
LocationVo polygonVo = new LocationVo();
polygonVo.setMarkerType(LocationVo.MARKER_TYPE_POLYGON);
List<List<PositionVo>> polygonList = new ArrayList<>();
List<PositionVo> postionList = new ArrayList<>();
String[] areaRangeArr = areaRange.split("_");//多个点每个点的经纬度信息经度_纬度
for (String areaRange1 : areaRangeArr) {
String[] areaRange1Arr = areaRange1.split(",");
String longitudeStr = areaRange1Arr[0];
String latitudeStr = areaRange1Arr[1];
postionList.add(new PositionVo(new BigDecimal(longitudeStr), new BigDecimal(latitudeStr)));
polygonList.add(postionList);
}
polygonVo.setPolygonList(polygonList);
/**
* longitudelatitudeobjectBigDecimalDoubleLongIntegerStringDouble
*/
boolean isWithin = PositionUtils.checkAddressInLocation(polygonVo, Double.valueOf(String.valueOf(longitude)), Double.valueOf(String.valueOf(latitude)));
if (triggerStatus.equals(HwDictConstants.ELECTRONIC_FENCE_TRIGGER_STATUS_EXIT) && !isWithin) {//如果电子围栏配置是出界,而此设备出界则报警
isAlarmed = true;
} else if (triggerStatus.equals(HwDictConstants.ELECTRONIC_FENCE_TRIGGER_STATUS_ENTRY) && isWithin) {//如果电子围栏配置是入界,而此设备入界则报警
isAlarmed = true;
}
System.out.println("iswithin" + isWithin);
} else if (areaShapeFlag.equals(HwDictConstants.AREA_SHAPE_FLAG_CIRCULA)) {
String[] areaRangeArr = areaRange.split(",");
String longitudeStr = areaRangeArr[0];
String latitudeStr = areaRangeArr[1];
String radiusStr = areaRangeArr[2];
LocationVo circulrVo = new LocationVo();
circulrVo.setRadius(Double.valueOf(radiusStr));
circulrVo.setLongitude(Double.valueOf(longitudeStr));
circulrVo.setLatitude(Double.valueOf(latitudeStr));
circulrVo.setMarkerType(LocationVo.MARKER_TYPE_CIRCULAR);
boolean isWithin = PositionUtils.checkAddressInLocation(circulrVo, Double.valueOf(String.valueOf(longitude)), Double.valueOf(String.valueOf(latitude)));
System.out.println("iswithin:" + isWithin);
if (triggerStatus.equals(HwDictConstants.ELECTRONIC_FENCE_TRIGGER_STATUS_EXIT) && !isWithin) {//如果电子围栏配置是出界,而此设备出界则报警
isAlarmed = true;
} else if (triggerStatus.equals(HwDictConstants.ELECTRONIC_FENCE_TRIGGER_STATUS_ENTRY) && isWithin) {//如果电子围栏配置是入界,而此设备入界则报警
isAlarmed = true;
}
}
}
if (isAlarmed) {
HwAlarmInfo hwAralmInfo = new HwAlarmInfo();
hwAralmInfo.setAlarmInfoType(HwDictConstants.ALARM_INFO_TYPE_ELECTRONIC_FENCE);
hwAralmInfo.setAlarmReleatedId(hwElectronicFence.getElectronicFenceId());
hwAralmInfo.setDeviceId(deviceId);
hwAralmInfo.setMonitorUnitId(monitorUnitId);
hwAralmInfo.setSceneId(sceneId);
hwAralmInfo.setFunctionValue(longitude + "_" + latitude);
hwAralmInfo.setTriggerStatus(triggerStatus);
hwAralmInfo.setAlarmTime(new Date(ts));
hwAralmInfo.setCreateTime(new Date());
hwAlarmInfoMapper.insertHwAlarmInfo(hwAralmInfo);
}
});
}
}
public static void main(String[] args) {
System.out.println(System.currentTimeMillis());
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
Date date = new Date();
System.out.println(format.format(date));
Object jsonData = "{\n" +
"\n" +
" \"timestamp\": 1689814424,\"type\": \"CMD_REPORTDATA\",\n" +
" \"param\": [\n{\n" +
" \"datatype\": \"cttemperature\",\n" +
"\"datavalue\": {\n" +
" \"uid\": \"0009340109040126\", \"alias\": \"\",\n" +
" \"value\": 25.6,\n" +
" \"voltage\": 3.76,\n" +
" \"rssi\": -80\n" +
" } },\n" +
" {\"datatype\": \"cttemperature\",\n" +
" \"datavalue\": {\n" +
" \"uid1\": \"00093440109040924\",\n" +
" \"alias\": \"\",\n" +
" \"value\": 25.6,\n" +
" \"voltage\": 3.64,\n" +
" \"rssi\": -87\n" +
" }\n" +
" }]}";
}
}

@ -0,0 +1,27 @@
package com.ruoyi.dataprocess.service.impl;
import com.ruoyi.dataprocess.service.IDeviceStatusService;
import com.ruoyi.tdengine.api.RemoteTdEngineService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* @Description:
* @ClassName: DeviceStatusServiceImpl
* @Author : xins
* @Date :2023-09-04 15:31
* @Version :1.0
*/
@Service
public class DeviceStatusServiceImpl implements IDeviceStatusService {
@Resource
private RemoteTdEngineService remoteTdEngineService;
@Override
public void handleDeviceStatus(){
System.out.println("handleDeviceStatus");
}
}

@ -0,0 +1,32 @@
package com.ruoyi.dataprocess.mqtt.client.service;
import net.dreamlu.iot.mqtt.spring.client.MqttClientTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.nio.charset.StandardCharsets;
/**
* @author wsq
*/
@Service
public class ClientService {
private static final Logger logger = LoggerFactory.getLogger(ClientService.class);
@Autowired
private MqttClientTemplate client;
public boolean publish(String body) {
client.publish("/test/client", body.getBytes(StandardCharsets.UTF_8));
return true;
}
public boolean sub() {
client.subQos0("/test/#", (context, topic, message, payload) -> {
logger.info(topic + '\t' + new String(payload, StandardCharsets.UTF_8));
});
return true;
}
}

@ -0,0 +1,54 @@
/*
* Copyright (c) 2019-2029, Dreamlu (596392912@qq.com & dreamlu.net).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.ruoyi.dataprocess.mqtt.client.listener;
import net.dreamlu.iot.mqtt.core.client.MqttClientCreator;
import net.dreamlu.iot.mqtt.spring.client.event.MqttConnectedEvent;
import net.dreamlu.iot.mqtt.spring.client.event.MqttDisconnectEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
/**
*
*
* @author L.cm
*/
@Service
public class MqttClientConnectListener {
private static final Logger logger = LoggerFactory.getLogger(MqttClientConnectListener.class);
@Autowired
private MqttClientCreator mqttClientCreator;
@EventListener
public void onConnected(MqttConnectedEvent event) {
logger.info("MqttConnectedEvent:{}", event);
}
@EventListener
public void onDisconnect(MqttDisconnectEvent event) {
logger.info("MqttDisconnectEvent:{}", event);
// 在断线时更新 clientId、username、password
mqttClientCreator.clientId("newClient" + System.currentTimeMillis())
.username("newUserName")
.password("newPassword");
}
}

@ -0,0 +1,10 @@
Spring Boot Version: ${spring-boot.version}
Spring Application Name: ${spring.application.name}
_ _
(_) | |
_ __ _ _ ___ _ _ _ ______ ___ _ _ ___ | |_ ___ _ __ ___
| '__|| | | | / _ \ | | | || ||______|/ __|| | | |/ __|| __| / _ \| '_ ` _ \
| | | |_| || (_) || |_| || | \__ \| |_| |\__ \| |_ | __/| | | | | |
|_| \__,_| \___/ \__, ||_| |___/ \__, ||___/ \__| \___||_| |_| |_|
__/ | __/ |
|___/ |___/

@ -0,0 +1,25 @@
# Tomcat
server:
port: 9603
# Spring
spring:
application:
# 应用名称
name: hw-data-process
profiles:
# 环境配置
active: dev
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: 127.0.0.1:8848
config:
# 配置中心地址
server-addr: 127.0.0.1:8848
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 日志存放路径 -->
<property name="log.path" value="logs/hw-data-process" />
<!-- 日志输出格式 -->
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 系统日志输出 -->
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/info.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>INFO</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/error.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>ERROR</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 系统模块日志级别控制 -->
<logger name="com.ruoyi" level="info" />
<!-- Spring日志级别控制 -->
<logger name="org.springframework" level="warn" />
<root level="info">
<appender-ref ref="console" />
</root>
<!--系统操作日志-->
<root level="info">
<appender-ref ref="file_info" />
<appender-ref ref="file_error" />
</root>
</configuration>

@ -0,0 +1,75 @@
<?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.ruoyi.dataprocess.mapper.HwAlarmInfoMapper">
<resultMap type="HwAlarmInfo" id="HwAlarmInfoResult">
<result property="alarmInfoId" column="alarm_info_id" />
<result property="alarmInfoType" column="alarm_info_type" />
<result property="alarmReleatedId" column="alarm_releated_id" />
<result property="deviceId" column="device_id" />
<result property="monitorUnitId" column="monitor_unit_id" />
<result property="sceneId" column="scene_id" />
<result property="alarmLevelId" column="alarm_level_id" />
<result property="alarmTypeId" column="alarm_type_id" />
<result property="modeFunctionId" column="mode_function_id" />
<result property="functionName" column="function_name" />
<result property="functionIdentifier" column="function_identifier" />
<result property="functionValue" column="function_value" />
<result property="triggerStatus" column="trigger_status" />
<result property="handleStatus" column="handle_status" />
<result property="alarmTime" column="alarm_time" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<result property="alarmInfoField" column="alarm_info_field" />
</resultMap>
<insert id="insertHwAlarmInfo" parameterType="HwAlarmInfo" useGeneratedKeys="true" keyProperty="alarmInfoId">
insert into hw_alarm_info
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="alarmInfoType != null and alarmInfoType != ''">alarm_info_type,</if>
<if test="alarmReleatedId != null">alarm_releated_id,</if>
<if test="deviceId != null">device_id,</if>
<if test="monitorUnitId != null">monitor_unit_id,</if>
<if test="sceneId != null">scene_id,</if>
<if test="alarmLevelId != null">alarm_level_id,</if>
<if test="alarmTypeId != null">alarm_type_id,</if>
<if test="modeFunctionId != null">mode_function_id,</if>
<if test="functionName != null">function_name,</if>
<if test="functionIdentifier != null">function_identifier,</if>
<if test="functionValue != null">function_value,</if>
<if test="triggerStatus != null">trigger_status,</if>
<if test="handleStatus != null and handleStatus != ''">handle_status,</if>
<if test="alarmTime != null">alarm_time,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
<if test="alarmInfoField != null">alarm_info_field,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="alarmInfoType != null and alarmInfoType != ''">#{alarmInfoType},</if>
<if test="alarmReleatedId != null">#{alarmReleatedId},</if>
<if test="deviceId != null">#{deviceId},</if>
<if test="monitorUnitId != null">#{monitorUnitId},</if>
<if test="sceneId != null">#{sceneId},</if>
<if test="alarmLevelId != null">#{alarmLevelId},</if>
<if test="alarmTypeId != null">#{alarmTypeId},</if>
<if test="modeFunctionId != null">#{modeFunctionId},</if>
<if test="functionName != null">#{functionName},</if>
<if test="functionIdentifier != null">#{functionIdentifier},</if>
<if test="functionValue != null">#{functionValue},</if>
<if test="triggerStatus != null">#{triggerStatus},</if>
<if test="handleStatus != null and handleStatus != ''">#{handleStatus},</if>
<if test="alarmTime != null">#{alarmTime},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="alarmInfoField != null">#{alarmInfoField},</if>
</trim>
</insert>
</mapper>

@ -0,0 +1,47 @@
<?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.ruoyi.dataprocess.mapper.HwDeviceMapper">
<resultMap type="com.ruoyi.dataprocess.domain.HwDevice" id="HwDeviceResult">
<result property="deviceId" column="device_id" />
<result property="deviceCode" column="device_code" />
<result property="deviceName" column="device_name" />
<result property="sceneId" column="scene_id" />
<result property="monitorUnitId" column="monitor_unit_id" />
<result property="deviceType" column="device_type" />
<result property="networkingMode" column="networking_mode" />
<result property="accessProtocol" column="access_protocol" />
<result property="dataFormat" column="data_format" />
<result property="releatedDeviceId" column="releated_device_id" />
<result property="deviceModeId" column="device_mode_id" />
<result property="accessGwProtocol" column="access_gw_protocol" />
<result property="activeStatus" column="active_status" />
<result property="deviceStatus" column="device_status" />
<result property="activeTime" column="active_time" />
<result property="devicePic" column="device_pic" />
<result property="ipAddress" column="ip_address" />
<result property="areaId" column="area_id" />
<result property="deviceLocation" column="device_location" />
<result property="currentModuleVersion" column="current_module_version" />
<result property="currentSinglechipVersion" column="current_singlechip_version" />
<result property="remark" column="remark" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<result property="deviceField" column="device_field" />
</resultMap>
<sql id="selectHwDeviceVo">
select device_id, device_code, scene_id, monitor_unit_id, device_type, device_mode_id, device_status from hw_device
</sql>
<select id="selectHwDeviceByDeviceCode" parameterType="String" resultMap="HwDeviceResult">
<include refid="selectHwDeviceVo"/>
where device_code = #{deviceCode} limit 1
</select>
</mapper>

@ -0,0 +1,57 @@
<?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.ruoyi.dataprocess.mapper.HwElectronicFenceMapper">
<resultMap type="HwElectronicFence" id="HwElectronicFenceResult">
<result property="electronicFenceId" column="electronic_fence_id" />
<result property="electronicFenceName" column="electronic_fence_name" />
<result property="sceneId" column="scene_id" />
<result property="fenceType" column="fence_type" />
<result property="effectiveTimeFlag" column="effective_time_flag" />
<result property="effectiveTime" column="effective_time" />
<result property="triggerStatus" column="trigger_status" />
<result property="areaShapeFlag" column="area_shape_flag" />
<result property="areaRange" column="area_range" />
<result property="fencePushFlag" column="fence_push_flag" />
<result property="fencePushContent" column="fence_push_content" />
<result property="fenceRecoverContent" column="fence_recover_content" />
</resultMap>
<sql id="selectElectronicFenceVo">
select electronic_fence_id, electronic_fence_name, scene_id, fence_type, effective_time_flag, effective_time, trigger_status, area_shape_flag,
area_range, fence_push_flag, fence_push_content, fence_recover_content
from hw_electronic_fence hef
</sql>
<select id="selectSuitableElectronicFenceList" resultMap="HwElectronicFenceResult">
<include refid="selectElectronicFenceVo"/>
where (exists (select 1 from hw_fence_target hft where
hft.electronic_fence_id = hef.electronic_fence_id
and ((hft.target_id=#{deviceId} and hft.target_type=1) or (hft.target_id=#{monitorUnitId} and hft.target_type=2))))
or (fence_type=3 and scene_id = #{sceneId}) and hef.trigger_status!=0
</select>
<select id="selectElectronicFencesByDeviceId" resultMap="HwElectronicFenceResult">
<include refid="selectElectronicFenceVo"/>
where exists (select 1 from hw_fence_target hft where
hft.electronic_fence_id = hef.electronic_fence_id
and hft.target_id=#{deviceId} and hft.target_type=1)
and hef.fence_type=1 and hef.trigger_status!=0
</select>
<select id="selectElectronicFencesByMonitorUnitId" resultMap="HwElectronicFenceResult">
<include refid="selectElectronicFenceVo"/>
where exists (select 1 from hw_fence_target hft where
hft.electronic_fence_id = hef.electronic_fence_id
and hft.target_id=#{deviceId} and hft.target_type=2)
and hef.fence_type=2 and hef.trigger_status!=0
</select>
<select id="selectElectronicFencesBySceneId" resultMap="HwElectronicFenceResult">
<include refid="selectElectronicFenceVo"/>
where scene_id=#{sceneId} and hef.fence_type=3 and hef.trigger_status!=0
</select>
</mapper>

@ -4,6 +4,7 @@ import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.hw.validated.tdengine.AddTdSTableColumn;
import com.ruoyi.common.core.hw.validated.tdengine.InsertTdTable;
import com.ruoyi.tdengine.api.domain.*;
import com.ruoyi.tdengine.service.IDeviceStatusService;
import com.ruoyi.tdengine.service.ITdEngineService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -17,6 +18,7 @@ import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @ClassDescription: TdEngine Controller
@ -32,6 +34,9 @@ public class TdEngineController {
@Autowired
private ITdEngineService tdEngineService;
@Autowired
private IDeviceStatusService deviceStatusService;
private static final Logger log = LoggerFactory.getLogger(TdEngineController.class);
/* @description
@ -257,7 +262,6 @@ public class TdEngineController {
}
}
/**
* @return R<?>
* @param: tdSelectDto
@ -368,4 +372,37 @@ public class TdEngineController {
}
}
/**
* @return R<?>
* @param: tdSelectDto
* @description 线
* @author xins
* @date 2023-08-29 11:26
*/
@PostMapping("/getOnlineDevicesGroupByDay")
public R<?> getOnlineDevicesGroupByDay(@RequestBody DeviceStatus queryDeviceStatus) {
try {
List<DeviceStatus> deviceStatuses = this.deviceStatusService.getOnlineDevicesGroupByDay(queryDeviceStatus);
Map<Long, List<DeviceStatus>> deviceStatusMap = deviceStatuses.stream()
.collect(Collectors.groupingBy(DeviceStatus::getTs));
deviceStatusMap.forEach((k,v)->{
System.out.println(k+"----"+v);
});
return R.ok(deviceStatusMap);
} catch (UncategorizedSQLException e) {
String message = e.getCause().getMessage();
try {
message = message.substring(message.lastIndexOf("invalid operation"));
} catch (Exception ex) {
}
log.error(message);
return R.fail(message);
} catch (Exception e) {
log.error(e.getMessage());
return R.fail(e.getMessage());
}
}
}

@ -0,0 +1,24 @@
package com.ruoyi.tdengine.mapper;
import com.ruoyi.tdengine.api.domain.DeviceStatus;
import java.util.List;
/**
* @Description:TDengine
* @ClassName: DeviceStatusMapper
* @Author : xins
* @Date :2023-09-05 13:20
* @Version :1.0
*/
public interface DeviceStatusMapper {
/**
* @param: deviceStatus
* @description 线
* @author xins
* @date 2023-09-05 11:43
* @return List<DeviceStatus>
*/
List<DeviceStatus> getOnlineDevicesGroupByDay(DeviceStatus deviceStatus);
}

@ -7,7 +7,7 @@ import java.util.List;
import java.util.Map;
/**
* @ClassDescription:
* @ClassDescription:TDengine
* @ClassName: TdEngineMapper
* @Author: thinglinks
* @Date: 2021-12-27 14:52:34

@ -0,0 +1,17 @@
package com.ruoyi.tdengine.service;
import com.ruoyi.tdengine.api.domain.DeviceStatus;
import java.util.List;
public interface IDeviceStatusService {
/**
* @param: DeviceStatus
* @description 线
* @author xins
* @date 2023-09-05 13:23
* @return List<DeviceStatus>
*/
public List<DeviceStatus> getOnlineDevicesGroupByDay(DeviceStatus queryDeviceStatus);
}

@ -0,0 +1,52 @@
package com.ruoyi.tdengine.service.impl;
import com.ruoyi.common.core.constant.TdEngineConstants;
import com.ruoyi.tdengine.api.domain.DeviceStatus;
import com.ruoyi.tdengine.mapper.DeviceStatusMapper;
import com.ruoyi.tdengine.service.IDeviceStatusService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Description:
* @ClassName: DeviceStatusServiceImpl
* @Author : xins
* @Date :2023-09-05 13:27
* @Version :1.0
*/
@Service
public class DeviceStatusServiceImpl implements IDeviceStatusService {
@Autowired
private DeviceStatusMapper deviceStatusMapper;
/**
* @param: DeviceStatus
* @description 线
* @author xins
* @date 2023-09-05 13:23
* @return List<DeviceStatus>
*/
@Override
public List<DeviceStatus> getOnlineDevicesGroupByDay(DeviceStatus queryDeviceStatus) {
// Map<String, Object> params = new HashMap<>();
// DeviceStatus queryDeviceStatus = new DeviceStatus();
// String databaseName = TdEngineConstants.getDatabaseName(sceneId);
// String superTableName = TdEngineConstants.getDeviceStatusSuperTableName(sceneId);
// params.put("databaseName", databaseName);
// params.put("superTableName", superTableName);
// params.put("beginTime", beginTime);
// params.put("endTime", endTime);
// queryDeviceStatus.setParams(params);
// if (sceneId != null) {
// queryDeviceStatus.setSceneId(sceneId);
// }
List<DeviceStatus> deviceStatuses = deviceStatusMapper.getOnlineDevicesGroupByDay(queryDeviceStatus);
return deviceStatuses;
}
}

@ -1,10 +1,8 @@
package com.ruoyi.tdengine.service.impl;
import com.ruoyi.common.core.constant.TdEngineConstants;
import com.ruoyi.tdengine.api.domain.TdField;
import com.ruoyi.tdengine.api.domain.TdFieldVo;
import com.ruoyi.tdengine.api.domain.TdHistorySelectDto;
import com.ruoyi.tdengine.api.domain.TdSelectDto;
import com.ruoyi.tdengine.api.domain.*;
import com.ruoyi.tdengine.mapper.DeviceStatusMapper;
import com.ruoyi.tdengine.mapper.TdEngineMapper;
import com.ruoyi.tdengine.service.ITdEngineService;
import org.apache.commons.lang3.StringUtils;
@ -32,6 +30,7 @@ public class TdEngineServiceImpl implements ITdEngineService {
@Autowired
private TdEngineMapper tdEngineMapper;
// @Autowired
// private RedisService redisService;
@ -114,8 +113,8 @@ public class TdEngineServiceImpl implements ITdEngineService {
* @date 2023-08-30 11:03
*/
@Override
public void alterTableTag(String databaseName,String tableName,String tagName,Object tagValue){
this.tdEngineMapper.alterTableTag(databaseName,tableName,tagName,tagValue);
public void alterTableTag(String databaseName, String tableName, String tagName, Object tagValue) {
this.tdEngineMapper.alterTableTag(databaseName, tableName, tagName, tagValue);
}
/**
@ -208,11 +207,11 @@ public class TdEngineServiceImpl implements ITdEngineService {
/**
* @return Long
* @param: tdHistorySelectDto
* @description
* @author xins
* @date 2023-08-29 16:54
* @return Long
*/
@Override
public Long getCountOfHistoryData(TdHistorySelectDto tdHistorySelectDto) throws Exception {
@ -223,9 +222,6 @@ public class TdEngineServiceImpl implements ITdEngineService {
return countMap.get("dataCount");
}
//
// /**
// * 检查数据库表是否存在

@ -0,0 +1,18 @@
<?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.ruoyi.tdengine.mapper.DeviceStatusMapper">
<select id="getOnlineDevicesGroupByDay" parameterType="com.ruoyi.tdengine.api.domain.DeviceStatus" resultType="com.ruoyi.tdengine.api.domain.DeviceStatus" >
select timetruncate(ts,1d) ts,devicetype,onlinestatus,devicecode from #{params.databaseName}.#{params.superTableName}
where onlinestatus=1
<if test="{params.beginTime}!= null and {params.endTime} != null">
and ts BETWEEN #{params.beginTime} AND #{params.endTime}
</if>
<if test="sceneId != null "> and scene_id = #{sceneId}</if>
group by timetruncate(ts,1d),devicetype,onlinestatus,devicecode
order by ts
</select>
</mapper>

@ -260,6 +260,17 @@
</select>
<select id="getOnlineDevicesByDay" parameterType="com.ruoyi.tdengine.api.domain.DeviceStatus" resultType="com.ruoyi.tdengine.api.domain.DeviceStatus" >
select timetruncate(ts,1d) ts,devicetype,onlinestatus,devicecode from #{params.databaseName}.#{params.superTableName}
where onlinestatus=1
<if test="{params.beginTime}!= null and {params.endTime} != null">
and ts BETWEEN #{params.beginTime} AND #{params.endTime}
</if>
<if test="sceneId != null "> and scene_id = #{sceneId}</if>
group by timetruncate(ts,1d),devicetype,onlinestatus,devicecode
order by ts
</select>

@ -27,6 +27,7 @@
<module>hw-business</module>
<module>hw-basic</module>
<module>hw-tdengine</module>
<module>hw-data-process</module>
</modules>
<artifactId>ruoyi-modules</artifactId>

Loading…
Cancel
Save