diff --git a/pom.xml b/pom.xml
index a5d18f9..0901ec0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -213,6 +213,13 @@
${ruoyi.version}
+
+
+ com.ruoyi
+ hw-api-tdengine
+ ${ruoyi.version}
+
+
diff --git a/ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/domain/DeviceStatus.java b/ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/domain/DeviceStatus.java
new file mode 100644
index 0000000..08f3edb
--- /dev/null
+++ b/ruoyi-api/hw-api-tdengine/src/main/java/com/ruoyi/tdengine/api/domain/DeviceStatus.java
@@ -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;
+ }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/HwDictConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/HwDictConstants.java
index 00417ac..cc2f169 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/HwDictConstants.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/HwDictConstants.java
@@ -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";//电子围栏
+
}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/TdEngineConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/TdEngineConstants.java
index e5c87b8..17e136d 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/TdEngineConstants.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/TdEngineConstants.java
@@ -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 TDENGINE_KEY_TRANSFER_MAP = new HashMap();
+
+ 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";
}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/ResultEnums.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/ResultEnums.java
new file mode 100644
index 0000000..2c0b4c1
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/ResultEnums.java
@@ -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;
+ }
+}
diff --git a/ruoyi-modules/hw-data-process/pom.xml b/ruoyi-modules/hw-data-process/pom.xml
new file mode 100644
index 0000000..d2f099a
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/pom.xml
@@ -0,0 +1,120 @@
+
+
+
+ com.ruoyi
+ ruoyi-modules
+ 3.6.3
+
+ 4.0.0
+
+ ruoyi-modules-dataprocess
+
+
+ ruoyi-modules-dataprocess数据处理模块
+
+
+
+
+
+
+ com.alibaba.cloud
+ spring-cloud-starter-alibaba-nacos-discovery
+
+
+
+
+ com.alibaba.cloud
+ spring-cloud-starter-alibaba-nacos-config
+
+
+
+
+ com.alibaba.cloud
+ spring-cloud-starter-alibaba-sentinel
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+
+
+ io.springfox
+ springfox-swagger-ui
+ ${swagger.fox.version}
+
+
+
+
+ com.mysql
+ mysql-connector-j
+
+
+
+
+ com.ruoyi
+ ruoyi-common-datasource
+
+
+
+
+ com.ruoyi
+ ruoyi-common-datascope
+
+
+
+
+ com.ruoyi
+ ruoyi-common-log
+
+
+
+
+ com.ruoyi
+ ruoyi-common-swagger
+
+
+
+
+ net.dreamlu
+ mica-mqtt-client-spring-boot-starter
+ 2.1.0
+
+
+
+
+ com.ruoyi
+ hw-api-tdengine
+
+
+
+ org.locationtech.jts
+ jts-core
+ 1.19.0
+
+
+
+
+
+
+ ${project.artifactId}
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ repackage
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/HwDataProcessApplication.java b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/HwDataProcessApplication.java
new file mode 100644
index 0000000..3e10315
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/HwDataProcessApplication.java
@@ -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" +
+ " ''-' `'-' `-..-' ");
+ }
+}
diff --git a/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/amap/LocationVo.java b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/amap/LocationVo.java
new file mode 100644
index 0000000..728eb6d
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/amap/LocationVo.java
@@ -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;
+
+ /**
+ * 标记类型:1圆,2多边形
+ */
+// @ApiModelProperty(value = "标记类型:1圆,2多边形")
+ private int markerType;
+
+ /**
+ * 多边形区域
+ */
+ private List> polygonList;
+}
+
+
diff --git a/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/amap/PositionUtils.java b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/amap/PositionUtils.java
new file mode 100644
index 0000000..fa634c4
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/amap/PositionUtils.java
@@ -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> coordinates = locationVo.getPolygonList();
+ if (coordinates == null || coordinates.isEmpty()) {
+ return false;
+ }
+ //可以传好几个多边形
+ for (List 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> polygonList = new ArrayList<>();
+ List 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);
+
+ }
+}
diff --git a/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/amap/PositionVo.java b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/amap/PositionVo.java
new file mode 100644
index 0000000..1af05fb
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/amap/PositionVo.java
@@ -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;
+ }
+}
diff --git a/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/common/ImageUtils.java b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/common/ImageUtils.java
new file mode 100644
index 0000000..457f2b7
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/common/ImageUtils.java
@@ -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字符串翻译成图片
+
+
+ }
+
+}
diff --git a/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/common/SpringBeanUtils.java b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/common/SpringBeanUtils.java
new file mode 100644
index 0000000..2893d94
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/common/SpringBeanUtils.java
@@ -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;
+ }
+
+ /**
+ * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
+ */
+ @SuppressWarnings("unchecked")
+ public static T getBean(String name) {
+// log.debug("从SpringContextHolder中取出Bean:" + name);
+ assertContextInjected();
+ return (T) applicationContext.getBean(name);
+ }
+
+ /**
+ * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
+ */
+ public static T getBean(Class requiredType) {
+ assertContextInjected();
+ return applicationContext.getBean(requiredType);
+ }
+
+ /**
+ * 清除SpringContextHolder中的ApplicationContext为Null.
+ */
+ 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.");
+ }
+ }
+}
\ No newline at end of file
diff --git a/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/config/RedisMessageListenerConfig.java b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/config/RedisMessageListenerConfig.java
new file mode 100644
index 0000000..067e31a
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/config/RedisMessageListenerConfig.java
@@ -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 topicList = Arrays.asList(new PatternTopic("life.*"),new PatternTopic("*.life"));
+ container.addMessageListener(redisMessageListener, topicList);
+
+ return container;
+ }
+
+}
+
diff --git a/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/domain/HwAlarmInfo.java b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/domain/HwAlarmInfo.java
new file mode 100644
index 0000000..b666f6e
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/domain/HwAlarmInfo.java
@@ -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;
+
+ /** 报警信息类型是1关联表alarm_rule的字段alarm_rule_id;
+ 报警信息类型是3关联表hw_offline_rule的字段offline_rule_id;
+ 报警信息类型是4关联表hw_electronic_fence的字段electronic_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();
+ }
+}
diff --git a/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/domain/HwDevice.java b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/domain/HwDevice.java
new file mode 100644
index 0000000..46d25c5
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/domain/HwDevice.java
@@ -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-Fi,2、蜂窝(2G/3G/4G/5G),3、以太网,4、其他) */
+ @Excel(name = "联网方式(1:Wi-Fi,2、蜂窝(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;
+
+ /** 接入网关协议(1、Modbus)
+ 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();
+ }
+}
diff --git a/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/domain/HwElectronicFence.java b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/domain/HwElectronicFence.java
new file mode 100644
index 0000000..13ead56
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/domain/HwElectronicFence.java
@@ -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();
+ }
+}
diff --git a/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/listener/RedisMessageListener.java b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/listener/RedisMessageListener.java
new file mode 100644
index 0000000..d31516a
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/listener/RedisMessageListener.java
@@ -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("---------------------------------");
+ }
+}
diff --git a/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/mapper/HwAlarmInfoMapper.java b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/mapper/HwAlarmInfoMapper.java
new file mode 100644
index 0000000..9c8c387
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/mapper/HwAlarmInfoMapper.java
@@ -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);
+
+}
diff --git a/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/mapper/HwDeviceMapper.java b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/mapper/HwDeviceMapper.java
new file mode 100644
index 0000000..6f60e55
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/mapper/HwDeviceMapper.java
@@ -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);
+
+
+}
diff --git a/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/mapper/HwElectronicFenceMapper.java b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/mapper/HwElectronicFenceMapper.java
new file mode 100644
index 0000000..0375416
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/mapper/HwElectronicFenceMapper.java
@@ -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 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
+ */
+ public List selectElectronicFencesByDeviceId(Long deviceId);
+
+ /**
+ * @param: monitorUnitId
+ * @description 根据监控单元ID获取电子围栏配置
+ * @author xins
+ * @date 2023-09-03 12:11
+ * @return List
+ */
+ public List selectElectronicFencesByMonitorUnitId(Long monitorUnitId);
+
+ /**
+ * @param: sceneId
+ * @description 根据场景Id获取电子围栏配置
+ * @author xins
+ * @date 2023-09-03 12:11
+ * @return List
+ */
+ public List selectElectronicFencesBySceneId(Long sceneId);
+
+
+}
diff --git a/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/mqtt/client/config/MqttConfiguration.java b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/mqtt/client/config/MqttConfiguration.java
new file mode 100644
index 0000000..7f9b9ce
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/mqtt/client/config/MqttConfiguration.java
@@ -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;
+ }
+}
diff --git a/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/mqtt/client/controller/ClientController.java b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/mqtt/client/controller/ClientController.java
new file mode 100644
index 0000000..bcc85f2
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/mqtt/client/controller/ClientController.java
@@ -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();
+// }
+//
+//}
diff --git a/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/mqtt/client/listener/MqttClientConnectListener.java b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/mqtt/client/listener/MqttClientConnectListener.java
new file mode 100644
index 0000000..ba274d6
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/mqtt/client/listener/MqttClientConnectListener.java
@@ -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);
+ }
+
+}
diff --git a/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/mqtt/client/listener/MqttClientMessageListener.java b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/mqtt/client/listener/MqttClientMessageListener.java
new file mode 100644
index 0000000..fd8f22c
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/mqtt/client/listener/MqttClientMessageListener.java
@@ -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);
+// }
+//
+//
+//}
+//
diff --git a/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/mqtt/client/service/ClientService.java b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/mqtt/client/service/ClientService.java
new file mode 100644
index 0000000..480a783
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/mqtt/client/service/ClientService.java
@@ -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;
+// }
+//
+//}
diff --git a/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/service/IDataProcessService.java b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/service/IDataProcessService.java
new file mode 100644
index 0000000..18fe45e
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/service/IDataProcessService.java
@@ -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);
+
+}
diff --git a/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/service/IDeviceStatusService.java b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/service/IDeviceStatusService.java
new file mode 100644
index 0000000..99f5a34
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/service/IDeviceStatusService.java
@@ -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();
+}
diff --git a/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/service/impl/DataProcessServiceImpl.java b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/service/impl/DataProcessServiceImpl.java
new file mode 100644
index 0000000..759ebec
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/service/impl/DataProcessServiceImpl.java
@@ -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 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 entry : dataValueJson.entrySet()) {
+ String key = entry.getKey();
+ Object value = entry.getValue();
+
+ /**
+ * 先对key进行转换,例如对于key是value的需要转换成value1;
+ */
+ 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 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> polygonList = new ArrayList<>();
+ List 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);
+
+ /**
+ * 传入的longitude和latitude是object类型,本身有可能是BigDecimal,Double,Long和Integer,先转成String再转成Double
+ */
+ 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" +
+ " }]}";
+
+ }
+}
diff --git a/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/service/impl/DeviceStatusServiceImpl.java b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/service/impl/DeviceStatusServiceImpl.java
new file mode 100644
index 0000000..c90474f
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/src/main/java/com/ruoyi/dataprocess/service/impl/DeviceStatusServiceImpl.java
@@ -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");
+ }
+}
diff --git a/ruoyi-modules/hw-data-process/src/main/resources/ClientService.java b/ruoyi-modules/hw-data-process/src/main/resources/ClientService.java
new file mode 100644
index 0000000..ba43d31
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/src/main/resources/ClientService.java
@@ -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;
+ }
+
+}
diff --git a/ruoyi-modules/hw-data-process/src/main/resources/MqttClientConnectListener.java b/ruoyi-modules/hw-data-process/src/main/resources/MqttClientConnectListener.java
new file mode 100644
index 0000000..e4f1ecc
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/src/main/resources/MqttClientConnectListener.java
@@ -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");
+ }
+
+}
diff --git a/ruoyi-modules/hw-data-process/src/main/resources/banner.txt b/ruoyi-modules/hw-data-process/src/main/resources/banner.txt
new file mode 100644
index 0000000..fbd45f5
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/src/main/resources/banner.txt
@@ -0,0 +1,10 @@
+Spring Boot Version: ${spring-boot.version}
+Spring Application Name: ${spring.application.name}
+ _ _
+ (_) | |
+ _ __ _ _ ___ _ _ _ ______ ___ _ _ ___ | |_ ___ _ __ ___
+| '__|| | | | / _ \ | | | || ||______|/ __|| | | |/ __|| __| / _ \| '_ ` _ \
+| | | |_| || (_) || |_| || | \__ \| |_| |\__ \| |_ | __/| | | | | |
+|_| \__,_| \___/ \__, ||_| |___/ \__, ||___/ \__| \___||_| |_| |_|
+ __/ | __/ |
+ |___/ |___/
\ No newline at end of file
diff --git a/ruoyi-modules/hw-data-process/src/main/resources/bootstrap.yml b/ruoyi-modules/hw-data-process/src/main/resources/bootstrap.yml
new file mode 100644
index 0000000..856d7d0
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/src/main/resources/bootstrap.yml
@@ -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}
diff --git a/ruoyi-modules/hw-data-process/src/main/resources/logback.xml b/ruoyi-modules/hw-data-process/src/main/resources/logback.xml
new file mode 100644
index 0000000..4554898
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/src/main/resources/logback.xml
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+
+
+ ${log.pattern}
+
+
+
+
+
+ ${log.path}/info.log
+
+
+
+ ${log.path}/info.%d{yyyy-MM-dd}.log
+
+ 60
+
+
+ ${log.pattern}
+
+
+
+ INFO
+
+ ACCEPT
+
+ DENY
+
+
+
+
+ ${log.path}/error.log
+
+
+
+ ${log.path}/error.%d{yyyy-MM-dd}.log
+
+ 60
+
+
+ ${log.pattern}
+
+
+
+ ERROR
+
+ ACCEPT
+
+ DENY
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ruoyi-modules/hw-data-process/src/main/resources/mapper/dataprocess/HwAlarmInfoMapper.xml b/ruoyi-modules/hw-data-process/src/main/resources/mapper/dataprocess/HwAlarmInfoMapper.xml
new file mode 100644
index 0000000..15aa31f
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/src/main/resources/mapper/dataprocess/HwAlarmInfoMapper.xml
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ insert into hw_alarm_info
+
+ alarm_info_type,
+ alarm_releated_id,
+ device_id,
+ monitor_unit_id,
+ scene_id,
+ alarm_level_id,
+ alarm_type_id,
+ mode_function_id,
+ function_name,
+ function_identifier,
+ function_value,
+ trigger_status,
+ handle_status,
+ alarm_time,
+ create_time,
+ update_by,
+ update_time,
+ alarm_info_field,
+
+
+ #{alarmInfoType},
+ #{alarmReleatedId},
+ #{deviceId},
+ #{monitorUnitId},
+ #{sceneId},
+ #{alarmLevelId},
+ #{alarmTypeId},
+ #{modeFunctionId},
+ #{functionName},
+ #{functionIdentifier},
+ #{functionValue},
+ #{triggerStatus},
+ #{handleStatus},
+ #{alarmTime},
+ #{createTime},
+ #{updateBy},
+ #{updateTime},
+ #{alarmInfoField},
+
+
+
+
+
\ No newline at end of file
diff --git a/ruoyi-modules/hw-data-process/src/main/resources/mapper/dataprocess/HwDeviceMapper.xml b/ruoyi-modules/hw-data-process/src/main/resources/mapper/dataprocess/HwDeviceMapper.xml
new file mode 100644
index 0000000..d192fcf
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/src/main/resources/mapper/dataprocess/HwDeviceMapper.xml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ select device_id, device_code, scene_id, monitor_unit_id, device_type, device_mode_id, device_status from hw_device
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ruoyi-modules/hw-data-process/src/main/resources/mapper/dataprocess/HwElectronicFenceMapper.xml b/ruoyi-modules/hw-data-process/src/main/resources/mapper/dataprocess/HwElectronicFenceMapper.xml
new file mode 100644
index 0000000..01f3d5a
--- /dev/null
+++ b/ruoyi-modules/hw-data-process/src/main/resources/mapper/dataprocess/HwElectronicFenceMapper.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/controller/TdEngineController.java b/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/controller/TdEngineController.java
index b16b57a..f6069c7 100644
--- a/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/controller/TdEngineController.java
+++ b/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/controller/TdEngineController.java
@@ -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 deviceStatuses = this.deviceStatusService.getOnlineDevicesGroupByDay(queryDeviceStatus);
+ Map> 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());
+ }
+ }
+
}
diff --git a/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/mapper/DeviceStatusMapper.java b/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/mapper/DeviceStatusMapper.java
new file mode 100644
index 0000000..c306225
--- /dev/null
+++ b/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/mapper/DeviceStatusMapper.java
@@ -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
+ */
+ List getOnlineDevicesGroupByDay(DeviceStatus deviceStatus);
+}
diff --git a/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/mapper/TdEngineMapper.java b/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/mapper/TdEngineMapper.java
index 05b0a11..98e0e4d 100644
--- a/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/mapper/TdEngineMapper.java
+++ b/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/mapper/TdEngineMapper.java
@@ -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
diff --git a/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/service/IDeviceStatusService.java b/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/service/IDeviceStatusService.java
new file mode 100644
index 0000000..b039129
--- /dev/null
+++ b/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/service/IDeviceStatusService.java
@@ -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
+ */
+ public List getOnlineDevicesGroupByDay(DeviceStatus queryDeviceStatus);
+}
diff --git a/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/service/impl/DeviceStatusServiceImpl.java b/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/service/impl/DeviceStatusServiceImpl.java
new file mode 100644
index 0000000..7538eaf
--- /dev/null
+++ b/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/service/impl/DeviceStatusServiceImpl.java
@@ -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
+ */
+ @Override
+ public List getOnlineDevicesGroupByDay(DeviceStatus queryDeviceStatus) {
+// Map 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 deviceStatuses = deviceStatusMapper.getOnlineDevicesGroupByDay(queryDeviceStatus);
+
+ return deviceStatuses;
+ }
+}
diff --git a/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/service/impl/TdEngineServiceImpl.java b/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/service/impl/TdEngineServiceImpl.java
index 8f0875c..8571556 100644
--- a/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/service/impl/TdEngineServiceImpl.java
+++ b/ruoyi-modules/hw-tdengine/src/main/java/com/ruoyi/tdengine/service/impl/TdEngineServiceImpl.java
@@ -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");
}
-
-
-
//
// /**
// * 检查数据库表是否存在
diff --git a/ruoyi-modules/hw-tdengine/src/main/resources/mapper/tdengine/DeviceStatusMapper.xml b/ruoyi-modules/hw-tdengine/src/main/resources/mapper/tdengine/DeviceStatusMapper.xml
new file mode 100644
index 0000000..6698952
--- /dev/null
+++ b/ruoyi-modules/hw-tdengine/src/main/resources/mapper/tdengine/DeviceStatusMapper.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
diff --git a/ruoyi-modules/hw-tdengine/src/main/resources/mapper/tdengine/TdEngineMapper.xml b/ruoyi-modules/hw-tdengine/src/main/resources/mapper/tdengine/TdEngineMapper.xml
index 7aedf0e..c4132ab 100644
--- a/ruoyi-modules/hw-tdengine/src/main/resources/mapper/tdengine/TdEngineMapper.xml
+++ b/ruoyi-modules/hw-tdengine/src/main/resources/mapper/tdengine/TdEngineMapper.xml
@@ -260,6 +260,17 @@
+
+
diff --git a/ruoyi-modules/pom.xml b/ruoyi-modules/pom.xml
index b5a5a35..2207434 100644
--- a/ruoyi-modules/pom.xml
+++ b/ruoyi-modules/pom.xml
@@ -27,6 +27,7 @@
hw-business
hw-basic
hw-tdengine
+ hw-data-process
ruoyi-modules