Commit 0faee76ffd9013235427c5e998ba25d0a508a36f

Authored by YunaiV
1 parent 456423b5

reactor:【IoT 物联网】清理 yudao-module-iot-api

Showing 45 changed files with 123 additions and 248 deletions
yudao-module-iot/pom.xml
@@ -7,7 +7,6 @@ @@ -7,7 +7,6 @@
7 <version>${revision}</version> 7 <version>${revision}</version>
8 </parent> 8 </parent>
9 <modules> 9 <modules>
10 - <module>yudao-module-iot-api</module>  
11 <module>yudao-module-iot-biz</module> 10 <module>yudao-module-iot-biz</module>
12 <module>yudao-module-iot-core</module> 11 <module>yudao-module-iot-core</module>
13 <module>yudao-module-iot-gateway</module> 12 <module>yudao-module-iot-gateway</module>
yudao-module-iot/yudao-module-iot-api/pom.xml deleted
1 -<?xml version="1.0" encoding="UTF-8"?>  
2 -<project xmlns="http://maven.apache.org/POM/4.0.0"  
3 - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
4 - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
5 - <parent>  
6 - <artifactId>yudao-module-iot</artifactId>  
7 - <groupId>cn.iocoder.boot</groupId>  
8 - <version>${revision}</version>  
9 - </parent>  
10 - <modelVersion>4.0.0</modelVersion>  
11 - <artifactId>yudao-module-iot-api</artifactId>  
12 - <packaging>jar</packaging>  
13 -  
14 - <name>${project.artifactId}</name>  
15 - <!-- TODO 芋艿:需要在整理下,特别是 PF4J -->  
16 - <description>  
17 - 物联网 模块 API,暴露给其它模块调用  
18 - </description>  
19 -  
20 - <dependencies>  
21 - <dependency>  
22 - <groupId>cn.iocoder.boot</groupId>  
23 - <artifactId>yudao-common</artifactId>  
24 - </dependency>  
25 -  
26 - <!-- Web 相关 -->  
27 - <dependency>  
28 - <groupId>org.springframework</groupId>  
29 - <artifactId>spring-web</artifactId>  
30 - <scope>provided</scope> <!-- 设置为 provided,只有工具类需要使用到 -->  
31 - </dependency>  
32 -  
33 - <!-- 工具类相关 -->  
34 - <dependency>  
35 - <groupId>com.fasterxml.jackson.core</groupId>  
36 - <artifactId>jackson-databind</artifactId>  
37 - <scope>provided</scope> <!-- 设置为 provided,只有工具类需要使用到 -->  
38 - </dependency>  
39 -  
40 - <!-- <dependency>-->  
41 - <!-- <groupId>org.pf4j</groupId> &lt;!&ndash; PF4J:内置插件机制 &ndash;&gt;-->  
42 - <!-- <artifactId>pf4j-spring</artifactId>-->  
43 - <!-- </dependency>-->  
44 -  
45 - <!-- 参数校验 -->  
46 - <dependency>  
47 - <groupId>org.springframework.boot</groupId>  
48 - <artifactId>spring-boot-starter-validation</artifactId>  
49 - <optional>true</optional>  
50 - </dependency>  
51 - </dependencies>  
52 -  
53 -</project>  
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/api/device/dto/control/upstream/IotDeviceEventReportReqDTO.java deleted
1 -package cn.iocoder.yudao.module.iot.api.device.dto.control.upstream;  
2 -  
3 -import jakarta.validation.constraints.NotEmpty;  
4 -import lombok.Data;  
5 -  
6 -import java.util.Map;  
7 -  
8 -/**  
9 - * IoT 设备【事件】上报 Request DTO  
10 - *  
11 - * @author 芋道源码  
12 - */  
13 -@Data  
14 -public class IotDeviceEventReportReqDTO extends IotDeviceUpstreamAbstractReqDTO {  
15 -  
16 - /**  
17 - * 事件标识  
18 - */  
19 - @NotEmpty(message = "事件标识不能为空")  
20 - private String identifier;  
21 - /**  
22 - * 事件参数  
23 - */  
24 - private Map<String, Object> params;  
25 -  
26 -}  
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/api/device/dto/control/upstream/IotDevicePropertyReportReqDTO.java deleted
1 -package cn.iocoder.yudao.module.iot.api.device.dto.control.upstream;  
2 -  
3 -import jakarta.validation.constraints.NotEmpty;  
4 -import lombok.Data;  
5 -  
6 -import java.util.Map;  
7 -  
8 -/**  
9 - * IoT 设备【属性】上报 Request DTO  
10 - *  
11 - * @author 芋道源码  
12 - */  
13 -@Data  
14 -public class IotDevicePropertyReportReqDTO extends IotDeviceUpstreamAbstractReqDTO {  
15 -  
16 - /**  
17 - * 属性参数  
18 - */  
19 - @NotEmpty(message = "属性参数不能为空")  
20 - private Map<String, Object> properties;  
21 -  
22 -}  
23 \ No newline at end of file 0 \ No newline at end of file
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/api/device/dto/control/upstream/IotDeviceUpstreamAbstractReqDTO.java deleted
1 -package cn.iocoder.yudao.module.iot.api.device.dto.control.upstream;  
2 -  
3 -import cn.iocoder.yudao.framework.common.util.json.databind.TimestampLocalDateTimeSerializer;  
4 -import com.fasterxml.jackson.databind.annotation.JsonSerialize;  
5 -import jakarta.validation.constraints.NotEmpty;  
6 -import lombok.Data;  
7 -  
8 -import java.time.LocalDateTime;  
9 -  
10 -/**  
11 - * IoT 设备上行的抽象 Request DTO  
12 - *  
13 - * @author 芋道源码  
14 - */  
15 -@Data  
16 -public abstract class IotDeviceUpstreamAbstractReqDTO {  
17 -  
18 - /**  
19 - * 请求编号  
20 - */  
21 - private String requestId;  
22 -  
23 - /**  
24 - * 插件实例的进程编号  
25 - */  
26 - private String processId;  
27 -  
28 - /**  
29 - * 产品标识  
30 - */  
31 - @NotEmpty(message = "产品标识不能为空")  
32 - private String productKey;  
33 - /**  
34 - * 设备名称  
35 - */  
36 - @NotEmpty(message = "设备名称不能为空")  
37 - private String deviceName;  
38 -  
39 - /**  
40 - * 上报时间  
41 - */  
42 - @JsonSerialize(using = TimestampLocalDateTimeSerializer.class) // 解决 iot plugins 序列化 LocalDateTime 是数组,导致无法解析的问题  
43 - private LocalDateTime reportTime;  
44 -  
45 -}  
yudao-module-iot/yudao-module-iot-biz/pom.xml
@@ -25,11 +25,6 @@ @@ -25,11 +25,6 @@
25 </dependency> 25 </dependency>
26 <dependency> 26 <dependency>
27 <groupId>cn.iocoder.boot</groupId> 27 <groupId>cn.iocoder.boot</groupId>
28 - <artifactId>yudao-module-iot-api</artifactId>  
29 - <version>${revision}</version>  
30 - </dependency>  
31 - <dependency>  
32 - <groupId>cn.iocoder.boot</groupId>  
33 <artifactId>yudao-module-iot-core</artifactId> 28 <artifactId>yudao-module-iot-core</artifactId>
34 <version>${revision}</version> 29 <version>${revision}</version>
35 </dependency> 30 </dependency>
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/rule/IotAlertConfigDO.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/alert/IotAlertConfigDO.java
1 -package cn.iocoder.yudao.module.iot.dal.dataobject.rule; 1 +package cn.iocoder.yudao.module.iot.dal.dataobject.alert;
2 2
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 4 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 -import cn.iocoder.yudao.module.iot.enums.rule.IotAlertConfigReceiveTypeEnum; 5 +import cn.iocoder.yudao.framework.mybatis.core.type.IntegerListTypeHandler;
  6 +import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;
  7 +import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO;
  8 +import cn.iocoder.yudao.module.iot.enums.DictTypeConstants;
  9 +import cn.iocoder.yudao.module.iot.enums.alert.IotAlertConfigReceiveTypeEnum;
5 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 10 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
6 import com.baomidou.mybatisplus.annotation.KeySequence; 11 import com.baomidou.mybatisplus.annotation.KeySequence;
7 import com.baomidou.mybatisplus.annotation.TableField; 12 import com.baomidou.mybatisplus.annotation.TableField;
8 import com.baomidou.mybatisplus.annotation.TableId; 13 import com.baomidou.mybatisplus.annotation.TableId;
9 import com.baomidou.mybatisplus.annotation.TableName; 14 import com.baomidou.mybatisplus.annotation.TableName;
10 -import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;  
11 -import lombok.*; 15 +import lombok.AllArgsConstructor;
  16 +import lombok.Builder;
  17 +import lombok.Data;
  18 +import lombok.NoArgsConstructor;
12 19
13 import java.util.List; 20 import java.util.List;
14 21
@@ -41,37 +48,37 @@ public class IotAlertConfigDO extends BaseDO { @@ -41,37 +48,37 @@ public class IotAlertConfigDO extends BaseDO {
41 /** 48 /**
42 * 配置状态 49 * 配置状态
43 * 50 *
44 - * TODO 数据字典 51 + * 字典 {@link DictTypeConstants#ALERT_LEVEL}
45 */ 52 */
46 private Integer level; 53 private Integer level;
47 /** 54 /**
48 * 配置状态 55 * 配置状态
49 * 56 *
50 - * 枚举 {@link cn.iocoder.yudao.framework.common.enums.CommonStatusEnum} 57 + * 枚举 {@link CommonStatusEnum}
51 */ 58 */
52 private Integer status; 59 private Integer status;
53 60
54 /** 61 /**
55 - * 关联的规则场景编号数组 62 + * 关联的场景联动规则编号数组
56 * 63 *
57 * 关联 {@link IotRuleSceneDO#getId()} 64 * 关联 {@link IotRuleSceneDO#getId()}
58 */ 65 */
59 - @TableField(typeHandler = JacksonTypeHandler.class)  
60 - private List<Long> ruleSceneIds; 66 + @TableField(typeHandler = LongListTypeHandler.class)
  67 + private List<Long> sceneRuleIds;
61 68
62 /** 69 /**
63 * 接收的用户编号数组 70 * 接收的用户编号数组
64 * 71 *
65 * 关联 {@link AdminUserRespDTO#getId()} 72 * 关联 {@link AdminUserRespDTO#getId()}
66 */ 73 */
67 - @TableField(typeHandler = JacksonTypeHandler.class) 74 + @TableField(typeHandler = LongListTypeHandler.class)
68 private List<Long> receiveUserIds; 75 private List<Long> receiveUserIds;
69 /** 76 /**
70 * 接收的类型数组 77 * 接收的类型数组
71 * 78 *
72 * 枚举 {@link IotAlertConfigReceiveTypeEnum} 79 * 枚举 {@link IotAlertConfigReceiveTypeEnum}
73 */ 80 */
74 - @TableField(typeHandler = JacksonTypeHandler.class) 81 + @TableField(typeHandler = IntegerListTypeHandler.class)
75 private List<Integer> receiveTypes; 82 private List<Integer> receiveTypes;
76 83
77 } 84 }
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/rule/IotAlertRecordDO.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/alert/IotAlertRecordDO.java
1 -package cn.iocoder.yudao.module.iot.dal.dataobject.rule; 1 +package cn.iocoder.yudao.module.iot.dal.dataobject.alert;
2 2
3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; 4 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
@@ -45,17 +45,17 @@ public class IotAlertRecordDO extends BaseDO { @@ -45,17 +45,17 @@ public class IotAlertRecordDO extends BaseDO {
45 private String name; 45 private String name;
46 46
47 /** 47 /**
48 - * 产品标识 48 + * 产品编号
49 * 49 *
50 - * 关联 {@link IotProductDO#getProductKey()} ()} 50 + * 关联 {@link IotProductDO#getId()}
51 */ 51 */
52 - private String productKey; 52 + private Long productId;
53 /** 53 /**
54 - * 设备名称 54 + * 设备编号
55 * 55 *
56 - * 冗余 {@link IotDeviceDO#getDeviceName()} 56 + * 关联 {@link IotDeviceDO#getId()}
57 */ 57 */
58 - private String deviceName; 58 + private String deviceId;
59 59
60 // TODO @芋艿:有没更好的方式 60 // TODO @芋艿:有没更好的方式
61 /** 61 /**
@@ -64,7 +64,6 @@ public class IotAlertRecordDO extends BaseDO { @@ -64,7 +64,6 @@ public class IotAlertRecordDO extends BaseDO {
64 @TableField(typeHandler = JacksonTypeHandler.class) 64 @TableField(typeHandler = JacksonTypeHandler.class)
65 private IotDeviceMessage deviceMessage; 65 private IotDeviceMessage deviceMessage;
66 66
67 - // TODO @芋艿:换成枚举,枚举对应 ApiErrorLogProcessStatusEnum  
68 /** 67 /**
69 * 处理状态 68 * 处理状态
70 * 69 *
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/rule/IotSceneRuleDO.java
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.iot.dal.dataobject.rule; @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.iot.dal.dataobject.rule;
3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
4 import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; 4 import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
5 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; 5 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
  6 +import cn.iocoder.yudao.module.iot.dal.dataobject.alert.IotAlertConfigDO;
6 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; 7 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
7 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; 8 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
8 import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; 9 import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO;
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/DictTypeConstants.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/DictTypeConstants.java
@@ -14,5 +14,6 @@ public class DictTypeConstants { @@ -14,5 +14,6 @@ public class DictTypeConstants {
14 14
15 public static final String DEVICE_STATE = "iot_device_state"; 15 public static final String DEVICE_STATE = "iot_device_state";
16 16
  17 + public static final String ALERT_LEVEL = "iot_alert_level";
17 18
18 } 19 }
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/rule/IotAlertConfigReceiveTypeEnum.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/alert/IotAlertConfigReceiveTypeEnum.java
1 -package cn.iocoder.yudao.module.iot.enums.rule; 1 +package cn.iocoder.yudao.module.iot.enums.alert;
2 2
3 import cn.iocoder.yudao.framework.common.core.ArrayValuable; 3 import cn.iocoder.yudao.framework.common.core.ArrayValuable;
4 import lombok.Getter; 4 import lombok.Getter;
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/device/IotDeviceMessageIdentifierEnum.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/device/IotDeviceMessageIdentifierEnum.java
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/device/IotDeviceMessageTypeEnum.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/device/IotDeviceMessageTypeEnum.java
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ota/IotOtaUpgradeRecordStatusEnum.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/ota/IotOtaUpgradeRecordStatusEnum.java
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ota/IotOtaUpgradeTaskScopeEnum.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/ota/IotOtaUpgradeTaskScopeEnum.java
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ota/IotOtaUpgradeTaskStatusEnum.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/ota/IotOtaUpgradeTaskStatusEnum.java
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/product/IotNetTypeEnum.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/product/IotNetTypeEnum.java
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/product/IotProductDeviceTypeEnum.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/product/IotProductDeviceTypeEnum.java
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/product/IotProductStatusEnum.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/product/IotProductStatusEnum.java
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/rule/IotDataSinkTypeEnum.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/rule/IotDataSinkTypeEnum.java
@@ -16,14 +16,13 @@ import java.util.Arrays; @@ -16,14 +16,13 @@ import java.util.Arrays;
16 public enum IotDataSinkTypeEnum implements ArrayValuable<Integer> { 16 public enum IotDataSinkTypeEnum implements ArrayValuable<Integer> {
17 17
18 HTTP(1, "HTTP"), 18 HTTP(1, "HTTP"),
19 - TCP(2, "TCP"),  
20 - WEBSOCKET(3, "WebSocket"), 19 + TCP(2, "TCP"), // TODO @puhui999:待实现;
  20 + WEBSOCKET(3, "WebSocket"), // TODO @puhui999:待实现;
21 21
22 - MQTT(10, "MQTT"), 22 + MQTT(10, "MQTT"), // TODO 待实现;
23 23
24 - DATABASE(20, "Database"),  
25 - // TODO @芋艿:改成 Redis;通过 execute 通用化;  
26 - REDIS_STREAM(21, "Redis Stream"), 24 + DATABASE(20, "Database"), // TODO @puhui999:待实现;可以简单点,对应的表名是什么,字段先固定了。
  25 + REDIS_STREAM(21, "Redis Stream"), // TODO @puhui999:改成 Redis;然后枚举不同的数据结构?这样,枚举就可以是 Redis 了
27 26
28 ROCKETMQ(30, "RocketMQ"), 27 ROCKETMQ(30, "RocketMQ"),
29 RABBITMQ(31, "RabbitMQ"), 28 RABBITMQ(31, "RabbitMQ"),
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/rule/IotRuleSceneActionTypeEnum.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/rule/IotRuleSceneActionTypeEnum.java
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/rule/IotRuleSceneConditionOperatorEnum.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/rule/IotRuleSceneConditionOperatorEnum.java
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/rule/IotRuleSceneConditionTypeEnum.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/rule/IotRuleSceneConditionTypeEnum.java
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/rule/IotRuleSceneTriggerTypeEnum.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/rule/IotRuleSceneTriggerTypeEnum.java
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/thingmodel/IotDataSpecsDataTypeEnum.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/thingmodel/IotDataSpecsDataTypeEnum.java
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/thingmodel/IotThingModelAccessModeEnum.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/thingmodel/IotThingModelAccessModeEnum.java
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/thingmodel/IotThingModelParamDirectionEnum.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/thingmodel/IotThingModelParamDirectionEnum.java
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/thingmodel/IotThingModelServiceCallTypeEnum.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/thingmodel/IotThingModelServiceCallTypeEnum.java
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/thingmodel/IotThingModelServiceEventTypeEnum.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/thingmodel/IotThingModelServiceEventTypeEnum.java
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/thingmodel/IotThingModelTypeEnum.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/thingmodel/IotThingModelTypeEnum.java
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/device/IotDeviceMessageSubscriber.java
1 package cn.iocoder.yudao.module.iot.mq.consumer.device; 1 package cn.iocoder.yudao.module.iot.mq.consumer.device;
2 2
3 import cn.hutool.core.util.ObjectUtil; 3 import cn.hutool.core.util.ObjectUtil;
4 -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;  
5 import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; 4 import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
6 import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageMethodEnum; 5 import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageMethodEnum;
7 import cn.iocoder.yudao.module.iot.core.enums.IotDeviceStateEnum; 6 import cn.iocoder.yudao.module.iot.core.enums.IotDeviceStateEnum;
@@ -19,6 +18,7 @@ import lombok.extern.slf4j.Slf4j; @@ -19,6 +18,7 @@ import lombok.extern.slf4j.Slf4j;
19 import org.springframework.stereotype.Component; 18 import org.springframework.stereotype.Component;
20 19
21 import java.time.LocalDateTime; 20 import java.time.LocalDateTime;
  21 +import java.util.Objects;
22 22
23 /** 23 /**
24 * 针对 {@link IotDeviceMessage} 的业务处理器:调用 method 对应的逻辑。例如说: 24 * 针对 {@link IotDeviceMessage} 的业务处理器:调用 method 对应的逻辑。例如说:
@@ -83,15 +83,14 @@ public class IotDeviceMessageSubscriber implements IotMessageSubscriber&lt;IotDevic @@ -83,15 +83,14 @@ public class IotDeviceMessageSubscriber implements IotMessageSubscriber&lt;IotDevic
83 return; 83 return;
84 } 84 }
85 // 如果是 STATE 相关的消息,无需处理,不然就重复处理状态了 85 // 如果是 STATE 相关的消息,无需处理,不然就重复处理状态了
86 - if (ObjectUtils.equalsAny(message.getMethod(), IotDeviceMessageMethodEnum.STATE_ONLINE.getMethod(),  
87 - IotDeviceMessageMethodEnum.STATE_OFFLINE.getMethod())) { 86 + if (Objects.equals(message.getMethod(), IotDeviceMessageMethodEnum.STATE_UPDATE.getMethod())) {
88 return; 87 return;
89 } 88 }
90 89
91 // 特殊:设备非在线时,主动标记设备为在线 90 // 特殊:设备非在线时,主动标记设备为在线
92 // 为什么不直接更新状态呢?因为通过 IotDeviceMessage 可以经过一系列的处理,例如说记录日志、规则引擎等等 91 // 为什么不直接更新状态呢?因为通过 IotDeviceMessage 可以经过一系列的处理,例如说记录日志、规则引擎等等
93 try { 92 try {
94 - deviceMessageService.sendDeviceMessage(IotDeviceMessage.buildStateOnline().setDeviceId(device.getId())); 93 + deviceMessageService.sendDeviceMessage(IotDeviceMessage.buildStateUpdateOnline().setDeviceId(device.getId()));
95 } catch (Exception e) { 94 } catch (Exception e) {
96 // 注意:即使执行失败,也不影响主流程 95 // 注意:即使执行失败,也不影响主流程
97 log.error("[forceDeviceOnline][message({}) device({}) 强制设备上线失败]", message, device, e); 96 log.error("[forceDeviceOnline][message({}) device({}) 强制设备上线失败]", message, device, e);
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/message/IotDeviceMessageServiceImpl.java
1 package cn.iocoder.yudao.module.iot.service.device.message; 1 package cn.iocoder.yudao.module.iot.service.device.message;
2 2
3 import cn.hutool.core.date.LocalDateTimeUtil; 3 import cn.hutool.core.date.LocalDateTimeUtil;
  4 +import cn.hutool.core.lang.Assert;
4 import cn.hutool.core.map.MapUtil; 5 import cn.hutool.core.map.MapUtil;
5 import cn.hutool.core.util.StrUtil; 6 import cn.hutool.core.util.StrUtil;
6 import cn.hutool.extra.spring.SpringUtil; 7 import cn.hutool.extra.spring.SpringUtil;
@@ -13,7 +14,6 @@ import cn.iocoder.yudao.module.iot.controller.admin.device.vo.message.IotDeviceM @@ -13,7 +14,6 @@ import cn.iocoder.yudao.module.iot.controller.admin.device.vo.message.IotDeviceM
13 import cn.iocoder.yudao.module.iot.controller.admin.statistics.vo.IotStatisticsDeviceMessageReqVO; 14 import cn.iocoder.yudao.module.iot.controller.admin.statistics.vo.IotStatisticsDeviceMessageReqVO;
14 import cn.iocoder.yudao.module.iot.controller.admin.statistics.vo.IotStatisticsDeviceMessageSummaryByDateRespVO; 15 import cn.iocoder.yudao.module.iot.controller.admin.statistics.vo.IotStatisticsDeviceMessageSummaryByDateRespVO;
15 import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageMethodEnum; 16 import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageMethodEnum;
16 -import cn.iocoder.yudao.module.iot.core.enums.IotDeviceStateEnum;  
17 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; 17 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
18 import cn.iocoder.yudao.module.iot.core.mq.producer.IotDeviceMessageProducer; 18 import cn.iocoder.yudao.module.iot.core.mq.producer.IotDeviceMessageProducer;
19 import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils; 19 import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils;
@@ -176,15 +176,12 @@ public class IotDeviceMessageServiceImpl implements IotDeviceMessageService { @@ -176,15 +176,12 @@ public class IotDeviceMessageServiceImpl implements IotDeviceMessageService {
176 // TODO @芋艿:可优化:未来逻辑复杂后,可以独立拆除 Processor 处理器 176 // TODO @芋艿:可优化:未来逻辑复杂后,可以独立拆除 Processor 处理器
177 @SuppressWarnings("SameReturnValue") 177 @SuppressWarnings("SameReturnValue")
178 private Object handleUpstreamDeviceMessage0(IotDeviceMessage message, IotDeviceDO device) { 178 private Object handleUpstreamDeviceMessage0(IotDeviceMessage message, IotDeviceDO device) {
179 - // 设备上线  
180 - if (Objects.equal(message.getMethod(), IotDeviceMessageMethodEnum.STATE_ONLINE.getMethod())) {  
181 - deviceService.updateDeviceState(device, IotDeviceStateEnum.ONLINE.getState());  
182 - // TODO 芋艿:子设备的关联  
183 - return null;  
184 - }  
185 - // 设备下线  
186 - if (Objects.equal(message.getMethod(), IotDeviceMessageMethodEnum.STATE_OFFLINE.getMethod())) {  
187 - deviceService.updateDeviceState(device, IotDeviceStateEnum.OFFLINE.getState()); 179 + // 设备上下线
  180 + if (Objects.equal(message.getMethod(), IotDeviceMessageMethodEnum.STATE_UPDATE.getMethod())) {
  181 + String stateStr = IotDeviceMessageUtils.getIdentifier(message);
  182 + assert stateStr != null;
  183 + Assert.notEmpty(stateStr, "设备状态不能为空");
  184 + deviceService.updateDeviceState(device, Integer.valueOf(stateStr));
188 // TODO 芋艿:子设备的关联 185 // TODO 芋艿:子设备的关联
189 return null; 186 return null;
190 } 187 }
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/data/IotDataRuleServiceImpl.java
@@ -172,7 +172,7 @@ public class IotDataRuleServiceImpl implements IotDataRuleService { @@ -172,7 +172,7 @@ public class IotDataRuleServiceImpl implements IotDataRuleService {
172 for (IotDataRuleDO rule : rules) { 172 for (IotDataRuleDO rule : rules) {
173 IotDataRuleDO.SourceConfig found = CollUtil.findOne(rule.getSourceConfigs(), 173 IotDataRuleDO.SourceConfig found = CollUtil.findOne(rule.getSourceConfigs(),
174 config -> ObjectUtils.equalsAny(config.getDeviceId(), deviceId, IotDeviceDO.DEVICE_ID_ALL) 174 config -> ObjectUtils.equalsAny(config.getDeviceId(), deviceId, IotDeviceDO.DEVICE_ID_ALL)
175 - && (StrUtil.isNotEmpty(config.getMethod()) || ObjUtil.equal(config.getMethod(), method)) 175 + && Objects.equals(config.getMethod(), method)
176 && (StrUtil.isEmpty(config.getIdentifier()) || ObjUtil.equal(config.getIdentifier(), identifier))); 176 && (StrUtil.isEmpty(config.getIdentifier()) || ObjUtil.equal(config.getIdentifier(), identifier)));
177 if (found != null) { 177 if (found != null) {
178 matchedRules.add(new IotDataRuleDO().setId(rule.getId()).setSinkIds(rule.getSinkIds())); 178 matchedRules.add(new IotDataRuleDO().setId(rule.getId()).setSinkIds(rule.getSinkIds()));
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/data/action/IotHttpDataSinkAction.java
@@ -18,6 +18,8 @@ import org.springframework.web.util.UriComponentsBuilder; @@ -18,6 +18,8 @@ import org.springframework.web.util.UriComponentsBuilder;
18 import java.util.HashMap; 18 import java.util.HashMap;
19 import java.util.Map; 19 import java.util.Map;
20 20
  21 +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID;
  22 +
21 /** 23 /**
22 * HTTP 的 {@link IotDataRuleAction} 实现类 24 * HTTP 的 {@link IotDataRuleAction} 实现类
23 * 25 *
@@ -36,6 +38,7 @@ public class IotHttpDataSinkAction implements IotDataRuleAction { @@ -36,6 +38,7 @@ public class IotHttpDataSinkAction implements IotDataRuleAction {
36 } 38 }
37 39
38 @Override 40 @Override
  41 + @SuppressWarnings("unchecked")
39 public void execute(IotDeviceMessage message, IotDataSinkDO dataSink) { 42 public void execute(IotDeviceMessage message, IotDataSinkDO dataSink) {
40 IotDataSinkHttpConfig config = (IotDataSinkHttpConfig) dataSink.getConfig(); 43 IotDataSinkHttpConfig config = (IotDataSinkHttpConfig) dataSink.getConfig();
41 Assert.notNull(config, "配置({})不能为空", dataSink.getId()); 44 Assert.notNull(config, "配置({})不能为空", dataSink.getId());
@@ -49,8 +52,7 @@ public class IotHttpDataSinkAction implements IotDataRuleAction { @@ -49,8 +52,7 @@ public class IotHttpDataSinkAction implements IotDataRuleAction {
49 if (CollUtil.isNotEmpty(config.getHeaders())) { 52 if (CollUtil.isNotEmpty(config.getHeaders())) {
50 config.getHeaders().putAll(config.getHeaders()); 53 config.getHeaders().putAll(config.getHeaders());
51 } 54 }
52 - // TODO @puhui999:@yunai:可能需要通过设备查询到租户,然后 set  
53 -// headers.add(HEADER_TENANT_ID, message.getTenantId().toString()); 55 + headers.add(HEADER_TENANT_ID, message.getTenantId().toString());
54 // 1.2 构建 URL 56 // 1.2 构建 URL
55 UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUriString(config.getUrl()); 57 UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUriString(config.getUrl());
56 if (CollUtil.isNotEmpty(config.getQuery())) { 58 if (CollUtil.isNotEmpty(config.getQuery())) {
@@ -72,18 +74,17 @@ public class IotHttpDataSinkAction implements IotDataRuleAction { @@ -72,18 +74,17 @@ public class IotHttpDataSinkAction implements IotDataRuleAction {
72 requestEntity = new HttpEntity<>(JsonUtils.toJsonString(requestBody), headers); 74 requestEntity = new HttpEntity<>(JsonUtils.toJsonString(requestBody), headers);
73 } 75 }
74 76
75 - // 2.1 发送请求 77 + // 2. 发送请求
76 responseEntity = restTemplate.exchange(url, method, requestEntity, String.class); 78 responseEntity = restTemplate.exchange(url, method, requestEntity, String.class);
77 - // 2.2 记录日志  
78 if (responseEntity.getStatusCode().is2xxSuccessful()) { 79 if (responseEntity.getStatusCode().is2xxSuccessful()) {
79 - log.info("[executeHttp][message({}) config({}) url({}) method({}) requestEntity({}) 请求成功({})]", 80 + log.info("[execute][message({}) config({}) url({}) method({}) requestEntity({}) 请求成功({})]",
80 message, config, url, method, requestEntity, responseEntity); 81 message, config, url, method, requestEntity, responseEntity);
81 } else { 82 } else {
82 - log.error("[executeHttp][message({}) config({}) url({}) method({}) requestEntity({}) 请求失败({})]", 83 + log.error("[execute][message({}) config({}) url({}) method({}) requestEntity({}) 请求失败({})]",
83 message, config, url, method, requestEntity, responseEntity); 84 message, config, url, method, requestEntity, responseEntity);
84 } 85 }
85 } catch (Exception e) { 86 } catch (Exception e) {
86 - log.error("[executeHttp][message({}) config({}) url({}) method({}) requestEntity({}) 请求异常({})]", 87 + log.error("[execute][message({}) config({}) url({}) method({}) requestEntity({}) 请求异常({})]",
87 message, config, url, method, requestEntity, responseEntity, e); 88 message, config, url, method, requestEntity, responseEntity, e);
88 } 89 }
89 } 90 }
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/data/action/IotKafkaDataRuleAction.java
1 package cn.iocoder.yudao.module.iot.service.rule.data.action; 1 package cn.iocoder.yudao.module.iot.service.rule.data.action;
2 2
  3 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
3 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.config.IotDataSinkKafkaConfig; 4 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.config.IotDataSinkKafkaConfig;
4 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; 5 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
5 import cn.iocoder.yudao.module.iot.enums.rule.IotDataSinkTypeEnum; 6 import cn.iocoder.yudao.module.iot.enums.rule.IotDataSinkTypeEnum;
@@ -9,6 +10,7 @@ import org.apache.kafka.common.serialization.StringSerializer; @@ -9,6 +10,7 @@ import org.apache.kafka.common.serialization.StringSerializer;
9 import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 10 import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
10 import org.springframework.kafka.core.DefaultKafkaProducerFactory; 11 import org.springframework.kafka.core.DefaultKafkaProducerFactory;
11 import org.springframework.kafka.core.KafkaTemplate; 12 import org.springframework.kafka.core.KafkaTemplate;
  13 +import org.springframework.kafka.support.SendResult;
12 import org.springframework.stereotype.Component; 14 import org.springframework.stereotype.Component;
13 15
14 import java.time.Duration; 16 import java.time.Duration;
@@ -36,13 +38,27 @@ public class IotKafkaDataRuleAction extends @@ -36,13 +38,27 @@ public class IotKafkaDataRuleAction extends
36 38
37 @Override 39 @Override
38 public void execute(IotDeviceMessage message, IotDataSinkKafkaConfig config) throws Exception { 40 public void execute(IotDeviceMessage message, IotDataSinkKafkaConfig config) throws Exception {
39 - // 1. 获取或创建 KafkaTemplate  
40 - KafkaTemplate<String, String> kafkaTemplate = getProducer(config); 41 + try {
  42 + // 1. 获取或创建 KafkaTemplate
  43 + KafkaTemplate<String, String> kafkaTemplate = getProducer(config);
41 44
42 - // 2. 发送消息并等待结果  
43 - kafkaTemplate.send(config.getTopic(), message.toString())  
44 - .get(SEND_TIMEOUT.getSeconds(), TimeUnit.SECONDS); // 添加超时等待  
45 - log.info("[execute0][message({}) 发送成功]", message); 45 + // 2. 发送消息并等待结果
  46 + SendResult<String, String> sendResult = kafkaTemplate.send(config.getTopic(), JsonUtils.toJsonString(message))
  47 + .get(SEND_TIMEOUT.getSeconds(), TimeUnit.SECONDS);
  48 + // 3. 处理发送结果
  49 + if (sendResult != null && sendResult.getRecordMetadata() != null) {
  50 + log.info("[execute][message({}) config({}) 发送成功,结果: partition={}, offset={}, timestamp={}]",
  51 + message, config,
  52 + sendResult.getRecordMetadata().partition(),
  53 + sendResult.getRecordMetadata().offset(),
  54 + sendResult.getRecordMetadata().timestamp());
  55 + } else {
  56 + log.warn("[execute][message({}) config({}) 发送结果为空]", message, config);
  57 + }
  58 + } catch (Exception e) {
  59 + log.error("[execute][message({}) config({}) 发送失败]", message, config, e);
  60 + throw e;
  61 + }
46 } 62 }
47 63
48 @Override 64 @Override
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/data/action/IotRabbitMQDataRuleAction.java
1 package cn.iocoder.yudao.module.iot.service.rule.data.action; 1 package cn.iocoder.yudao.module.iot.service.rule.data.action;
2 2
3 -import cn.iocoder.yudao.module.iot.dal.dataobject.rule.config.IotDataSinkRabbitMQConfig; 3 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
4 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; 4 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
  5 +import cn.iocoder.yudao.module.iot.dal.dataobject.rule.config.IotDataSinkRabbitMQConfig;
5 import cn.iocoder.yudao.module.iot.enums.rule.IotDataSinkTypeEnum; 6 import cn.iocoder.yudao.module.iot.enums.rule.IotDataSinkTypeEnum;
6 import com.rabbitmq.client.Channel; 7 import com.rabbitmq.client.Channel;
7 import com.rabbitmq.client.Connection; 8 import com.rabbitmq.client.Connection;
@@ -10,8 +11,6 @@ import lombok.extern.slf4j.Slf4j; @@ -10,8 +11,6 @@ import lombok.extern.slf4j.Slf4j;
10 import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 11 import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
11 import org.springframework.stereotype.Component; 12 import org.springframework.stereotype.Component;
12 13
13 -import java.nio.charset.StandardCharsets;  
14 -  
15 /** 14 /**
16 * RabbitMQ 的 {@link IotDataRuleAction} 实现类 15 * RabbitMQ 的 {@link IotDataRuleAction} 实现类
17 * 16 *
@@ -20,8 +19,8 @@ import java.nio.charset.StandardCharsets; @@ -20,8 +19,8 @@ import java.nio.charset.StandardCharsets;
20 @ConditionalOnClass(name = "com.rabbitmq.client.Channel") 19 @ConditionalOnClass(name = "com.rabbitmq.client.Channel")
21 @Component 20 @Component
22 @Slf4j 21 @Slf4j
23 -public class IotRabbitMQDataRuleAction extends  
24 - IotDataRuleCacheableAction<IotDataSinkRabbitMQConfig, Channel> { 22 +public class IotRabbitMQDataRuleAction
  23 + extends IotDataRuleCacheableAction<IotDataSinkRabbitMQConfig, Channel> {
25 24
26 @Override 25 @Override
27 public Integer getType() { 26 public Integer getType() {
@@ -30,17 +29,22 @@ public class IotRabbitMQDataRuleAction extends @@ -30,17 +29,22 @@ public class IotRabbitMQDataRuleAction extends
30 29
31 @Override 30 @Override
32 public void execute(IotDeviceMessage message, IotDataSinkRabbitMQConfig config) throws Exception { 31 public void execute(IotDeviceMessage message, IotDataSinkRabbitMQConfig config) throws Exception {
33 - // 1.1 获取或创建 Channel  
34 - Channel channel = getProducer(config);  
35 - // 1.2 声明交换机、队列和绑定关系  
36 - channel.exchangeDeclare(config.getExchange(), "direct", true);  
37 - channel.queueDeclare(config.getQueue(), true, false, false, null);  
38 - channel.queueBind(config.getQueue(), config.getExchange(), config.getRoutingKey()); 32 + try {
  33 + // 1.1 获取或创建 Channel
  34 + Channel channel = getProducer(config);
  35 + // 1.2 声明交换机、队列和绑定关系
  36 + channel.exchangeDeclare(config.getExchange(), "direct", true);
  37 + channel.queueDeclare(config.getQueue(), true, false, false, null);
  38 + channel.queueBind(config.getQueue(), config.getExchange(), config.getRoutingKey());
39 39
40 - // 2. 发送消息  
41 - channel.basicPublish(config.getExchange(), config.getRoutingKey(), null,  
42 - message.toString().getBytes(StandardCharsets.UTF_8));  
43 - log.info("[executeRabbitMQ][message({}) config({}) 发送成功]", message, config); 40 + // 2. 发送消息
  41 + channel.basicPublish(config.getExchange(), config.getRoutingKey(), null,
  42 + JsonUtils.toJsonByte(message));
  43 + log.info("[execute][message({}) config({}) 发送成功]", message, config);
  44 + } catch (Exception e) {
  45 + log.error("[execute][message({}) config({}) 发送失败]", message, config, e);
  46 + throw e;
  47 + }
44 } 48 }
45 49
46 @Override 50 @Override
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/data/action/IotRedisStreamRuleAction.java
1 package cn.iocoder.yudao.module.iot.service.rule.data.action; 1 package cn.iocoder.yudao.module.iot.service.rule.data.action;
2 2
3 import cn.hutool.core.util.StrUtil; 3 import cn.hutool.core.util.StrUtil;
  4 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
4 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.config.IotDataSinkRedisStreamConfig; 5 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.config.IotDataSinkRedisStreamConfig;
5 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; 6 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
6 import cn.iocoder.yudao.module.iot.enums.rule.IotDataSinkTypeEnum; 7 import cn.iocoder.yudao.module.iot.enums.rule.IotDataSinkTypeEnum;
@@ -38,10 +39,10 @@ public class IotRedisStreamRuleAction extends @@ -38,10 +39,10 @@ public class IotRedisStreamRuleAction extends
38 RedisTemplate<String, Object> redisTemplate = getProducer(config); 39 RedisTemplate<String, Object> redisTemplate = getProducer(config);
39 40
40 // 2. 创建并发送 Stream 记录 41 // 2. 创建并发送 Stream 记录
41 - ObjectRecord<String, IotDeviceMessage> record = StreamRecords.newRecord()  
42 - .ofObject(message).withStreamKey(config.getTopic()); 42 + ObjectRecord<String, ?> record = StreamRecords.newRecord()
  43 + .ofObject(JsonUtils.toJsonString(message)).withStreamKey(config.getTopic());
43 String recordId = String.valueOf(redisTemplate.opsForStream().add(record)); 44 String recordId = String.valueOf(redisTemplate.opsForStream().add(record));
44 - log.info("[executeRedisStream][消息发送成功] messageId: {}, config: {}", recordId, config); 45 + log.info("[execute][消息发送成功] messageId: {}, config: {}", recordId, config);
45 } 46 }
46 47
47 @Override 48 @Override
@@ -56,11 +57,11 @@ public class IotRedisStreamRuleAction extends @@ -56,11 +57,11 @@ public class IotRedisStreamRuleAction extends
56 serverConfig.setPassword(config.getPassword()); 57 serverConfig.setPassword(config.getPassword());
57 } 58 }
58 59
59 - // 创建 RedisTemplate 并配置 60 + // 2.1 创建 RedisTemplate 并配置
60 RedissonClient redisson = Redisson.create(redissonConfig); 61 RedissonClient redisson = Redisson.create(redissonConfig);
61 RedisTemplate<String, Object> template = new RedisTemplate<>(); 62 RedisTemplate<String, Object> template = new RedisTemplate<>();
62 template.setConnectionFactory(new RedissonConnectionFactory(redisson)); 63 template.setConnectionFactory(new RedissonConnectionFactory(redisson));
63 - // 设置序列化器 64 + // 2.2 设置序列化器
64 template.setKeySerializer(RedisSerializer.string()); 65 template.setKeySerializer(RedisSerializer.string());
65 template.setHashKeySerializer(RedisSerializer.string()); 66 template.setHashKeySerializer(RedisSerializer.string());
66 template.setValueSerializer(RedisSerializer.json()); 67 template.setValueSerializer(RedisSerializer.json());
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/data/action/IotRocketMQDataRuleAction.java
1 package cn.iocoder.yudao.module.iot.service.rule.data.action; 1 package cn.iocoder.yudao.module.iot.service.rule.data.action;
2 2
3 -import cn.iocoder.yudao.module.iot.dal.dataobject.rule.config.IotDataSinkRocketMQConfig; 3 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
4 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; 4 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
  5 +import cn.iocoder.yudao.module.iot.dal.dataobject.rule.config.IotDataSinkRocketMQConfig;
5 import cn.iocoder.yudao.module.iot.enums.rule.IotDataSinkTypeEnum; 6 import cn.iocoder.yudao.module.iot.enums.rule.IotDataSinkTypeEnum;
6 import lombok.extern.slf4j.Slf4j; 7 import lombok.extern.slf4j.Slf4j;
7 import org.apache.rocketmq.client.producer.DefaultMQProducer; 8 import org.apache.rocketmq.client.producer.DefaultMQProducer;
8 import org.apache.rocketmq.client.producer.SendResult; 9 import org.apache.rocketmq.client.producer.SendResult;
9 import org.apache.rocketmq.client.producer.SendStatus; 10 import org.apache.rocketmq.client.producer.SendStatus;
10 import org.apache.rocketmq.common.message.Message; 11 import org.apache.rocketmq.common.message.Message;
11 -import org.apache.rocketmq.remoting.common.RemotingHelper;  
12 import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 12 import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
13 import org.springframework.stereotype.Component; 13 import org.springframework.stereotype.Component;
14 14
@@ -33,19 +33,15 @@ public class IotRocketMQDataRuleAction extends @@ -33,19 +33,15 @@ public class IotRocketMQDataRuleAction extends
33 // 1. 获取或创建 Producer 33 // 1. 获取或创建 Producer
34 DefaultMQProducer producer = getProducer(config); 34 DefaultMQProducer producer = getProducer(config);
35 35
36 - // 2.1 创建消息对象,指定Topic、Tag和消息体  
37 - Message msg = new Message(  
38 - config.getTopic(),  
39 - config.getTags(),  
40 - message.toString().getBytes(RemotingHelper.DEFAULT_CHARSET)  
41 - ); 36 + // 2.1 创建消息对象,指定 Topic、Tag 和消息体
  37 + Message msg = new Message(config.getTopic(), config.getTags(), JsonUtils.toJsonByte(message));
42 // 2.2 发送同步消息并处理结果 38 // 2.2 发送同步消息并处理结果
43 SendResult sendResult = producer.send(msg); 39 SendResult sendResult = producer.send(msg);
44 // 2.3 处理发送结果 40 // 2.3 处理发送结果
45 if (SendStatus.SEND_OK.equals(sendResult.getSendStatus())) { 41 if (SendStatus.SEND_OK.equals(sendResult.getSendStatus())) {
46 - log.info("[executeRocketMQ][message({}) config({}) 发送成功,结果({})]", message, config, sendResult); 42 + log.info("[execute][message({}) config({}) 发送成功,结果({})]", message, config, sendResult);
47 } else { 43 } else {
48 - log.error("[executeRocketMQ][message({}) config({}) 发送失败,结果({})]", message, config, sendResult); 44 + log.error("[execute][message({}) config({}) 发送失败,结果({})]", message, config, sendResult);
49 } 45 }
50 } 46 }
51 47
yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/rule/action/databridge/IotDataBridgeExecuteTest.java
@@ -39,6 +39,7 @@ public class IotDataBridgeExecuteTest extends BaseMockitoUnitTest { @@ -39,6 +39,7 @@ public class IotDataBridgeExecuteTest extends BaseMockitoUnitTest {
39 39
40 @BeforeEach 40 @BeforeEach
41 public void setUp() { 41 public void setUp() {
  42 + // TODO @芋艿:@puhui999:需要调整下;
42 // 创建共享的测试消息 43 // 创建共享的测试消息
43 //message = IotDeviceMessage.builder().messageId("TEST-001").reportTime(LocalDateTime.now()) 44 //message = IotDeviceMessage.builder().messageId("TEST-001").reportTime(LocalDateTime.now())
44 // .productKey("testProduct").deviceName("testDevice") 45 // .productKey("testProduct").deviceName("testDevice")
yudao-module-iot/yudao-module-iot-core/src/main/java/cn/iocoder/yudao/module/iot/core/enums/IotDeviceMessageMethodEnum.java
@@ -19,10 +19,6 @@ public enum IotDeviceMessageMethodEnum implements ArrayValuable&lt;String&gt; { @@ -19,10 +19,6 @@ public enum IotDeviceMessageMethodEnum implements ArrayValuable&lt;String&gt; {
19 19
20 // ========== 设备状态 ========== 20 // ========== 设备状态 ==========
21 21
22 - // TODO @芋艿:要合并下;thing.state.update  
23 - STATE_ONLINE("thing.state.online", "设备上线", true),  
24 - STATE_OFFLINE("thing.state.offline", "设备下线", true),  
25 -  
26 STATE_UPDATE("thing.state.update", "设备状态更新", true), 22 STATE_UPDATE("thing.state.update", "设备状态更新", true),
27 23
28 // ========== 设备属性 ========== 24 // ========== 设备属性 ==========
@@ -52,7 +48,7 @@ public enum IotDeviceMessageMethodEnum implements ArrayValuable&lt;String&gt; { @@ -52,7 +48,7 @@ public enum IotDeviceMessageMethodEnum implements ArrayValuable&lt;String&gt; {
52 /** 48 /**
53 * 不进行 reply 回复的方法集合 49 * 不进行 reply 回复的方法集合
54 */ 50 */
55 - public static final Set<String> REPLY_DISABLED = Set.of(STATE_ONLINE.getMethod(), STATE_OFFLINE.getMethod()); 51 + public static final Set<String> REPLY_DISABLED = Set.of(STATE_UPDATE.getMethod());
56 52
57 private final String method; 53 private final String method;
58 54
yudao-module-iot/yudao-module-iot-core/src/main/java/cn/iocoder/yudao/module/iot/core/mq/message/IotDeviceMessage.java
1 package cn.iocoder.yudao.module.iot.core.mq.message; 1 package cn.iocoder.yudao.module.iot.core.mq.message;
2 2
  3 +import cn.hutool.core.map.MapUtil;
3 import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants; 4 import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
4 import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageMethodEnum; 5 import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageMethodEnum;
  6 +import cn.iocoder.yudao.module.iot.core.enums.IotDeviceStateEnum;
5 import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils; 7 import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils;
6 import lombok.AllArgsConstructor; 8 import lombok.AllArgsConstructor;
7 import lombok.Builder; 9 import lombok.Builder;
@@ -128,12 +130,14 @@ public class IotDeviceMessage { @@ -128,12 +130,14 @@ public class IotDeviceMessage {
128 130
129 // ========== 核心方法:在 of 基础方法之上,添加对应 method ========== 131 // ========== 核心方法:在 of 基础方法之上,添加对应 method ==========
130 132
131 - public static IotDeviceMessage buildStateOnline() {  
132 - return requestOf(IotDeviceMessageMethodEnum.STATE_ONLINE.getMethod()); 133 + public static IotDeviceMessage buildStateUpdateOnline() {
  134 + return requestOf(IotDeviceMessageMethodEnum.STATE_UPDATE.getMethod(),
  135 + MapUtil.of("state", IotDeviceStateEnum.ONLINE.getState()));
133 } 136 }
134 137
135 public static IotDeviceMessage buildStateOffline() { 138 public static IotDeviceMessage buildStateOffline() {
136 - return requestOf(IotDeviceMessageMethodEnum.STATE_OFFLINE.getMethod()); 139 + return requestOf(IotDeviceMessageMethodEnum.STATE_UPDATE.getMethod(),
  140 + MapUtil.of("state", IotDeviceStateEnum.OFFLINE.getState()));
137 } 141 }
138 142
139 } 143 }
yudao-module-iot/yudao-module-iot-core/src/main/java/cn/iocoder/yudao/module/iot/core/util/IotDeviceMessageUtils.java
@@ -55,11 +55,16 @@ public class IotDeviceMessageUtils { @@ -55,11 +55,16 @@ public class IotDeviceMessageUtils {
55 */ 55 */
56 @SuppressWarnings("unchecked") 56 @SuppressWarnings("unchecked")
57 public static String getIdentifier(IotDeviceMessage message) { 57 public static String getIdentifier(IotDeviceMessage message) {
  58 + if (message.getParams() == null) {
  59 + return null;
  60 + }
58 if (StrUtil.equalsAny(message.getMethod(), IotDeviceMessageMethodEnum.EVENT_POST.getMethod(), 61 if (StrUtil.equalsAny(message.getMethod(), IotDeviceMessageMethodEnum.EVENT_POST.getMethod(),
59 - message.getMethod(), IotDeviceMessageMethodEnum.SERVICE_INVOKE.getMethod())  
60 - && message.getParams() != null) { 62 + IotDeviceMessageMethodEnum.SERVICE_INVOKE.getMethod())) {
61 Map<String, Object> params = (Map<String, Object>) message.getParams(); 63 Map<String, Object> params = (Map<String, Object>) message.getParams();
62 return MapUtil.getStr(params, "identifier"); 64 return MapUtil.getStr(params, "identifier");
  65 + } else if (StrUtil.equalsAny(message.getMethod(), IotDeviceMessageMethodEnum.STATE_UPDATE.getMethod())) {
  66 + Map<String, Object> params = (Map<String, Object>) message.getParams();
  67 + return MapUtil.getStr(params, "state");
63 } 68 }
64 return null; 69 return null;
65 } 70 }
yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/emqx/router/IotEmqxAuthEventHandler.java
@@ -209,7 +209,7 @@ public class IotEmqxAuthEventHandler { @@ -209,7 +209,7 @@ public class IotEmqxAuthEventHandler {
209 209
210 try { 210 try {
211 // 2. 构建设备状态消息 211 // 2. 构建设备状态消息
212 - IotDeviceMessage message = online ? IotDeviceMessage.buildStateOnline() 212 + IotDeviceMessage message = online ? IotDeviceMessage.buildStateUpdateOnline()
213 : IotDeviceMessage.buildStateOffline(); 213 : IotDeviceMessage.buildStateOffline();
214 214
215 // 3. 发送设备状态消息 215 // 3. 发送设备状态消息
yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/http/router/IotHttpAuthHandler.java
@@ -78,7 +78,7 @@ public class IotHttpAuthHandler extends IotHttpAbstractHandler { @@ -78,7 +78,7 @@ public class IotHttpAuthHandler extends IotHttpAbstractHandler {
78 Assert.notBlank(token, "生成 token 不能为空位"); 78 Assert.notBlank(token, "生成 token 不能为空位");
79 79
80 // 3. 执行上线 80 // 3. 执行上线
81 - IotDeviceMessage message = IotDeviceMessage.buildStateOnline(); 81 + IotDeviceMessage message = IotDeviceMessage.buildStateUpdateOnline();
82 deviceMessageService.sendDeviceMessage(message, 82 deviceMessageService.sendDeviceMessage(message,
83 deviceInfo.getProductKey(), deviceInfo.getDeviceName(), protocol.getServerId()); 83 deviceInfo.getProductKey(), deviceInfo.getDeviceName(), protocol.getServerId());
84 84