Commit 0faee76ffd9013235427c5e998ba25d0a508a36f
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> <!– PF4J:内置插件机制 –>--> | ||
| 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
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<IotDevic | @@ -83,15 +83,14 @@ public class IotDeviceMessageSubscriber implements IotMessageSubscriber<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<String> { | @@ -19,10 +19,6 @@ public enum IotDeviceMessageMethodEnum implements ArrayValuable<String> { | ||
| 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<String> { | @@ -52,7 +48,7 @@ public enum IotDeviceMessageMethodEnum implements ArrayValuable<String> { | ||
| 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 |