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 <version>${revision}</version>
8 8 </parent>
9 9 <modules>
10   - <module>yudao-module-iot-api</module>
11 10 <module>yudao-module-iot-biz</module>
12 11 <module>yudao-module-iot-core</module>
13 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 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 25 </dependency>
26 26 <dependency>
27 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 28 <artifactId>yudao-module-iot-core</artifactId>
34 29 <version>${revision}</version>
35 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 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 10 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
6 11 import com.baomidou.mybatisplus.annotation.KeySequence;
7 12 import com.baomidou.mybatisplus.annotation.TableField;
8 13 import com.baomidou.mybatisplus.annotation.TableId;
9 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 20 import java.util.List;
14 21  
... ... @@ -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 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 59 private Integer status;
53 60  
54 61 /**
55   - * 关联的规则场景编号数组
  62 + * 关联的场景联动规则编号数组
56 63 *
57 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 72 * 关联 {@link AdminUserRespDTO#getId()}
66 73 */
67   - @TableField(typeHandler = JacksonTypeHandler.class)
  74 + @TableField(typeHandler = LongListTypeHandler.class)
68 75 private List<Long> receiveUserIds;
69 76 /**
70 77 * 接收的类型数组
71 78 *
72 79 * 枚举 {@link IotAlertConfigReceiveTypeEnum}
73 80 */
74   - @TableField(typeHandler = JacksonTypeHandler.class)
  81 + @TableField(typeHandler = IntegerListTypeHandler.class)
75 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 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 4 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
... ... @@ -45,17 +45,17 @@ public class IotAlertRecordDO extends BaseDO {
45 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 60 // TODO @芋艿:有没更好的方式
61 61 /**
... ... @@ -64,7 +64,6 @@ public class IotAlertRecordDO extends BaseDO {
64 64 @TableField(typeHandler = JacksonTypeHandler.class)
65 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 3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
4 4 import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
5 5 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
  6 +import cn.iocoder.yudao.module.iot.dal.dataobject.alert.IotAlertConfigDO;
6 7 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
7 8 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
8 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 14  
15 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 3 import cn.iocoder.yudao.framework.common.core.ArrayValuable;
4 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 16 public enum IotDataSinkTypeEnum implements ArrayValuable<Integer> {
17 17  
18 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 27 ROCKETMQ(30, "RocketMQ"),
29 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 1 package cn.iocoder.yudao.module.iot.mq.consumer.device;
2 2  
3 3 import cn.hutool.core.util.ObjectUtil;
4   -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
5 4 import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
6 5 import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageMethodEnum;
7 6 import cn.iocoder.yudao.module.iot.core.enums.IotDeviceStateEnum;
... ... @@ -19,6 +18,7 @@ import lombok.extern.slf4j.Slf4j;
19 18 import org.springframework.stereotype.Component;
20 19  
21 20 import java.time.LocalDateTime;
  21 +import java.util.Objects;
22 22  
23 23 /**
24 24 * 针对 {@link IotDeviceMessage} 的业务处理器:调用 method 对应的逻辑。例如说:
... ... @@ -83,15 +83,14 @@ public class IotDeviceMessageSubscriber implements IotMessageSubscriber&lt;IotDevic
83 83 return;
84 84 }
85 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 87 return;
89 88 }
90 89  
91 90 // 特殊:设备非在线时,主动标记设备为在线
92 91 // 为什么不直接更新状态呢?因为通过 IotDeviceMessage 可以经过一系列的处理,例如说记录日志、规则引擎等等
93 92 try {
94   - deviceMessageService.sendDeviceMessage(IotDeviceMessage.buildStateOnline().setDeviceId(device.getId()));
  93 + deviceMessageService.sendDeviceMessage(IotDeviceMessage.buildStateUpdateOnline().setDeviceId(device.getId()));
95 94 } catch (Exception e) {
96 95 // 注意:即使执行失败,也不影响主流程
97 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 1 package cn.iocoder.yudao.module.iot.service.device.message;
2 2  
3 3 import cn.hutool.core.date.LocalDateTimeUtil;
  4 +import cn.hutool.core.lang.Assert;
4 5 import cn.hutool.core.map.MapUtil;
5 6 import cn.hutool.core.util.StrUtil;
6 7 import cn.hutool.extra.spring.SpringUtil;
... ... @@ -13,7 +14,6 @@ import cn.iocoder.yudao.module.iot.controller.admin.device.vo.message.IotDeviceM
13 14 import cn.iocoder.yudao.module.iot.controller.admin.statistics.vo.IotStatisticsDeviceMessageReqVO;
14 15 import cn.iocoder.yudao.module.iot.controller.admin.statistics.vo.IotStatisticsDeviceMessageSummaryByDateRespVO;
15 16 import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageMethodEnum;
16   -import cn.iocoder.yudao.module.iot.core.enums.IotDeviceStateEnum;
17 17 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
18 18 import cn.iocoder.yudao.module.iot.core.mq.producer.IotDeviceMessageProducer;
19 19 import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils;
... ... @@ -176,15 +176,12 @@ public class IotDeviceMessageServiceImpl implements IotDeviceMessageService {
176 176 // TODO @芋艿:可优化:未来逻辑复杂后,可以独立拆除 Processor 处理器
177 177 @SuppressWarnings("SameReturnValue")
178 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 185 // TODO 芋艿:子设备的关联
189 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 172 for (IotDataRuleDO rule : rules) {
173 173 IotDataRuleDO.SourceConfig found = CollUtil.findOne(rule.getSourceConfigs(),
174 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 176 && (StrUtil.isEmpty(config.getIdentifier()) || ObjUtil.equal(config.getIdentifier(), identifier)));
177 177 if (found != null) {
178 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 18 import java.util.HashMap;
19 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 24 * HTTP 的 {@link IotDataRuleAction} 实现类
23 25 *
... ... @@ -36,6 +38,7 @@ public class IotHttpDataSinkAction implements IotDataRuleAction {
36 38 }
37 39  
38 40 @Override
  41 + @SuppressWarnings("unchecked")
39 42 public void execute(IotDeviceMessage message, IotDataSinkDO dataSink) {
40 43 IotDataSinkHttpConfig config = (IotDataSinkHttpConfig) dataSink.getConfig();
41 44 Assert.notNull(config, "配置({})不能为空", dataSink.getId());
... ... @@ -49,8 +52,7 @@ public class IotHttpDataSinkAction implements IotDataRuleAction {
49 52 if (CollUtil.isNotEmpty(config.getHeaders())) {
50 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 56 // 1.2 构建 URL
55 57 UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUriString(config.getUrl());
56 58 if (CollUtil.isNotEmpty(config.getQuery())) {
... ... @@ -72,18 +74,17 @@ public class IotHttpDataSinkAction implements IotDataRuleAction {
72 74 requestEntity = new HttpEntity<>(JsonUtils.toJsonString(requestBody), headers);
73 75 }
74 76  
75   - // 2.1 发送请求
  77 + // 2. 发送请求
76 78 responseEntity = restTemplate.exchange(url, method, requestEntity, String.class);
77   - // 2.2 记录日志
78 79 if (responseEntity.getStatusCode().is2xxSuccessful()) {
79   - log.info("[executeHttp][message({}) config({}) url({}) method({}) requestEntity({}) 请求成功({})]",
  80 + log.info("[execute][message({}) config({}) url({}) method({}) requestEntity({}) 请求成功({})]",
80 81 message, config, url, method, requestEntity, responseEntity);
81 82 } else {
82   - log.error("[executeHttp][message({}) config({}) url({}) method({}) requestEntity({}) 请求失败({})]",
  83 + log.error("[execute][message({}) config({}) url({}) method({}) requestEntity({}) 请求失败({})]",
83 84 message, config, url, method, requestEntity, responseEntity);
84 85 }
85 86 } catch (Exception e) {
86   - log.error("[executeHttp][message({}) config({}) url({}) method({}) requestEntity({}) 请求异常({})]",
  87 + log.error("[execute][message({}) config({}) url({}) method({}) requestEntity({}) 请求异常({})]",
87 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 1 package cn.iocoder.yudao.module.iot.service.rule.data.action;
2 2  
  3 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
3 4 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.config.IotDataSinkKafkaConfig;
4 5 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
5 6 import cn.iocoder.yudao.module.iot.enums.rule.IotDataSinkTypeEnum;
... ... @@ -9,6 +10,7 @@ import org.apache.kafka.common.serialization.StringSerializer;
9 10 import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
10 11 import org.springframework.kafka.core.DefaultKafkaProducerFactory;
11 12 import org.springframework.kafka.core.KafkaTemplate;
  13 +import org.springframework.kafka.support.SendResult;
12 14 import org.springframework.stereotype.Component;
13 15  
14 16 import java.time.Duration;
... ... @@ -36,13 +38,27 @@ public class IotKafkaDataRuleAction extends
36 38  
37 39 @Override
38 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 64 @Override
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/data/action/IotRabbitMQDataRuleAction.java
1 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 4 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
  5 +import cn.iocoder.yudao.module.iot.dal.dataobject.rule.config.IotDataSinkRabbitMQConfig;
5 6 import cn.iocoder.yudao.module.iot.enums.rule.IotDataSinkTypeEnum;
6 7 import com.rabbitmq.client.Channel;
7 8 import com.rabbitmq.client.Connection;
... ... @@ -10,8 +11,6 @@ import lombok.extern.slf4j.Slf4j;
10 11 import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
11 12 import org.springframework.stereotype.Component;
12 13  
13   -import java.nio.charset.StandardCharsets;
14   -
15 14 /**
16 15 * RabbitMQ 的 {@link IotDataRuleAction} 实现类
17 16 *
... ... @@ -20,8 +19,8 @@ import java.nio.charset.StandardCharsets;
20 19 @ConditionalOnClass(name = "com.rabbitmq.client.Channel")
21 20 @Component
22 21 @Slf4j
23   -public class IotRabbitMQDataRuleAction extends
24   - IotDataRuleCacheableAction<IotDataSinkRabbitMQConfig, Channel> {
  22 +public class IotRabbitMQDataRuleAction
  23 + extends IotDataRuleCacheableAction<IotDataSinkRabbitMQConfig, Channel> {
25 24  
26 25 @Override
27 26 public Integer getType() {
... ... @@ -30,17 +29,22 @@ public class IotRabbitMQDataRuleAction extends
30 29  
31 30 @Override
32 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 50 @Override
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/data/action/IotRedisStreamRuleAction.java
1 1 package cn.iocoder.yudao.module.iot.service.rule.data.action;
2 2  
3 3 import cn.hutool.core.util.StrUtil;
  4 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
4 5 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.config.IotDataSinkRedisStreamConfig;
5 6 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
6 7 import cn.iocoder.yudao.module.iot.enums.rule.IotDataSinkTypeEnum;
... ... @@ -38,10 +39,10 @@ public class IotRedisStreamRuleAction extends
38 39 RedisTemplate<String, Object> redisTemplate = getProducer(config);
39 40  
40 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 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 48 @Override
... ... @@ -56,11 +57,11 @@ public class IotRedisStreamRuleAction extends
56 57 serverConfig.setPassword(config.getPassword());
57 58 }
58 59  
59   - // 创建 RedisTemplate 并配置
  60 + // 2.1 创建 RedisTemplate 并配置
60 61 RedissonClient redisson = Redisson.create(redissonConfig);
61 62 RedisTemplate<String, Object> template = new RedisTemplate<>();
62 63 template.setConnectionFactory(new RedissonConnectionFactory(redisson));
63   - // 设置序列化器
  64 + // 2.2 设置序列化器
64 65 template.setKeySerializer(RedisSerializer.string());
65 66 template.setHashKeySerializer(RedisSerializer.string());
66 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 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 4 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
  5 +import cn.iocoder.yudao.module.iot.dal.dataobject.rule.config.IotDataSinkRocketMQConfig;
5 6 import cn.iocoder.yudao.module.iot.enums.rule.IotDataSinkTypeEnum;
6 7 import lombok.extern.slf4j.Slf4j;
7 8 import org.apache.rocketmq.client.producer.DefaultMQProducer;
8 9 import org.apache.rocketmq.client.producer.SendResult;
9 10 import org.apache.rocketmq.client.producer.SendStatus;
10 11 import org.apache.rocketmq.common.message.Message;
11   -import org.apache.rocketmq.remoting.common.RemotingHelper;
12 12 import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
13 13 import org.springframework.stereotype.Component;
14 14  
... ... @@ -33,19 +33,15 @@ public class IotRocketMQDataRuleAction extends
33 33 // 1. 获取或创建 Producer
34 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 38 // 2.2 发送同步消息并处理结果
43 39 SendResult sendResult = producer.send(msg);
44 40 // 2.3 处理发送结果
45 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 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 39  
40 40 @BeforeEach
41 41 public void setUp() {
  42 + // TODO @芋艿:@puhui999:需要调整下;
42 43 // 创建共享的测试消息
43 44 //message = IotDeviceMessage.builder().messageId("TEST-001").reportTime(LocalDateTime.now())
44 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 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 22 STATE_UPDATE("thing.state.update", "设备状态更新", true),
27 23  
28 24 // ========== 设备属性 ==========
... ... @@ -52,7 +48,7 @@ public enum IotDeviceMessageMethodEnum implements ArrayValuable&lt;String&gt; {
52 48 /**
53 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 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 1 package cn.iocoder.yudao.module.iot.core.mq.message;
2 2  
  3 +import cn.hutool.core.map.MapUtil;
3 4 import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
4 5 import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageMethodEnum;
  6 +import cn.iocoder.yudao.module.iot.core.enums.IotDeviceStateEnum;
5 7 import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils;
6 8 import lombok.AllArgsConstructor;
7 9 import lombok.Builder;
... ... @@ -128,12 +130,14 @@ public class IotDeviceMessage {
128 130  
129 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 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 55 */
56 56 @SuppressWarnings("unchecked")
57 57 public static String getIdentifier(IotDeviceMessage message) {
  58 + if (message.getParams() == null) {
  59 + return null;
  60 + }
58 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 63 Map<String, Object> params = (Map<String, Object>) message.getParams();
62 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 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 209  
210 210 try {
211 211 // 2. 构建设备状态消息
212   - IotDeviceMessage message = online ? IotDeviceMessage.buildStateOnline()
  212 + IotDeviceMessage message = online ? IotDeviceMessage.buildStateUpdateOnline()
213 213 : IotDeviceMessage.buildStateOffline();
214 214  
215 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 78 Assert.notBlank(token, "生成 token 不能为空位");
79 79  
80 80 // 3. 执行上线
81   - IotDeviceMessage message = IotDeviceMessage.buildStateOnline();
  81 + IotDeviceMessage message = IotDeviceMessage.buildStateUpdateOnline();
82 82 deviceMessageService.sendDeviceMessage(message,
83 83 deviceInfo.getProductKey(), deviceInfo.getDeviceName(), protocol.getServerId());
84 84  
... ...