Commit 37fdd6247d3572a60bd7a5afea34a1fca51b2844
Committed by
Gitee
!1302 【代码优化】IoT: 物模型、场景联动
Merge pull request !1302 from puhui999/iot
Showing
33 changed files
with
436 additions
and
490 deletions
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java
| @@ -72,8 +72,8 @@ public interface ErrorCodeConstants { | @@ -72,8 +72,8 @@ public interface ErrorCodeConstants { | ||
| 72 | // ========== IoT 数据桥梁 1-050-010-000 ========== | 72 | // ========== IoT 数据桥梁 1-050-010-000 ========== |
| 73 | ErrorCode DATA_BRIDGE_NOT_EXISTS = new ErrorCode(1_050_010_000, "IoT 数据桥梁不存在"); | 73 | ErrorCode DATA_BRIDGE_NOT_EXISTS = new ErrorCode(1_050_010_000, "IoT 数据桥梁不存在"); |
| 74 | 74 | ||
| 75 | - // ========== IoT 规则场景(场景联动) 1-050-011-000 ========== | ||
| 76 | - ErrorCode RULE_SCENE_NOT_EXISTS = new ErrorCode(1_050_011_000, "IoT 规则场景(场景联动)不存在"); | 75 | + // ========== IoT 场景联动 1-050-011-000 ========== |
| 76 | + ErrorCode RULE_SCENE_NOT_EXISTS = new ErrorCode(1_050_011_000, "IoT 场景联动不存在"); | ||
| 77 | 77 | ||
| 78 | // ========== IoT 产品脚本信息 1-050-012-000 ========== | 78 | // ========== IoT 产品脚本信息 1-050-012-000 ========== |
| 79 | ErrorCode PRODUCT_SCRIPT_NOT_EXISTS = new ErrorCode(1_050_012_000, "IoT 产品脚本信息不存在"); | 79 | ErrorCode PRODUCT_SCRIPT_NOT_EXISTS = new ErrorCode(1_050_012_000, "IoT 产品脚本信息不存在"); |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/IotRuleSceneController.java
| @@ -20,8 +20,7 @@ import org.springframework.web.bind.annotation.*; | @@ -20,8 +20,7 @@ import org.springframework.web.bind.annotation.*; | ||
| 20 | 20 | ||
| 21 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | 21 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 22 | 22 | ||
| 23 | -// TODO @芋艿:规则场景 要不要,统一改成 场景联动 | ||
| 24 | -@Tag(name = "管理后台 - IoT 规则场景") | 23 | +@Tag(name = "管理后台 - IoT 场景联动") |
| 25 | @RestController | 24 | @RestController |
| 26 | @RequestMapping("/iot/rule-scene") | 25 | @RequestMapping("/iot/rule-scene") |
| 27 | @Validated | 26 | @Validated |
| @@ -31,14 +30,14 @@ public class IotRuleSceneController { | @@ -31,14 +30,14 @@ public class IotRuleSceneController { | ||
| 31 | private IotRuleSceneService ruleSceneService; | 30 | private IotRuleSceneService ruleSceneService; |
| 32 | 31 | ||
| 33 | @PostMapping("/create") | 32 | @PostMapping("/create") |
| 34 | - @Operation(summary = "创建规则场景(场景联动)") | 33 | + @Operation(summary = "创建场景联动") |
| 35 | @PreAuthorize("@ss.hasPermission('iot:rule-scene:create')") | 34 | @PreAuthorize("@ss.hasPermission('iot:rule-scene:create')") |
| 36 | public CommonResult<Long> createRuleScene(@Valid @RequestBody IotRuleSceneSaveReqVO createReqVO) { | 35 | public CommonResult<Long> createRuleScene(@Valid @RequestBody IotRuleSceneSaveReqVO createReqVO) { |
| 37 | return success(ruleSceneService.createRuleScene(createReqVO)); | 36 | return success(ruleSceneService.createRuleScene(createReqVO)); |
| 38 | } | 37 | } |
| 39 | 38 | ||
| 40 | @PutMapping("/update") | 39 | @PutMapping("/update") |
| 41 | - @Operation(summary = "更新规则场景(场景联动)") | 40 | + @Operation(summary = "更新场景联动") |
| 42 | @PreAuthorize("@ss.hasPermission('iot:rule-scene:update')") | 41 | @PreAuthorize("@ss.hasPermission('iot:rule-scene:update')") |
| 43 | public CommonResult<Boolean> updateRuleScene(@Valid @RequestBody IotRuleSceneSaveReqVO updateReqVO) { | 42 | public CommonResult<Boolean> updateRuleScene(@Valid @RequestBody IotRuleSceneSaveReqVO updateReqVO) { |
| 44 | ruleSceneService.updateRuleScene(updateReqVO); | 43 | ruleSceneService.updateRuleScene(updateReqVO); |
| @@ -46,7 +45,7 @@ public class IotRuleSceneController { | @@ -46,7 +45,7 @@ public class IotRuleSceneController { | ||
| 46 | } | 45 | } |
| 47 | 46 | ||
| 48 | @DeleteMapping("/delete") | 47 | @DeleteMapping("/delete") |
| 49 | - @Operation(summary = "删除规则场景(场景联动)") | 48 | + @Operation(summary = "删除场景联动") |
| 50 | @Parameter(name = "id", description = "编号", required = true) | 49 | @Parameter(name = "id", description = "编号", required = true) |
| 51 | @PreAuthorize("@ss.hasPermission('iot:rule-scene:delete')") | 50 | @PreAuthorize("@ss.hasPermission('iot:rule-scene:delete')") |
| 52 | public CommonResult<Boolean> deleteRuleScene(@RequestParam("id") Long id) { | 51 | public CommonResult<Boolean> deleteRuleScene(@RequestParam("id") Long id) { |
| @@ -55,7 +54,7 @@ public class IotRuleSceneController { | @@ -55,7 +54,7 @@ public class IotRuleSceneController { | ||
| 55 | } | 54 | } |
| 56 | 55 | ||
| 57 | @GetMapping("/get") | 56 | @GetMapping("/get") |
| 58 | - @Operation(summary = "获得规则场景(场景联动)") | 57 | + @Operation(summary = "获得场景联动") |
| 59 | @Parameter(name = "id", description = "编号", required = true, example = "1024") | 58 | @Parameter(name = "id", description = "编号", required = true, example = "1024") |
| 60 | @PreAuthorize("@ss.hasPermission('iot:rule-scene:query')") | 59 | @PreAuthorize("@ss.hasPermission('iot:rule-scene:query')") |
| 61 | public CommonResult<IotRuleSceneRespVO> getRuleScene(@RequestParam("id") Long id) { | 60 | public CommonResult<IotRuleSceneRespVO> getRuleScene(@RequestParam("id") Long id) { |
| @@ -64,7 +63,7 @@ public class IotRuleSceneController { | @@ -64,7 +63,7 @@ public class IotRuleSceneController { | ||
| 64 | } | 63 | } |
| 65 | 64 | ||
| 66 | @GetMapping("/page") | 65 | @GetMapping("/page") |
| 67 | - @Operation(summary = "获得规则场景(场景联动)分页") | 66 | + @Operation(summary = "获得场景联动分页") |
| 68 | @PreAuthorize("@ss.hasPermission('iot:rule-scene:query')") | 67 | @PreAuthorize("@ss.hasPermission('iot:rule-scene:query')") |
| 69 | public CommonResult<PageResult<IotRuleSceneRespVO>> getRuleScenePage(@Valid IotRuleScenePageReqVO pageReqVO) { | 68 | public CommonResult<PageResult<IotRuleSceneRespVO>> getRuleScenePage(@Valid IotRuleScenePageReqVO pageReqVO) { |
| 70 | PageResult<IotRuleSceneDO> pageResult = ruleSceneService.getRuleScenePage(pageReqVO); | 69 | PageResult<IotRuleSceneDO> pageResult = ruleSceneService.getRuleScenePage(pageReqVO); |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/databridge/config/IotDataBridgeAbstractConfig.java
| @@ -18,7 +18,7 @@ import lombok.Data; | @@ -18,7 +18,7 @@ import lombok.Data; | ||
| 18 | @JsonSubTypes({ | 18 | @JsonSubTypes({ |
| 19 | @JsonSubTypes.Type(value = IotDataBridgeHttpConfig.class, name = "1"), | 19 | @JsonSubTypes.Type(value = IotDataBridgeHttpConfig.class, name = "1"), |
| 20 | @JsonSubTypes.Type(value = IotDataBridgeMqttConfig.class, name = "10"), | 20 | @JsonSubTypes.Type(value = IotDataBridgeMqttConfig.class, name = "10"), |
| 21 | - @JsonSubTypes.Type(value = IotDataBridgeRedisStreamMQConfig.class, name = "21"), | 21 | + @JsonSubTypes.Type(value = IotDataBridgeRedisStreamConfig.class, name = "21"), |
| 22 | @JsonSubTypes.Type(value = IotDataBridgeRocketMQConfig.class, name = "30"), | 22 | @JsonSubTypes.Type(value = IotDataBridgeRocketMQConfig.class, name = "30"), |
| 23 | @JsonSubTypes.Type(value = IotDataBridgeRabbitMQConfig.class, name = "31"), | 23 | @JsonSubTypes.Type(value = IotDataBridgeRabbitMQConfig.class, name = "31"), |
| 24 | @JsonSubTypes.Type(value = IotDataBridgeKafkaMQConfig.class, name = "32"), | 24 | @JsonSubTypes.Type(value = IotDataBridgeKafkaMQConfig.class, name = "32"), |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/databridge/config/IotDataBridgeRedisStreamMQConfig.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/databridge/config/IotDataBridgeRedisStreamConfig.java
| @@ -2,14 +2,13 @@ package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config; | @@ -2,14 +2,13 @@ package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config; | ||
| 2 | 2 | ||
| 3 | import lombok.Data; | 3 | import lombok.Data; |
| 4 | 4 | ||
| 5 | -// TODO @puhui999:MQ 可以去掉哈。stream 更精准 | ||
| 6 | /** | 5 | /** |
| 7 | * IoT Redis Stream 配置 {@link IotDataBridgeAbstractConfig} 实现类 | 6 | * IoT Redis Stream 配置 {@link IotDataBridgeAbstractConfig} 实现类 |
| 8 | * | 7 | * |
| 9 | * @author HUIHUI | 8 | * @author HUIHUI |
| 10 | */ | 9 | */ |
| 11 | @Data | 10 | @Data |
| 12 | -public class IotDataBridgeRedisStreamMQConfig extends IotDataBridgeAbstractConfig { | 11 | +public class IotDataBridgeRedisStreamConfig extends IotDataBridgeAbstractConfig { |
| 13 | 12 | ||
| 14 | /** | 13 | /** |
| 15 | * Redis 服务器地址 | 14 | * Redis 服务器地址 |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/package-info.java deleted
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/IotRuleScenePageReqVO.java
| @@ -13,7 +13,7 @@ import java.time.LocalDateTime; | @@ -13,7 +13,7 @@ import java.time.LocalDateTime; | ||
| 13 | 13 | ||
| 14 | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | 14 | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; |
| 15 | 15 | ||
| 16 | -@Schema(description = "管理后台 - IoT 规则场景(场景联动)分页 Request VO") | 16 | +@Schema(description = "管理后台 - IoT 场景联动分页 Request VO") |
| 17 | @Data | 17 | @Data |
| 18 | @EqualsAndHashCode(callSuper = true) | 18 | @EqualsAndHashCode(callSuper = true) |
| 19 | @ToString(callSuper = true) | 19 | @ToString(callSuper = true) |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/IotRuleSceneRespVO.java
| 1 | package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene; | 1 | package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config.IotRuleSceneActionConfig; | ||
| 4 | -import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config.IotRuleSceneTriggerConfig; | 3 | +import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; |
| 5 | import io.swagger.v3.oas.annotations.media.Schema; | 4 | import io.swagger.v3.oas.annotations.media.Schema; |
| 6 | import lombok.Data; | 5 | import lombok.Data; |
| 7 | 6 | ||
| 8 | import java.time.LocalDateTime; | 7 | import java.time.LocalDateTime; |
| 9 | import java.util.List; | 8 | import java.util.List; |
| 10 | 9 | ||
| 11 | -@Schema(description = "管理后台 - IoT 规则场景(场景联动) Response VO") | 10 | +@Schema(description = "管理后台 - IoT 场景联动 Response VO") |
| 12 | @Data | 11 | @Data |
| 13 | public class IotRuleSceneRespVO { | 12 | public class IotRuleSceneRespVO { |
| 14 | 13 | ||
| @@ -25,10 +24,10 @@ public class IotRuleSceneRespVO { | @@ -25,10 +24,10 @@ public class IotRuleSceneRespVO { | ||
| 25 | private Integer status; | 24 | private Integer status; |
| 26 | 25 | ||
| 27 | @Schema(description = "触发器数组", requiredMode = Schema.RequiredMode.REQUIRED) | 26 | @Schema(description = "触发器数组", requiredMode = Schema.RequiredMode.REQUIRED) |
| 28 | - private List<IotRuleSceneTriggerConfig> triggers; | 27 | + private List<IotRuleSceneDO.TriggerConfig> triggers; |
| 29 | 28 | ||
| 30 | @Schema(description = "执行器数组", requiredMode = Schema.RequiredMode.REQUIRED) | 29 | @Schema(description = "执行器数组", requiredMode = Schema.RequiredMode.REQUIRED) |
| 31 | - private List<IotRuleSceneActionConfig> actions; | 30 | + private List<IotRuleSceneDO.ActionConfig> actions; |
| 32 | 31 | ||
| 33 | @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) | 32 | @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) |
| 34 | private LocalDateTime createTime; | 33 | private LocalDateTime createTime; |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/IotRuleSceneSaveReqVO.java
| @@ -2,8 +2,7 @@ package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene; | @@ -2,8 +2,7 @@ package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | 3 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| 4 | import cn.iocoder.yudao.framework.common.validation.InEnum; | 4 | import cn.iocoder.yudao.framework.common.validation.InEnum; |
| 5 | -import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config.IotRuleSceneActionConfig; | ||
| 6 | -import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config.IotRuleSceneTriggerConfig; | 5 | +import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; |
| 7 | import io.swagger.v3.oas.annotations.media.Schema; | 6 | import io.swagger.v3.oas.annotations.media.Schema; |
| 8 | import jakarta.validation.constraints.NotEmpty; | 7 | import jakarta.validation.constraints.NotEmpty; |
| 9 | import jakarta.validation.constraints.NotNull; | 8 | import jakarta.validation.constraints.NotNull; |
| @@ -11,7 +10,7 @@ import lombok.Data; | @@ -11,7 +10,7 @@ import lombok.Data; | ||
| 11 | 10 | ||
| 12 | import java.util.List; | 11 | import java.util.List; |
| 13 | 12 | ||
| 14 | -@Schema(description = "管理后台 - IoT 规则场景(场景联动)新增/修改 Request VO") | 13 | +@Schema(description = "管理后台 - IoT 场景联动新增/修改 Request VO") |
| 15 | @Data | 14 | @Data |
| 16 | public class IotRuleSceneSaveReqVO { | 15 | public class IotRuleSceneSaveReqVO { |
| 17 | 16 | ||
| @@ -32,10 +31,10 @@ public class IotRuleSceneSaveReqVO { | @@ -32,10 +31,10 @@ public class IotRuleSceneSaveReqVO { | ||
| 32 | 31 | ||
| 33 | @Schema(description = "触发器数组", requiredMode = Schema.RequiredMode.REQUIRED) | 32 | @Schema(description = "触发器数组", requiredMode = Schema.RequiredMode.REQUIRED) |
| 34 | @NotEmpty(message = "触发器数组不能为空") | 33 | @NotEmpty(message = "触发器数组不能为空") |
| 35 | - private List<IotRuleSceneTriggerConfig> triggers; | 34 | + private List<IotRuleSceneDO.TriggerConfig> triggers; |
| 36 | 35 | ||
| 37 | @Schema(description = "执行器数组", requiredMode = Schema.RequiredMode.REQUIRED) | 36 | @Schema(description = "执行器数组", requiredMode = Schema.RequiredMode.REQUIRED) |
| 38 | @NotEmpty(message = "执行器数组不能为空") | 37 | @NotEmpty(message = "执行器数组不能为空") |
| 39 | - private List<IotRuleSceneActionConfig> actions; | 38 | + private List<IotRuleSceneDO.ActionConfig> actions; |
| 40 | 39 | ||
| 41 | } | 40 | } |
| 42 | \ No newline at end of file | 41 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/config/IotRuleSceneActionConfig.java deleted
| 1 | -package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; | ||
| 4 | -import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum; | ||
| 5 | -import lombok.Data; | ||
| 6 | - | ||
| 7 | -// TODO @puhui999:这个要不内嵌到 IoTRuleSceneDO 里面? | ||
| 8 | -/** | ||
| 9 | - * 执行器配置 | ||
| 10 | - * | ||
| 11 | - * @author 芋道源码 | ||
| 12 | - */ | ||
| 13 | -@Data | ||
| 14 | -public class IotRuleSceneActionConfig { | ||
| 15 | - | ||
| 16 | - /** | ||
| 17 | - * 执行类型 | ||
| 18 | - * | ||
| 19 | - * 枚举 {@link IotRuleSceneActionTypeEnum} | ||
| 20 | - */ | ||
| 21 | - private Integer type; | ||
| 22 | - | ||
| 23 | - /** | ||
| 24 | - * 设备控制 | ||
| 25 | - * | ||
| 26 | - * 必填:当 {@link #type} 为 {@link IotRuleSceneActionTypeEnum#DEVICE_CONTROL} 时 | ||
| 27 | - */ | ||
| 28 | - private IotRuleSceneActionDeviceControl deviceControl; | ||
| 29 | - | ||
| 30 | - /** | ||
| 31 | - * 数据桥接编号 | ||
| 32 | - * | ||
| 33 | - * 必填:当 {@link #type} 为 {@link IotRuleSceneActionTypeEnum#DATA_BRIDGE} 时 | ||
| 34 | - * 关联:{@link IotDataBridgeDO#getId()} | ||
| 35 | - */ | ||
| 36 | - private Long dataBridgeId; | ||
| 37 | - | ||
| 38 | -} | ||
| 39 | \ No newline at end of file | 0 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/config/IotRuleSceneActionDeviceControl.java deleted
| 1 | -package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | ||
| 4 | -import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; | ||
| 5 | -import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum; | ||
| 6 | -import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum; | ||
| 7 | -import lombok.Data; | ||
| 8 | - | ||
| 9 | -import java.util.List; | ||
| 10 | -import java.util.Map; | ||
| 11 | - | ||
| 12 | -// TODO @puhui999:这个要不内嵌到 IoTRuleSceneDO 里面? | ||
| 13 | -/** | ||
| 14 | - * 执行设备控制 | ||
| 15 | - * | ||
| 16 | - * @author 芋道源码 | ||
| 17 | - */ | ||
| 18 | -@Data | ||
| 19 | -public class IotRuleSceneActionDeviceControl { | ||
| 20 | - | ||
| 21 | - /** | ||
| 22 | - * 产品标识 | ||
| 23 | - * | ||
| 24 | - * 关联 {@link IotProductDO#getProductKey()} | ||
| 25 | - */ | ||
| 26 | - private String productKey; | ||
| 27 | - /** | ||
| 28 | - * 设备名称数组 | ||
| 29 | - * | ||
| 30 | - * 关联 {@link IotDeviceDO#getDeviceName()} | ||
| 31 | - */ | ||
| 32 | - private List<String> deviceNames; | ||
| 33 | - | ||
| 34 | - /** | ||
| 35 | - * 消息类型 | ||
| 36 | - * | ||
| 37 | - * 枚举 {@link IotDeviceMessageTypeEnum#PROPERTY}、{@link IotDeviceMessageTypeEnum#SERVICE} | ||
| 38 | - */ | ||
| 39 | - private String type; | ||
| 40 | - /** | ||
| 41 | - * 消息标识符 | ||
| 42 | - * | ||
| 43 | - * 枚举 {@link IotDeviceMessageIdentifierEnum} | ||
| 44 | - * | ||
| 45 | - * 1. 属性设置:对应 {@link IotDeviceMessageIdentifierEnum#PROPERTY_SET} | ||
| 46 | - * 2. 服务调用:对应 {@link IotDeviceMessageIdentifierEnum#SERVICE_INVOKE} | ||
| 47 | - */ | ||
| 48 | - private String identifier; | ||
| 49 | - | ||
| 50 | - /** | ||
| 51 | - * 具体数据 | ||
| 52 | - * | ||
| 53 | - * 1. 属性设置:在 {@link #type} 是 {@link IotDeviceMessageTypeEnum#PROPERTY} 时,对应 properties | ||
| 54 | - * 2. 服务调用:在 {@link #type} 是 {@link IotDeviceMessageTypeEnum#SERVICE} 时,对应 params | ||
| 55 | - */ | ||
| 56 | - private Map<String, Object> data; | ||
| 57 | - | ||
| 58 | -} | ||
| 59 | \ No newline at end of file | 0 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/config/IotRuleSceneTriggerCondition.java deleted
| 1 | -package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum; | ||
| 4 | -import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum; | ||
| 5 | -import lombok.Data; | ||
| 6 | - | ||
| 7 | -import java.util.List; | ||
| 8 | - | ||
| 9 | -// TODO @puhui999:这个要不内嵌到 IoTRuleSceneDO 里面? | ||
| 10 | -/** | ||
| 11 | - * 触发条件 | ||
| 12 | - * | ||
| 13 | - * @author 芋道源码 | ||
| 14 | - */ | ||
| 15 | -@Data | ||
| 16 | -public class IotRuleSceneTriggerCondition { | ||
| 17 | - | ||
| 18 | - /** | ||
| 19 | - * 消息类型 | ||
| 20 | - * | ||
| 21 | - * 枚举 {@link IotDeviceMessageTypeEnum} | ||
| 22 | - */ | ||
| 23 | - private String type; | ||
| 24 | - /** | ||
| 25 | - * 消息标识符 | ||
| 26 | - * | ||
| 27 | - * 枚举 {@link IotDeviceMessageIdentifierEnum} | ||
| 28 | - */ | ||
| 29 | - private String identifier; | ||
| 30 | - | ||
| 31 | - /** | ||
| 32 | - * 参数数组 | ||
| 33 | - * | ||
| 34 | - * 参数与参数之间,是“或”的关系 | ||
| 35 | - */ | ||
| 36 | - private List<IotRuleSceneTriggerConditionParameter> parameters; | ||
| 37 | - | ||
| 38 | -} | ||
| 39 | \ No newline at end of file | 0 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/config/IotRuleSceneTriggerConditionParameter.java deleted
| 1 | -package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; | ||
| 4 | -import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneTriggerConditionParameterOperatorEnum; | ||
| 5 | -import lombok.Data; | ||
| 6 | - | ||
| 7 | -// TODO @puhui999:这个要不内嵌到 IoTRuleSceneDO 里面? | ||
| 8 | -/** | ||
| 9 | - * 触发条件参数 | ||
| 10 | - * | ||
| 11 | - * @author 芋道源码 | ||
| 12 | - */ | ||
| 13 | -@Data | ||
| 14 | -public class IotRuleSceneTriggerConditionParameter { | ||
| 15 | - | ||
| 16 | - /** | ||
| 17 | - * 标识符(属性、事件、服务) | ||
| 18 | - * | ||
| 19 | - * 关联 {@link IotThingModelDO#getIdentifier()} | ||
| 20 | - */ | ||
| 21 | - private String identifier; | ||
| 22 | - | ||
| 23 | - /** | ||
| 24 | - * 操作符 | ||
| 25 | - * | ||
| 26 | - * 枚举 {@link IotRuleSceneTriggerConditionParameterOperatorEnum} | ||
| 27 | - */ | ||
| 28 | - private String operator; | ||
| 29 | - | ||
| 30 | - /** | ||
| 31 | - * 比较值 | ||
| 32 | - * | ||
| 33 | - * 如果有多个值,则使用 "," 分隔,类似 "1,2,3"。 | ||
| 34 | - * 例如说,{@link IotRuleSceneTriggerConditionParameterOperatorEnum#IN}、{@link IotRuleSceneTriggerConditionParameterOperatorEnum#BETWEEN} | ||
| 35 | - */ | ||
| 36 | - private String value; | ||
| 37 | - | ||
| 38 | -} | ||
| 39 | \ No newline at end of file | 0 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/config/IotRuleSceneTriggerConfig.java deleted
| 1 | -package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | ||
| 4 | -import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; | ||
| 5 | -import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneTriggerTypeEnum; | ||
| 6 | -import lombok.Data; | ||
| 7 | - | ||
| 8 | -import java.util.List; | ||
| 9 | - | ||
| 10 | -// TODO @puhui999:这个要不内嵌到 IoTRuleSceneDO 里面? | ||
| 11 | -/** | ||
| 12 | - * 触发器配置 | ||
| 13 | - * | ||
| 14 | - * @author 芋道源码 | ||
| 15 | - */ | ||
| 16 | -@Data | ||
| 17 | -public class IotRuleSceneTriggerConfig { | ||
| 18 | - | ||
| 19 | - /** | ||
| 20 | - * 触发类型 | ||
| 21 | - * | ||
| 22 | - * 枚举 {@link IotRuleSceneTriggerTypeEnum} | ||
| 23 | - */ | ||
| 24 | - private Integer type; | ||
| 25 | - | ||
| 26 | - /** | ||
| 27 | - * 产品标识 | ||
| 28 | - * | ||
| 29 | - * 关联 {@link IotProductDO#getProductKey()} | ||
| 30 | - */ | ||
| 31 | - private String productKey; | ||
| 32 | - /** | ||
| 33 | - * 设备名称数组 | ||
| 34 | - * | ||
| 35 | - * 关联 {@link IotDeviceDO#getDeviceName()} | ||
| 36 | - */ | ||
| 37 | - private List<String> deviceNames; | ||
| 38 | - | ||
| 39 | - /** | ||
| 40 | - * 触发条件数组 | ||
| 41 | - * | ||
| 42 | - * 必填:当 {@link #type} 为 {@link IotRuleSceneTriggerTypeEnum#DEVICE} 时 | ||
| 43 | - * 条件与条件之间,是“或”的关系 | ||
| 44 | - */ | ||
| 45 | - private List<IotRuleSceneTriggerCondition> conditions; | ||
| 46 | - | ||
| 47 | - /** | ||
| 48 | - * CRON 表达式 | ||
| 49 | - * | ||
| 50 | - * 必填:当 {@link #type} 为 {@link IotRuleSceneTriggerTypeEnum#TIMER} 时 | ||
| 51 | - */ | ||
| 52 | - private String cronExpression; | ||
| 53 | - | ||
| 54 | -} | ||
| 55 | \ No newline at end of file | 0 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/IotThingModelController.http
| @@ -174,7 +174,7 @@ GET {{baseUrl}}/iot/product-thing-model/get?id=67 | @@ -174,7 +174,7 @@ GET {{baseUrl}}/iot/product-thing-model/get?id=67 | ||
| 174 | tenant-id: {{adminTenentId}} | 174 | tenant-id: {{adminTenentId}} |
| 175 | Authorization: Bearer {{token}} | 175 | Authorization: Bearer {{token}} |
| 176 | 176 | ||
| 177 | -### 请求 /iot/product-thing-model/tsl-by-product-id 接口 => 成功 | ||
| 178 | -GET {{baseUrl}}/iot/product-thing-model/tsl-by-product-id?productId=1001 | 177 | +### 请求 /iot/product-thing-model/get-tsl 接口 => 成功 |
| 178 | +GET {{baseUrl}}/iot/product-thing-model/get-tsl?productId=1001 | ||
| 179 | tenant-id: {{adminTenentId}} | 179 | tenant-id: {{adminTenentId}} |
| 180 | Authorization: Bearer {{token}} | 180 | Authorization: Bearer {{token}} |
| 181 | \ No newline at end of file | 181 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/IotThingModelController.java
| 1 | package cn.iocoder.yudao.module.iot.controller.admin.thingmodel; | 1 | package cn.iocoder.yudao.module.iot.controller.admin.thingmodel; |
| 2 | 2 | ||
| 3 | +import cn.hutool.core.collection.CollUtil; | ||
| 4 | +import cn.hutool.core.util.ObjUtil; | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 5 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 6 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | 7 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 6 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.*; | 8 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.*; |
| 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; | 9 | import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; |
| 10 | +import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelTypeEnum; | ||
| 8 | import cn.iocoder.yudao.module.iot.service.thingmodel.IotThingModelService; | 11 | import cn.iocoder.yudao.module.iot.service.thingmodel.IotThingModelService; |
| 9 | import io.swagger.v3.oas.annotations.Operation; | 12 | import io.swagger.v3.oas.annotations.Operation; |
| 10 | import io.swagger.v3.oas.annotations.Parameter; | 13 | import io.swagger.v3.oas.annotations.Parameter; |
| @@ -18,6 +21,8 @@ import org.springframework.web.bind.annotation.*; | @@ -18,6 +21,8 @@ import org.springframework.web.bind.annotation.*; | ||
| 18 | import java.util.List; | 21 | import java.util.List; |
| 19 | 22 | ||
| 20 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | 23 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 24 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; | ||
| 25 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList; | ||
| 21 | 26 | ||
| 22 | @Tag(name = "管理后台 - IoT 产品物模型") | 27 | @Tag(name = "管理后台 - IoT 产品物模型") |
| 23 | @RestController | 28 | @RestController |
| @@ -61,13 +66,31 @@ public class IotThingModelController { | @@ -61,13 +66,31 @@ public class IotThingModelController { | ||
| 61 | return success(BeanUtils.toBean(thingModel, IotThingModelRespVO.class)); | 66 | return success(BeanUtils.toBean(thingModel, IotThingModelRespVO.class)); |
| 62 | } | 67 | } |
| 63 | 68 | ||
| 64 | - // TODO @puhui999:要不叫 get-tsl,去掉 product-id;后续,把 | ||
| 65 | - @GetMapping("/tsl-by-product-id") | 69 | + @GetMapping("/get-tsl") |
| 66 | @Operation(summary = "获得产品物模型 TSL") | 70 | @Operation(summary = "获得产品物模型 TSL") |
| 67 | @Parameter(name = "productId", description = "产品 ID", required = true, example = "1024") | 71 | @Parameter(name = "productId", description = "产品 ID", required = true, example = "1024") |
| 68 | @PreAuthorize("@ss.hasPermission('iot:thing-model:query')") | 72 | @PreAuthorize("@ss.hasPermission('iot:thing-model:query')") |
| 69 | - public CommonResult<IotThingModelTSLRespVO> getThingModelTslByProductId(@RequestParam("productId") Long productId) { | ||
| 70 | - return success(thingModelService.getThingModelTslByProductId(productId)); | 73 | + public CommonResult<IotThingModelTSLRespVO> getThingModelTsl(@RequestParam("productId") Long productId) { |
| 74 | + IotThingModelTSLRespVO tslRespVO = new IotThingModelTSLRespVO(); | ||
| 75 | + // 1. 获得产品所有物模型定义 | ||
| 76 | + List<IotThingModelDO> thingModels = thingModelService.getThingModelListByProductId(productId); | ||
| 77 | + if (CollUtil.isEmpty(thingModels)) { | ||
| 78 | + return success(tslRespVO); | ||
| 79 | + } | ||
| 80 | + | ||
| 81 | + // 2.1 设置公共部分参数 | ||
| 82 | + IotThingModelDO thingModel = thingModels.get(0); | ||
| 83 | + tslRespVO.setProductId(thingModel.getProductId()).setProductKey(thingModel.getProductKey()); | ||
| 84 | + // 2.2 处理属性列表 | ||
| 85 | + tslRespVO.setProperties(convertList(filterList(thingModels, item -> | ||
| 86 | + ObjUtil.equal(IotThingModelTypeEnum.PROPERTY.getType(), item.getType())), IotThingModelDO::getProperty)); | ||
| 87 | + // 2.3 处理服务列表 | ||
| 88 | + tslRespVO.setServices(convertList(filterList(thingModels, item -> | ||
| 89 | + ObjUtil.equal(IotThingModelTypeEnum.SERVICE.getType(), item.getType())), IotThingModelDO::getService)); | ||
| 90 | + // 2.4 处理事件列表 | ||
| 91 | + tslRespVO.setEvents(convertList(filterList(thingModels, item -> | ||
| 92 | + ObjUtil.equal(IotThingModelTypeEnum.EVENT.getType(), item.getType())), IotThingModelDO::getEvent)); | ||
| 93 | + return success(tslRespVO); | ||
| 71 | } | 94 | } |
| 72 | 95 | ||
| 73 | @GetMapping("/list") | 96 | @GetMapping("/list") |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/dataType/ThingModelArrayDataSpecs.java
| 1 | package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType; | 1 | package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType; |
| 2 | 2 | ||
| 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
| 4 | +import jakarta.validation.Valid; | ||
| 5 | +import jakarta.validation.constraints.NotEmpty; | ||
| 6 | +import jakarta.validation.constraints.NotNull; | ||
| 7 | +import jakarta.validation.constraints.Pattern; | ||
| 4 | import lombok.Data; | 8 | import lombok.Data; |
| 5 | import lombok.EqualsAndHashCode; | 9 | import lombok.EqualsAndHashCode; |
| 6 | 10 | ||
| @@ -16,18 +20,17 @@ import java.util.List; | @@ -16,18 +20,17 @@ import java.util.List; | ||
| 16 | @JsonIgnoreProperties({"dataType"}) // 忽略子类中的 dataType 字段,从而避免重复 | 20 | @JsonIgnoreProperties({"dataType"}) // 忽略子类中的 dataType 字段,从而避免重复 |
| 17 | public class ThingModelArrayDataSpecs extends ThingModelDataSpecs { | 21 | public class ThingModelArrayDataSpecs extends ThingModelDataSpecs { |
| 18 | 22 | ||
| 19 | - /** | ||
| 20 | - * 数组中的元素个数 | ||
| 21 | - */ | 23 | + @NotNull(message = "数组元素个数不能为空") |
| 22 | private Integer size; | 24 | private Integer size; |
| 23 | - /** | ||
| 24 | - * 数组中的元素的数据类型。可选值:struct、int、float、double 或 text | ||
| 25 | - */ | 25 | + |
| 26 | + @NotEmpty(message = "数组元素的数据类型不能为空") | ||
| 27 | + @Pattern(regexp = "^(struct|int|float|double|text)$", message = "数组元素的数据类型必须为:struct、int、float、double 或 text") | ||
| 26 | private String childDataType; | 28 | private String childDataType; |
| 27 | /** | 29 | /** |
| 28 | * 数据类型(childDataType)为列表型 struct 的数据规范存储在 dataSpecsList 中 | 30 | * 数据类型(childDataType)为列表型 struct 的数据规范存储在 dataSpecsList 中 |
| 29 | * 此时 struct 取值范围为:int、float、double、text、date、enum、bool | 31 | * 此时 struct 取值范围为:int、float、double、text、date、enum、bool |
| 30 | */ | 32 | */ |
| 33 | + @Valid | ||
| 31 | private List<ThingModelDataSpecs> dataSpecsList; | 34 | private List<ThingModelDataSpecs> dataSpecsList; |
| 32 | 35 | ||
| 33 | } | 36 | } |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/dataType/ThingModelBoolOrEnumDataSpecs.java
| 1 | package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType; | 1 | package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType; |
| 2 | 2 | ||
| 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
| 4 | +import jakarta.validation.constraints.NotEmpty; | ||
| 5 | +import jakarta.validation.constraints.NotNull; | ||
| 6 | +import jakarta.validation.constraints.Pattern; | ||
| 4 | import lombok.Data; | 7 | import lombok.Data; |
| 5 | import lombok.EqualsAndHashCode; | 8 | import lombok.EqualsAndHashCode; |
| 6 | 9 | ||
| @@ -16,16 +19,12 @@ import lombok.EqualsAndHashCode; | @@ -16,16 +19,12 @@ import lombok.EqualsAndHashCode; | ||
| 16 | @JsonIgnoreProperties({"dataType"}) // 忽略子类中的 dataType 字段,从而避免重复 | 19 | @JsonIgnoreProperties({"dataType"}) // 忽略子类中的 dataType 字段,从而避免重复 |
| 17 | public class ThingModelBoolOrEnumDataSpecs extends ThingModelDataSpecs { | 20 | public class ThingModelBoolOrEnumDataSpecs extends ThingModelDataSpecs { |
| 18 | 21 | ||
| 19 | - // TODO @puhui999:要不写下参数校验?这样,注释可以简洁一点 | ||
| 20 | - /** | ||
| 21 | - * 枚举项的名称。 | ||
| 22 | - * 可包含中文、大小写英文字母、数字、下划线(_)和短划线(-) | ||
| 23 | - * 必须以中文、英文字母或数字开头,长度不超过 20 个字符 | ||
| 24 | - */ | 22 | + @NotEmpty(message = "枚举项的名称不能为空") |
| 23 | + @Pattern(regexp = "^[\\u4e00-\\u9fa5a-zA-Z0-9][\\u4e00-\\u9fa5a-zA-Z0-9_-]{0,19}$", | ||
| 24 | + message = "枚举项的名称只能包含中文、大小写英文字母、数字、下划线和短划线,必须以中文、英文字母或数字开头,长度不超过 20 个字符") | ||
| 25 | private String name; | 25 | private String name; |
| 26 | - /** | ||
| 27 | - * 枚举值。 | ||
| 28 | - */ | 26 | + |
| 27 | + @NotNull(message = "枚举值不能为空") | ||
| 29 | private Integer value; | 28 | private Integer value; |
| 30 | 29 | ||
| 31 | } | 30 | } |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/dataType/ThingModelDateOrTextDataSpecs.java
| 1 | package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType; | 1 | package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType; |
| 2 | 2 | ||
| 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
| 4 | +import jakarta.validation.constraints.Max; | ||
| 4 | import lombok.Data; | 5 | import lombok.Data; |
| 5 | import lombok.EqualsAndHashCode; | 6 | import lombok.EqualsAndHashCode; |
| 6 | 7 | ||
| @@ -20,6 +21,7 @@ public class ThingModelDateOrTextDataSpecs extends ThingModelDataSpecs { | @@ -20,6 +21,7 @@ public class ThingModelDateOrTextDataSpecs extends ThingModelDataSpecs { | ||
| 20 | * 数据长度,单位为字节。取值不能超过 2048。 | 21 | * 数据长度,单位为字节。取值不能超过 2048。 |
| 21 | * 当 dataType 为 text 时,需传入该参数。 | 22 | * 当 dataType 为 text 时,需传入该参数。 |
| 22 | */ | 23 | */ |
| 24 | + @Max(value = 2048, message = "数据长度不能超过 2048") | ||
| 23 | private Integer length; | 25 | private Integer length; |
| 24 | /** | 26 | /** |
| 25 | * 默认值,可选参数,用于存储默认值。 | 27 | * 默认值,可选参数,用于存储默认值。 |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/dataType/ThingModelNumericDataSpec.java
| 1 | package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType; | 1 | package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType; |
| 2 | 2 | ||
| 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
| 4 | +import jakarta.validation.constraints.NotEmpty; | ||
| 5 | +import jakarta.validation.constraints.Pattern; | ||
| 4 | import lombok.Data; | 6 | import lombok.Data; |
| 5 | import lombok.EqualsAndHashCode; | 7 | import lombok.EqualsAndHashCode; |
| 6 | 8 | ||
| @@ -18,18 +20,21 @@ public class ThingModelNumericDataSpec extends ThingModelDataSpecs { | @@ -18,18 +20,21 @@ public class ThingModelNumericDataSpec extends ThingModelDataSpecs { | ||
| 18 | 20 | ||
| 19 | /** | 21 | /** |
| 20 | * 最大值,需转为字符串类型。值必须与 dataType 类型一致。 | 22 | * 最大值,需转为字符串类型。值必须与 dataType 类型一致。 |
| 21 | - * 例如,当 dataType 为 int 时,取值为 "200",而不是 200。 | ||
| 22 | */ | 23 | */ |
| 24 | + @NotEmpty(message = "最大值不能为空") | ||
| 25 | + @Pattern(regexp = "^-?\\d+(\\.\\d+)?$", message = "最大值必须为数值类型") | ||
| 23 | private String max; | 26 | private String max; |
| 24 | /** | 27 | /** |
| 25 | * 最小值,需转为字符串类型。值必须与 dataType 类型一致。 | 28 | * 最小值,需转为字符串类型。值必须与 dataType 类型一致。 |
| 26 | - * 例如,当 dataType 为 int 时,取值为 "0",而不是 0。 | ||
| 27 | */ | 29 | */ |
| 30 | + @NotEmpty(message = "最小值不能为空") | ||
| 31 | + @Pattern(regexp = "^-?\\d+(\\.\\d+)?$", message = "最小值必须为数值类型") | ||
| 28 | private String min; | 32 | private String min; |
| 29 | /** | 33 | /** |
| 30 | * 步长,需转为字符串类型。值必须与 dataType 类型一致。 | 34 | * 步长,需转为字符串类型。值必须与 dataType 类型一致。 |
| 31 | - * 例如,当 dataType 为 int 时,取值为 "10",而不是 10。 | ||
| 32 | */ | 35 | */ |
| 36 | + @NotEmpty(message = "步长不能为空") | ||
| 37 | + @Pattern(regexp = "^-?\\d+(\\.\\d+)?$", message = "步长必须为数值类型") | ||
| 33 | private String step; | 38 | private String step; |
| 34 | /** | 39 | /** |
| 35 | * 精度。当 dataType 为 float 或 double 时可选传入。 | 40 | * 精度。当 dataType 为 float 或 double 时可选传入。 |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/model/dataType/ThingModelStructDataSpecs.java
| 1 | package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType; | 1 | package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.framework.common.validation.InEnum; | ||
| 3 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelAccessModeEnum; | 4 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelAccessModeEnum; |
| 4 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | 5 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
| 6 | +import jakarta.validation.Valid; | ||
| 7 | +import jakarta.validation.constraints.NotEmpty; | ||
| 8 | +import jakarta.validation.constraints.Pattern; | ||
| 5 | import lombok.Data; | 9 | import lombok.Data; |
| 6 | import lombok.EqualsAndHashCode; | 10 | import lombok.EqualsAndHashCode; |
| 7 | 11 | ||
| @@ -17,35 +21,36 @@ import java.util.List; | @@ -17,35 +21,36 @@ import java.util.List; | ||
| 17 | @JsonIgnoreProperties({"dataType"}) // 忽略子类中的 dataType 字段,从而避免重复 | 21 | @JsonIgnoreProperties({"dataType"}) // 忽略子类中的 dataType 字段,从而避免重复 |
| 18 | public class ThingModelStructDataSpecs extends ThingModelDataSpecs { | 22 | public class ThingModelStructDataSpecs extends ThingModelDataSpecs { |
| 19 | 23 | ||
| 20 | - /** | ||
| 21 | - * 属性标识符 | ||
| 22 | - */ | 24 | + @NotEmpty(message = "属性标识符不能为空") |
| 25 | + @Pattern(regexp = "^[a-zA-Z][a-zA-Z0-9_]{0,31}$", message = "属性标识符只能由字母、数字和下划线组成,必须以字母开头,长度不超过 32 个字符") | ||
| 23 | private String identifier; | 26 | private String identifier; |
| 24 | - /** | ||
| 25 | - * 属性名称 | ||
| 26 | - */ | 27 | + |
| 28 | + @NotEmpty(message = "属性名称不能为空") | ||
| 27 | private String name; | 29 | private String name; |
| 28 | - /** | ||
| 29 | - * 云端可以对该属性进行的操作类型 | ||
| 30 | - * | ||
| 31 | - * 枚举 {@link IotThingModelAccessModeEnum} | ||
| 32 | - */ | 30 | + |
| 31 | + @NotEmpty(message = "操作类型不能为空") | ||
| 32 | + @InEnum(IotThingModelAccessModeEnum.class) | ||
| 33 | private String accessMode; | 33 | private String accessMode; |
| 34 | + | ||
| 34 | /** | 35 | /** |
| 35 | * 是否是标准品类的必选服务 | 36 | * 是否是标准品类的必选服务 |
| 36 | */ | 37 | */ |
| 37 | private Boolean required; | 38 | private Boolean required; |
| 38 | - /** | ||
| 39 | - * struct 数据的数据类型 | ||
| 40 | - */ | 39 | + |
| 40 | + @NotEmpty(message = "数据类型不能为空") | ||
| 41 | + @Pattern(regexp = "^(int|float|double|text|date|enum|bool)$", message = "数据类型必须为:int、float、double、text、date、enum、bool") | ||
| 41 | private String childDataType; | 42 | private String childDataType; |
| 43 | + | ||
| 42 | /** | 44 | /** |
| 43 | * 数据类型(dataType)为非列表型(int、float、double、text、date、array)的数据规范存储在 dataSpecs 中 | 45 | * 数据类型(dataType)为非列表型(int、float、double、text、date、array)的数据规范存储在 dataSpecs 中 |
| 44 | */ | 46 | */ |
| 47 | + @Valid | ||
| 45 | private ThingModelDataSpecs dataSpecs; | 48 | private ThingModelDataSpecs dataSpecs; |
| 49 | + | ||
| 46 | /** | 50 | /** |
| 47 | * 数据类型(dataType)为列表型(enum、bool、struct)的数据规范存储在 dataSpecsList 中 | 51 | * 数据类型(dataType)为列表型(enum、bool、struct)的数据规范存储在 dataSpecsList 中 |
| 48 | */ | 52 | */ |
| 53 | + @Valid | ||
| 49 | private List<ThingModelDataSpecs> dataSpecsList; | 54 | private List<ThingModelDataSpecs> dataSpecsList; |
| 50 | 55 | ||
| 51 | } | 56 | } |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/rule/IotRuleSceneDO.java
| 1 | package cn.iocoder.yudao.module.iot.dal.dataobject.rule; | 1 | package cn.iocoder.yudao.module.iot.dal.dataobject.rule; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; | 3 | import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; |
| 4 | -import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config.IotRuleSceneActionConfig; | ||
| 5 | -import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config.IotRuleSceneTriggerConfig; | 4 | +import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 5 | +import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; | ||
| 6 | +import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; | ||
| 7 | +import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum; | ||
| 8 | +import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum; | ||
| 9 | +import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum; | ||
| 10 | +import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneTriggerConditionParameterOperatorEnum; | ||
| 11 | +import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneTriggerTypeEnum; | ||
| 6 | import com.baomidou.mybatisplus.annotation.KeySequence; | 12 | import com.baomidou.mybatisplus.annotation.KeySequence; |
| 7 | import com.baomidou.mybatisplus.annotation.TableField; | 13 | import com.baomidou.mybatisplus.annotation.TableField; |
| 8 | import com.baomidou.mybatisplus.annotation.TableId; | 14 | import com.baomidou.mybatisplus.annotation.TableId; |
| @@ -14,13 +20,14 @@ import lombok.Data; | @@ -14,13 +20,14 @@ import lombok.Data; | ||
| 14 | import lombok.NoArgsConstructor; | 20 | import lombok.NoArgsConstructor; |
| 15 | 21 | ||
| 16 | import java.util.List; | 22 | import java.util.List; |
| 23 | +import java.util.Map; | ||
| 17 | 24 | ||
| 18 | /** | 25 | /** |
| 19 | - * IoT 规则场景(场景联动) DO | 26 | + * IoT 场景联动 DO |
| 20 | * | 27 | * |
| 21 | * @author 芋道源码 | 28 | * @author 芋道源码 |
| 22 | */ | 29 | */ |
| 23 | -@TableName("iot_rule_scene") | 30 | +@TableName(value = "iot_rule_scene", autoResultMap = true) |
| 24 | @KeySequence("iot_rule_scene_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 | 31 | @KeySequence("iot_rule_scene_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 |
| 25 | @Data | 32 | @Data |
| 26 | @Builder | 33 | @Builder |
| @@ -52,12 +59,188 @@ public class IotRuleSceneDO extends TenantBaseDO { | @@ -52,12 +59,188 @@ public class IotRuleSceneDO extends TenantBaseDO { | ||
| 52 | * 触发器数组 | 59 | * 触发器数组 |
| 53 | */ | 60 | */ |
| 54 | @TableField(typeHandler = JacksonTypeHandler.class) | 61 | @TableField(typeHandler = JacksonTypeHandler.class) |
| 55 | - private List<IotRuleSceneTriggerConfig> triggers; | 62 | + private List<TriggerConfig> triggers; |
| 56 | 63 | ||
| 57 | /** | 64 | /** |
| 58 | * 执行器数组 | 65 | * 执行器数组 |
| 59 | */ | 66 | */ |
| 60 | @TableField(typeHandler = JacksonTypeHandler.class) | 67 | @TableField(typeHandler = JacksonTypeHandler.class) |
| 61 | - private List<IotRuleSceneActionConfig> actions; | 68 | + private List<ActionConfig> actions; |
| 69 | + | ||
| 70 | + /** | ||
| 71 | + * 触发器配置 | ||
| 72 | + */ | ||
| 73 | + @Data | ||
| 74 | + public static class TriggerConfig { | ||
| 75 | + | ||
| 76 | + /** | ||
| 77 | + * 触发类型 | ||
| 78 | + * | ||
| 79 | + * 枚举 {@link IotRuleSceneTriggerTypeEnum} | ||
| 80 | + */ | ||
| 81 | + private Integer type; | ||
| 82 | + | ||
| 83 | + /** | ||
| 84 | + * 产品标识 | ||
| 85 | + * | ||
| 86 | + * 关联 {@link IotProductDO#getProductKey()} | ||
| 87 | + */ | ||
| 88 | + private String productKey; | ||
| 89 | + /** | ||
| 90 | + * 设备名称数组 | ||
| 91 | + * | ||
| 92 | + * 关联 {@link IotDeviceDO#getDeviceName()} | ||
| 93 | + */ | ||
| 94 | + private List<String> deviceNames; | ||
| 95 | + | ||
| 96 | + /** | ||
| 97 | + * 触发条件数组 | ||
| 98 | + * | ||
| 99 | + * 必填:当 {@link #type} 为 {@link IotRuleSceneTriggerTypeEnum#DEVICE} 时 | ||
| 100 | + * 条件与条件之间,是“或”的关系 | ||
| 101 | + */ | ||
| 102 | + private List<TriggerCondition> conditions; | ||
| 103 | + | ||
| 104 | + /** | ||
| 105 | + * CRON 表达式 | ||
| 106 | + * | ||
| 107 | + * 必填:当 {@link #type} 为 {@link IotRuleSceneTriggerTypeEnum#TIMER} 时 | ||
| 108 | + */ | ||
| 109 | + private String cronExpression; | ||
| 110 | + | ||
| 111 | + } | ||
| 112 | + | ||
| 113 | + /** | ||
| 114 | + * 触发条件 | ||
| 115 | + */ | ||
| 116 | + @Data | ||
| 117 | + public static class TriggerCondition { | ||
| 118 | + | ||
| 119 | + /** | ||
| 120 | + * 消息类型 | ||
| 121 | + * | ||
| 122 | + * 枚举 {@link IotDeviceMessageTypeEnum} | ||
| 123 | + */ | ||
| 124 | + private String type; | ||
| 125 | + /** | ||
| 126 | + * 消息标识符 | ||
| 127 | + * | ||
| 128 | + * 枚举 {@link IotDeviceMessageIdentifierEnum} | ||
| 129 | + */ | ||
| 130 | + private String identifier; | ||
| 131 | + | ||
| 132 | + /** | ||
| 133 | + * 参数数组 | ||
| 134 | + * | ||
| 135 | + * 参数与参数之间,是“或”的关系 | ||
| 136 | + */ | ||
| 137 | + private List<TriggerConditionParameter> parameters; | ||
| 138 | + | ||
| 139 | + } | ||
| 140 | + | ||
| 141 | + /** | ||
| 142 | + * 触发条件参数 | ||
| 143 | + */ | ||
| 144 | + @Data | ||
| 145 | + public static class TriggerConditionParameter { | ||
| 146 | + | ||
| 147 | + /** | ||
| 148 | + * 标识符(属性、事件、服务) | ||
| 149 | + * | ||
| 150 | + * 关联 {@link IotThingModelDO#getIdentifier()} | ||
| 151 | + */ | ||
| 152 | + private String identifier; | ||
| 153 | + | ||
| 154 | + /** | ||
| 155 | + * 操作符 | ||
| 156 | + * | ||
| 157 | + * 枚举 {@link IotRuleSceneTriggerConditionParameterOperatorEnum} | ||
| 158 | + */ | ||
| 159 | + private String operator; | ||
| 160 | + | ||
| 161 | + /** | ||
| 162 | + * 比较值 | ||
| 163 | + * | ||
| 164 | + * 如果有多个值,则使用 "," 分隔,类似 "1,2,3"。 | ||
| 165 | + * 例如说,{@link IotRuleSceneTriggerConditionParameterOperatorEnum#IN}、{@link IotRuleSceneTriggerConditionParameterOperatorEnum#BETWEEN} | ||
| 166 | + */ | ||
| 167 | + private String value; | ||
| 168 | + | ||
| 169 | + } | ||
| 170 | + | ||
| 171 | + /** | ||
| 172 | + * 执行器配置 | ||
| 173 | + */ | ||
| 174 | + @Data | ||
| 175 | + public static class ActionConfig { | ||
| 176 | + | ||
| 177 | + /** | ||
| 178 | + * 执行类型 | ||
| 179 | + * | ||
| 180 | + * 枚举 {@link IotRuleSceneActionTypeEnum} | ||
| 181 | + */ | ||
| 182 | + private Integer type; | ||
| 183 | + | ||
| 184 | + /** | ||
| 185 | + * 设备控制 | ||
| 186 | + * | ||
| 187 | + * 必填:当 {@link #type} 为 {@link IotRuleSceneActionTypeEnum#DEVICE_CONTROL} 时 | ||
| 188 | + */ | ||
| 189 | + private ActionDeviceControl deviceControl; | ||
| 190 | + | ||
| 191 | + /** | ||
| 192 | + * 数据桥接编号 | ||
| 193 | + * | ||
| 194 | + * 必填:当 {@link #type} 为 {@link IotRuleSceneActionTypeEnum#DATA_BRIDGE} 时 | ||
| 195 | + * 关联:{@link IotDataBridgeDO#getId()} | ||
| 196 | + */ | ||
| 197 | + private Long dataBridgeId; | ||
| 198 | + | ||
| 199 | + } | ||
| 200 | + | ||
| 201 | + /** | ||
| 202 | + * 执行设备控制 | ||
| 203 | + */ | ||
| 204 | + @Data | ||
| 205 | + public static class ActionDeviceControl { | ||
| 206 | + | ||
| 207 | + /** | ||
| 208 | + * 产品标识 | ||
| 209 | + * | ||
| 210 | + * 关联 {@link IotProductDO#getProductKey()} | ||
| 211 | + */ | ||
| 212 | + private String productKey; | ||
| 213 | + /** | ||
| 214 | + * 设备名称数组 | ||
| 215 | + * | ||
| 216 | + * 关联 {@link IotDeviceDO#getDeviceName()} | ||
| 217 | + */ | ||
| 218 | + private List<String> deviceNames; | ||
| 219 | + | ||
| 220 | + /** | ||
| 221 | + * 消息类型 | ||
| 222 | + * | ||
| 223 | + * 枚举 {@link IotDeviceMessageTypeEnum#PROPERTY}、{@link IotDeviceMessageTypeEnum#SERVICE} | ||
| 224 | + */ | ||
| 225 | + private String type; | ||
| 226 | + /** | ||
| 227 | + * 消息标识符 | ||
| 228 | + * | ||
| 229 | + * 枚举 {@link IotDeviceMessageIdentifierEnum} | ||
| 230 | + * | ||
| 231 | + * 1. 属性设置:对应 {@link IotDeviceMessageIdentifierEnum#PROPERTY_SET} | ||
| 232 | + * 2. 服务调用:对应 {@link IotDeviceMessageIdentifierEnum#SERVICE_INVOKE} | ||
| 233 | + */ | ||
| 234 | + private String identifier; | ||
| 235 | + | ||
| 236 | + /** | ||
| 237 | + * 具体数据 | ||
| 238 | + * | ||
| 239 | + * 1. 属性设置:在 {@link #type} 是 {@link IotDeviceMessageTypeEnum#PROPERTY} 时,对应 properties | ||
| 240 | + * 2. 服务调用:在 {@link #type} 是 {@link IotDeviceMessageTypeEnum#SERVICE} 时,对应 params | ||
| 241 | + */ | ||
| 242 | + private Map<String, Object> data; | ||
| 243 | + | ||
| 244 | + } | ||
| 62 | 245 | ||
| 63 | } | 246 | } |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/rule/IotRuleSceneMapper.java
| @@ -8,7 +8,7 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; | @@ -8,7 +8,7 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; | ||
| 8 | import org.apache.ibatis.annotations.Mapper; | 8 | import org.apache.ibatis.annotations.Mapper; |
| 9 | 9 | ||
| 10 | /** | 10 | /** |
| 11 | - * IoT 规则场景(场景联动) Mapper | 11 | + * IoT 场景联动 Mapper |
| 12 | * | 12 | * |
| 13 | * @author HUIHUI | 13 | * @author HUIHUI |
| 14 | */ | 14 | */ |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/IotRuleSceneService.java
| @@ -18,7 +18,7 @@ import java.util.List; | @@ -18,7 +18,7 @@ import java.util.List; | ||
| 18 | public interface IotRuleSceneService { | 18 | public interface IotRuleSceneService { |
| 19 | 19 | ||
| 20 | /** | 20 | /** |
| 21 | - * 创建规则场景(场景联动) | 21 | + * 创建场景联动 |
| 22 | * | 22 | * |
| 23 | * @param createReqVO 创建信息 | 23 | * @param createReqVO 创建信息 |
| 24 | * @return 编号 | 24 | * @return 编号 |
| @@ -26,32 +26,32 @@ public interface IotRuleSceneService { | @@ -26,32 +26,32 @@ public interface IotRuleSceneService { | ||
| 26 | Long createRuleScene(@Valid IotRuleSceneSaveReqVO createReqVO); | 26 | Long createRuleScene(@Valid IotRuleSceneSaveReqVO createReqVO); |
| 27 | 27 | ||
| 28 | /** | 28 | /** |
| 29 | - * 更新规则场景(场景联动) | 29 | + * 更新场景联动 |
| 30 | * | 30 | * |
| 31 | * @param updateReqVO 更新信息 | 31 | * @param updateReqVO 更新信息 |
| 32 | */ | 32 | */ |
| 33 | void updateRuleScene(@Valid IotRuleSceneSaveReqVO updateReqVO); | 33 | void updateRuleScene(@Valid IotRuleSceneSaveReqVO updateReqVO); |
| 34 | 34 | ||
| 35 | /** | 35 | /** |
| 36 | - * 删除规则场景(场景联动) | 36 | + * 删除场景联动 |
| 37 | * | 37 | * |
| 38 | * @param id 编号 | 38 | * @param id 编号 |
| 39 | */ | 39 | */ |
| 40 | void deleteRuleScene(Long id); | 40 | void deleteRuleScene(Long id); |
| 41 | 41 | ||
| 42 | /** | 42 | /** |
| 43 | - * 获得规则场景(场景联动) | 43 | + * 获得场景联动 |
| 44 | * | 44 | * |
| 45 | * @param id 编号 | 45 | * @param id 编号 |
| 46 | - * @return 规则场景(场景联动) | 46 | + * @return 场景联动 |
| 47 | */ | 47 | */ |
| 48 | IotRuleSceneDO getRuleScene(Long id); | 48 | IotRuleSceneDO getRuleScene(Long id); |
| 49 | 49 | ||
| 50 | /** | 50 | /** |
| 51 | - * 获得规则场景(场景联动)分页 | 51 | + * 获得场景联动分页 |
| 52 | * | 52 | * |
| 53 | * @param pageReqVO 分页查询 | 53 | * @param pageReqVO 分页查询 |
| 54 | - * @return 规则场景(场景联动)分页 | 54 | + * @return 场景联动分页 |
| 55 | */ | 55 | */ |
| 56 | PageResult<IotRuleSceneDO> getRuleScenePage(IotRuleScenePageReqVO pageReqVO); | 56 | PageResult<IotRuleSceneDO> getRuleScenePage(IotRuleScenePageReqVO pageReqVO); |
| 57 | 57 |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/IotRuleSceneServiceImpl.java
| @@ -17,7 +17,6 @@ import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; | @@ -17,7 +17,6 @@ import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; | ||
| 17 | import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; | 17 | import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; |
| 18 | import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleScenePageReqVO; | 18 | import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleScenePageReqVO; |
| 19 | import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleSceneSaveReqVO; | 19 | import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleSceneSaveReqVO; |
| 20 | -import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config.*; | ||
| 21 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; | 20 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; |
| 22 | import cn.iocoder.yudao.module.iot.dal.mysql.rule.IotRuleSceneMapper; | 21 | import cn.iocoder.yudao.module.iot.dal.mysql.rule.IotRuleSceneMapper; |
| 23 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum; | 22 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum; |
| @@ -118,82 +117,82 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { | @@ -118,82 +117,82 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { | ||
| 118 | if (true) { | 117 | if (true) { |
| 119 | IotRuleSceneDO ruleScene01 = new IotRuleSceneDO(); | 118 | IotRuleSceneDO ruleScene01 = new IotRuleSceneDO(); |
| 120 | ruleScene01.setTriggers(CollUtil.newArrayList()); | 119 | ruleScene01.setTriggers(CollUtil.newArrayList()); |
| 121 | - IotRuleSceneTriggerConfig trigger01 = new IotRuleSceneTriggerConfig(); | 120 | + IotRuleSceneDO.TriggerConfig trigger01 = new IotRuleSceneDO.TriggerConfig(); |
| 122 | trigger01.setType(IotRuleSceneTriggerTypeEnum.DEVICE.getType()); | 121 | trigger01.setType(IotRuleSceneTriggerTypeEnum.DEVICE.getType()); |
| 123 | trigger01.setConditions(CollUtil.newArrayList()); | 122 | trigger01.setConditions(CollUtil.newArrayList()); |
| 124 | // 属性 | 123 | // 属性 |
| 125 | - IotRuleSceneTriggerCondition condition01 = new IotRuleSceneTriggerCondition(); | 124 | + IotRuleSceneDO.TriggerCondition condition01 = new IotRuleSceneDO.TriggerCondition(); |
| 126 | condition01.setType(IotDeviceMessageTypeEnum.PROPERTY.getType()); | 125 | condition01.setType(IotDeviceMessageTypeEnum.PROPERTY.getType()); |
| 127 | condition01.setIdentifier(IotDeviceMessageIdentifierEnum.PROPERTY_REPORT.getIdentifier()); | 126 | condition01.setIdentifier(IotDeviceMessageIdentifierEnum.PROPERTY_REPORT.getIdentifier()); |
| 128 | condition01.setParameters(CollUtil.newArrayList()); | 127 | condition01.setParameters(CollUtil.newArrayList()); |
| 129 | -// IotRuleSceneTriggerConditionParameter parameter010 = new IotRuleSceneTriggerConditionParameter(); | 128 | +// IotRuleSceneDO.TriggerConditionParameter parameter010 = new IotRuleSceneDO.TriggerConditionParameter(); |
| 130 | // parameter010.setIdentifier("width"); | 129 | // parameter010.setIdentifier("width"); |
| 131 | // parameter010.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.getOperator()); | 130 | // parameter010.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.getOperator()); |
| 132 | // parameter010.setValue("abc"); | 131 | // parameter010.setValue("abc"); |
| 133 | // condition01.getParameters().add(parameter010); | 132 | // condition01.getParameters().add(parameter010); |
| 134 | - IotRuleSceneTriggerConditionParameter parameter011 = new IotRuleSceneTriggerConditionParameter(); | 133 | + IotRuleSceneDO.TriggerConditionParameter parameter011 = new IotRuleSceneDO.TriggerConditionParameter(); |
| 135 | parameter011.setIdentifier("width"); | 134 | parameter011.setIdentifier("width"); |
| 136 | parameter011.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.getOperator()); | 135 | parameter011.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.getOperator()); |
| 137 | parameter011.setValue("1"); | 136 | parameter011.setValue("1"); |
| 138 | condition01.getParameters().add(parameter011); | 137 | condition01.getParameters().add(parameter011); |
| 139 | - IotRuleSceneTriggerConditionParameter parameter012 = new IotRuleSceneTriggerConditionParameter(); | 138 | + IotRuleSceneDO.TriggerConditionParameter parameter012 = new IotRuleSceneDO.TriggerConditionParameter(); |
| 140 | parameter012.setIdentifier("width"); | 139 | parameter012.setIdentifier("width"); |
| 141 | parameter012.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_EQUALS.getOperator()); | 140 | parameter012.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_EQUALS.getOperator()); |
| 142 | parameter012.setValue("2"); | 141 | parameter012.setValue("2"); |
| 143 | condition01.getParameters().add(parameter012); | 142 | condition01.getParameters().add(parameter012); |
| 144 | - IotRuleSceneTriggerConditionParameter parameter013 = new IotRuleSceneTriggerConditionParameter(); | 143 | + IotRuleSceneDO.TriggerConditionParameter parameter013 = new IotRuleSceneDO.TriggerConditionParameter(); |
| 145 | parameter013.setIdentifier("width"); | 144 | parameter013.setIdentifier("width"); |
| 146 | parameter013.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.GREATER_THAN.getOperator()); | 145 | parameter013.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.GREATER_THAN.getOperator()); |
| 147 | parameter013.setValue("0"); | 146 | parameter013.setValue("0"); |
| 148 | condition01.getParameters().add(parameter013); | 147 | condition01.getParameters().add(parameter013); |
| 149 | - IotRuleSceneTriggerConditionParameter parameter014 = new IotRuleSceneTriggerConditionParameter(); | 148 | + IotRuleSceneDO.TriggerConditionParameter parameter014 = new IotRuleSceneDO.TriggerConditionParameter(); |
| 150 | parameter014.setIdentifier("width"); | 149 | parameter014.setIdentifier("width"); |
| 151 | parameter014.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.GREATER_THAN_OR_EQUALS.getOperator()); | 150 | parameter014.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.GREATER_THAN_OR_EQUALS.getOperator()); |
| 152 | parameter014.setValue("0"); | 151 | parameter014.setValue("0"); |
| 153 | condition01.getParameters().add(parameter014); | 152 | condition01.getParameters().add(parameter014); |
| 154 | - IotRuleSceneTriggerConditionParameter parameter015 = new IotRuleSceneTriggerConditionParameter(); | 153 | + IotRuleSceneDO.TriggerConditionParameter parameter015 = new IotRuleSceneDO.TriggerConditionParameter(); |
| 155 | parameter015.setIdentifier("width"); | 154 | parameter015.setIdentifier("width"); |
| 156 | parameter015.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.LESS_THAN.getOperator()); | 155 | parameter015.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.LESS_THAN.getOperator()); |
| 157 | parameter015.setValue("2"); | 156 | parameter015.setValue("2"); |
| 158 | condition01.getParameters().add(parameter015); | 157 | condition01.getParameters().add(parameter015); |
| 159 | - IotRuleSceneTriggerConditionParameter parameter016 = new IotRuleSceneTriggerConditionParameter(); | 158 | + IotRuleSceneDO.TriggerConditionParameter parameter016 = new IotRuleSceneDO.TriggerConditionParameter(); |
| 160 | parameter016.setIdentifier("width"); | 159 | parameter016.setIdentifier("width"); |
| 161 | parameter016.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.LESS_THAN_OR_EQUALS.getOperator()); | 160 | parameter016.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.LESS_THAN_OR_EQUALS.getOperator()); |
| 162 | parameter016.setValue("2"); | 161 | parameter016.setValue("2"); |
| 163 | condition01.getParameters().add(parameter016); | 162 | condition01.getParameters().add(parameter016); |
| 164 | - IotRuleSceneTriggerConditionParameter parameter017 = new IotRuleSceneTriggerConditionParameter(); | 163 | + IotRuleSceneDO.TriggerConditionParameter parameter017 = new IotRuleSceneDO.TriggerConditionParameter(); |
| 165 | parameter017.setIdentifier("width"); | 164 | parameter017.setIdentifier("width"); |
| 166 | parameter017.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.IN.getOperator()); | 165 | parameter017.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.IN.getOperator()); |
| 167 | parameter017.setValue("1,2,3"); | 166 | parameter017.setValue("1,2,3"); |
| 168 | condition01.getParameters().add(parameter017); | 167 | condition01.getParameters().add(parameter017); |
| 169 | - IotRuleSceneTriggerConditionParameter parameter018 = new IotRuleSceneTriggerConditionParameter(); | 168 | + IotRuleSceneDO.TriggerConditionParameter parameter018 = new IotRuleSceneDO.TriggerConditionParameter(); |
| 170 | parameter018.setIdentifier("width"); | 169 | parameter018.setIdentifier("width"); |
| 171 | parameter018.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_IN.getOperator()); | 170 | parameter018.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_IN.getOperator()); |
| 172 | parameter018.setValue("0,2,3"); | 171 | parameter018.setValue("0,2,3"); |
| 173 | condition01.getParameters().add(parameter018); | 172 | condition01.getParameters().add(parameter018); |
| 174 | - IotRuleSceneTriggerConditionParameter parameter019 = new IotRuleSceneTriggerConditionParameter(); | 173 | + IotRuleSceneDO.TriggerConditionParameter parameter019 = new IotRuleSceneDO.TriggerConditionParameter(); |
| 175 | parameter019.setIdentifier("width"); | 174 | parameter019.setIdentifier("width"); |
| 176 | parameter019.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.BETWEEN.getOperator()); | 175 | parameter019.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.BETWEEN.getOperator()); |
| 177 | parameter019.setValue("1,3"); | 176 | parameter019.setValue("1,3"); |
| 178 | condition01.getParameters().add(parameter019); | 177 | condition01.getParameters().add(parameter019); |
| 179 | - IotRuleSceneTriggerConditionParameter parameter020 = new IotRuleSceneTriggerConditionParameter(); | 178 | + IotRuleSceneDO.TriggerConditionParameter parameter020 = new IotRuleSceneDO.TriggerConditionParameter(); |
| 180 | parameter020.setIdentifier("width"); | 179 | parameter020.setIdentifier("width"); |
| 181 | parameter020.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_BETWEEN.getOperator()); | 180 | parameter020.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_BETWEEN.getOperator()); |
| 182 | parameter020.setValue("2,3"); | 181 | parameter020.setValue("2,3"); |
| 183 | condition01.getParameters().add(parameter020); | 182 | condition01.getParameters().add(parameter020); |
| 184 | trigger01.getConditions().add(condition01); | 183 | trigger01.getConditions().add(condition01); |
| 185 | // 状态 | 184 | // 状态 |
| 186 | - IotRuleSceneTriggerCondition condition02 = new IotRuleSceneTriggerCondition(); | 185 | + IotRuleSceneDO.TriggerCondition condition02 = new IotRuleSceneDO.TriggerCondition(); |
| 187 | condition02.setType(IotDeviceMessageTypeEnum.STATE.getType()); | 186 | condition02.setType(IotDeviceMessageTypeEnum.STATE.getType()); |
| 188 | condition02.setIdentifier(IotDeviceMessageIdentifierEnum.STATE_ONLINE.getIdentifier()); | 187 | condition02.setIdentifier(IotDeviceMessageIdentifierEnum.STATE_ONLINE.getIdentifier()); |
| 189 | condition02.setParameters(CollUtil.newArrayList()); | 188 | condition02.setParameters(CollUtil.newArrayList()); |
| 190 | trigger01.getConditions().add(condition02); | 189 | trigger01.getConditions().add(condition02); |
| 191 | // 事件 | 190 | // 事件 |
| 192 | - IotRuleSceneTriggerCondition condition03 = new IotRuleSceneTriggerCondition(); | 191 | + IotRuleSceneDO.TriggerCondition condition03 = new IotRuleSceneDO.TriggerCondition(); |
| 193 | condition03.setType(IotDeviceMessageTypeEnum.EVENT.getType()); | 192 | condition03.setType(IotDeviceMessageTypeEnum.EVENT.getType()); |
| 194 | condition03.setIdentifier("xxx"); | 193 | condition03.setIdentifier("xxx"); |
| 195 | condition03.setParameters(CollUtil.newArrayList()); | 194 | condition03.setParameters(CollUtil.newArrayList()); |
| 196 | - IotRuleSceneTriggerConditionParameter parameter030 = new IotRuleSceneTriggerConditionParameter(); | 195 | + IotRuleSceneDO.TriggerConditionParameter parameter030 = new IotRuleSceneDO.TriggerConditionParameter(); |
| 197 | parameter030.setIdentifier("width"); | 196 | parameter030.setIdentifier("width"); |
| 198 | parameter030.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.getOperator()); | 197 | parameter030.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.getOperator()); |
| 199 | parameter030.setValue("1"); | 198 | parameter030.setValue("1"); |
| @@ -202,21 +201,21 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { | @@ -202,21 +201,21 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { | ||
| 202 | // 动作 | 201 | // 动作 |
| 203 | ruleScene01.setActions(CollUtil.newArrayList()); | 202 | ruleScene01.setActions(CollUtil.newArrayList()); |
| 204 | // 设备控制 | 203 | // 设备控制 |
| 205 | - IotRuleSceneActionConfig action01 = new IotRuleSceneActionConfig(); | 204 | + IotRuleSceneDO.ActionConfig action01 = new IotRuleSceneDO.ActionConfig(); |
| 206 | action01.setType(IotRuleSceneActionTypeEnum.DEVICE_CONTROL.getType()); | 205 | action01.setType(IotRuleSceneActionTypeEnum.DEVICE_CONTROL.getType()); |
| 207 | - IotRuleSceneActionDeviceControl iotRuleSceneActionDeviceControl01 = new IotRuleSceneActionDeviceControl(); | ||
| 208 | - iotRuleSceneActionDeviceControl01.setProductKey("4aymZgOTOOCrDKRT"); | ||
| 209 | - iotRuleSceneActionDeviceControl01.setDeviceNames(ListUtil.of("small")); | ||
| 210 | - iotRuleSceneActionDeviceControl01.setType(IotDeviceMessageTypeEnum.PROPERTY.getType()); | ||
| 211 | - iotRuleSceneActionDeviceControl01.setIdentifier(IotDeviceMessageIdentifierEnum.PROPERTY_SET.getIdentifier()); | ||
| 212 | - iotRuleSceneActionDeviceControl01.setData(MapUtil.<String, Object>builder() | 206 | + IotRuleSceneDO.ActionDeviceControl actionDeviceControl01 = new IotRuleSceneDO.ActionDeviceControl(); |
| 207 | + actionDeviceControl01.setProductKey("4aymZgOTOOCrDKRT"); | ||
| 208 | + actionDeviceControl01.setDeviceNames(ListUtil.of("small")); | ||
| 209 | + actionDeviceControl01.setType(IotDeviceMessageTypeEnum.PROPERTY.getType()); | ||
| 210 | + actionDeviceControl01.setIdentifier(IotDeviceMessageIdentifierEnum.PROPERTY_SET.getIdentifier()); | ||
| 211 | + actionDeviceControl01.setData(MapUtil.<String, Object>builder() | ||
| 213 | .put("power", 1) | 212 | .put("power", 1) |
| 214 | .put("color", "red") | 213 | .put("color", "red") |
| 215 | .build()); | 214 | .build()); |
| 216 | - action01.setDeviceControl(iotRuleSceneActionDeviceControl01); | 215 | + action01.setDeviceControl(actionDeviceControl01); |
| 217 | // ruleScene01.getActions().add(action01); // TODO 芋艿:先不测试了 | 216 | // ruleScene01.getActions().add(action01); // TODO 芋艿:先不测试了 |
| 218 | // 数据桥接(http) | 217 | // 数据桥接(http) |
| 219 | - IotRuleSceneActionConfig action02 = new IotRuleSceneActionConfig(); | 218 | + IotRuleSceneDO.ActionConfig action02 = new IotRuleSceneDO.ActionConfig(); |
| 220 | action02.setType(IotRuleSceneActionTypeEnum.DATA_BRIDGE.getType()); | 219 | action02.setType(IotRuleSceneActionTypeEnum.DATA_BRIDGE.getType()); |
| 221 | action02.setDataBridgeId(1L); | 220 | action02.setDataBridgeId(1L); |
| 222 | ruleScene01.getActions().add(action02); | 221 | ruleScene01.getActions().add(action02); |
| @@ -226,7 +225,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { | @@ -226,7 +225,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { | ||
| 226 | List<IotRuleSceneDO> list = ruleSceneMapper.selectList(); | 225 | List<IotRuleSceneDO> list = ruleSceneMapper.selectList(); |
| 227 | // TODO @芋艿:需要考虑开启状态 | 226 | // TODO @芋艿:需要考虑开启状态 |
| 228 | return filterList(list, ruleScene -> { | 227 | return filterList(list, ruleScene -> { |
| 229 | - for (IotRuleSceneTriggerConfig trigger : ruleScene.getTriggers()) { | 228 | + for (IotRuleSceneDO.TriggerConfig trigger : ruleScene.getTriggers()) { |
| 230 | if (ObjUtil.notEqual(trigger.getProductKey(), productKey)) { | 229 | if (ObjUtil.notEqual(trigger.getProductKey(), productKey)) { |
| 231 | continue; | 230 | continue; |
| 232 | } | 231 | } |
| @@ -261,13 +260,13 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { | @@ -261,13 +260,13 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { | ||
| 261 | IotRuleSceneDO scene = new IotRuleSceneDO().setStatus(CommonStatusEnum.ENABLE.getStatus()); | 260 | IotRuleSceneDO scene = new IotRuleSceneDO().setStatus(CommonStatusEnum.ENABLE.getStatus()); |
| 262 | if (true) { | 261 | if (true) { |
| 263 | scene.setTenantId(1L); | 262 | scene.setTenantId(1L); |
| 264 | - IotRuleSceneTriggerConfig iotRuleSceneTriggerConfig = new IotRuleSceneTriggerConfig(); | ||
| 265 | - iotRuleSceneTriggerConfig.setType(IotRuleSceneTriggerTypeEnum.TIMER.getType()); | ||
| 266 | - scene.setTriggers(ListUtil.toList(iotRuleSceneTriggerConfig)); | 263 | + IotRuleSceneDO.TriggerConfig triggerConfig = new IotRuleSceneDO.TriggerConfig(); |
| 264 | + triggerConfig.setType(IotRuleSceneTriggerTypeEnum.TIMER.getType()); | ||
| 265 | + scene.setTriggers(ListUtil.toList(triggerConfig)); | ||
| 267 | // 动作 | 266 | // 动作 |
| 268 | - IotRuleSceneActionConfig action01 = new IotRuleSceneActionConfig(); | 267 | + IotRuleSceneDO.ActionConfig action01 = new IotRuleSceneDO.ActionConfig(); |
| 269 | action01.setType(IotRuleSceneActionTypeEnum.DEVICE_CONTROL.getType()); | 268 | action01.setType(IotRuleSceneActionTypeEnum.DEVICE_CONTROL.getType()); |
| 270 | - IotRuleSceneActionDeviceControl iotRuleSceneActionDeviceControl01 = new IotRuleSceneActionDeviceControl(); | 269 | + IotRuleSceneDO.ActionDeviceControl iotRuleSceneActionDeviceControl01 = new IotRuleSceneDO.ActionDeviceControl(); |
| 271 | iotRuleSceneActionDeviceControl01.setProductKey("4aymZgOTOOCrDKRT"); | 270 | iotRuleSceneActionDeviceControl01.setProductKey("4aymZgOTOOCrDKRT"); |
| 272 | iotRuleSceneActionDeviceControl01.setDeviceNames(ListUtil.of("small")); | 271 | iotRuleSceneActionDeviceControl01.setDeviceNames(ListUtil.of("small")); |
| 273 | iotRuleSceneActionDeviceControl01.setType(IotDeviceMessageTypeEnum.PROPERTY.getType()); | 272 | iotRuleSceneActionDeviceControl01.setType(IotDeviceMessageTypeEnum.PROPERTY.getType()); |
| @@ -288,7 +287,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { | @@ -288,7 +287,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { | ||
| 288 | return; | 287 | return; |
| 289 | } | 288 | } |
| 290 | // 1.2 判断是否有定时触发器,避免脏数据 | 289 | // 1.2 判断是否有定时触发器,避免脏数据 |
| 291 | - IotRuleSceneTriggerConfig config = CollUtil.findOne(scene.getTriggers(), | 290 | + IotRuleSceneDO.TriggerConfig config = CollUtil.findOne(scene.getTriggers(), |
| 292 | trigger -> ObjUtil.equals(trigger.getType(), IotRuleSceneTriggerTypeEnum.TIMER.getType())); | 291 | trigger -> ObjUtil.equals(trigger.getType(), IotRuleSceneTriggerTypeEnum.TIMER.getType())); |
| 293 | if (config == null) { | 292 | if (config == null) { |
| 294 | log.error("[executeRuleSceneByTimer][规则场景({}) 不存在定时触发器]", scene); | 293 | log.error("[executeRuleSceneByTimer][规则场景({}) 不存在定时触发器]", scene); |
| @@ -317,7 +316,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { | @@ -317,7 +316,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { | ||
| 317 | 316 | ||
| 318 | // 2. 匹配 trigger 触发器的条件 | 317 | // 2. 匹配 trigger 触发器的条件 |
| 319 | return filterList(ruleScenes, ruleScene -> { | 318 | return filterList(ruleScenes, ruleScene -> { |
| 320 | - for (IotRuleSceneTriggerConfig trigger : ruleScene.getTriggers()) { | 319 | + for (IotRuleSceneDO.TriggerConfig trigger : ruleScene.getTriggers()) { |
| 321 | // 2.1 非设备触发,不匹配 | 320 | // 2.1 非设备触发,不匹配 |
| 322 | if (ObjUtil.notEqual(trigger.getType(), IotRuleSceneTriggerTypeEnum.DEVICE.getType())) { | 321 | if (ObjUtil.notEqual(trigger.getType(), IotRuleSceneTriggerTypeEnum.DEVICE.getType())) { |
| 323 | return false; | 322 | return false; |
| @@ -328,13 +327,13 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { | @@ -328,13 +327,13 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { | ||
| 328 | return false; | 327 | return false; |
| 329 | } | 328 | } |
| 330 | // 2.3 多个条件,只需要满足一个即可 | 329 | // 2.3 多个条件,只需要满足一个即可 |
| 331 | - IotRuleSceneTriggerCondition matchedCondition = CollUtil.findOne(trigger.getConditions(), condition -> { | 330 | + IotRuleSceneDO.TriggerCondition matchedCondition = CollUtil.findOne(trigger.getConditions(), condition -> { |
| 332 | if (ObjUtil.notEqual(message.getType(), condition.getType()) | 331 | if (ObjUtil.notEqual(message.getType(), condition.getType()) |
| 333 | || ObjUtil.notEqual(message.getIdentifier(), condition.getIdentifier())) { | 332 | || ObjUtil.notEqual(message.getIdentifier(), condition.getIdentifier())) { |
| 334 | return false; | 333 | return false; |
| 335 | } | 334 | } |
| 336 | // 多个条件参数,必须全部满足。所以,下面的逻辑就是找到一个不满足的条件参数 | 335 | // 多个条件参数,必须全部满足。所以,下面的逻辑就是找到一个不满足的条件参数 |
| 337 | - IotRuleSceneTriggerConditionParameter notMatchedParameter = CollUtil.findOne(condition.getParameters(), | 336 | + IotRuleSceneDO.TriggerConditionParameter notMatchedParameter = CollUtil.findOne(condition.getParameters(), |
| 338 | parameter -> !isTriggerConditionParameterMatched(message, parameter, ruleScene, trigger)); | 337 | parameter -> !isTriggerConditionParameterMatched(message, parameter, ruleScene, trigger)); |
| 339 | return notMatchedParameter == null; | 338 | return notMatchedParameter == null; |
| 340 | }); | 339 | }); |
| @@ -360,8 +359,8 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { | @@ -360,8 +359,8 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { | ||
| 360 | * @return 是否匹配 | 359 | * @return 是否匹配 |
| 361 | */ | 360 | */ |
| 362 | @SuppressWarnings({"unchecked", "DataFlowIssue"}) | 361 | @SuppressWarnings({"unchecked", "DataFlowIssue"}) |
| 363 | - private boolean isTriggerConditionParameterMatched(IotDeviceMessage message, IotRuleSceneTriggerConditionParameter parameter, | ||
| 364 | - IotRuleSceneDO ruleScene, IotRuleSceneTriggerConfig trigger) { | 362 | + private boolean isTriggerConditionParameterMatched(IotDeviceMessage message, IotRuleSceneDO.TriggerConditionParameter parameter, |
| 363 | + IotRuleSceneDO ruleScene, IotRuleSceneDO.TriggerConfig trigger) { | ||
| 365 | // 1.1 校验操作符是否合法 | 364 | // 1.1 校验操作符是否合法 |
| 366 | IotRuleSceneTriggerConditionParameterOperatorEnum operator = | 365 | IotRuleSceneTriggerConditionParameterOperatorEnum operator = |
| 367 | IotRuleSceneTriggerConditionParameterOperatorEnum.operatorOf(parameter.getOperator()); | 366 | IotRuleSceneTriggerConditionParameterOperatorEnum.operatorOf(parameter.getOperator()); |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/IotRuleSceneAction.java
| 1 | package cn.iocoder.yudao.module.iot.service.rule.action; | 1 | package cn.iocoder.yudao.module.iot.service.rule.action; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config.IotRuleSceneActionConfig; | 3 | +import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; |
| 4 | import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum; | 4 | import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum; |
| 5 | import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | 5 | import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; |
| 6 | 6 | ||
| @@ -23,7 +23,7 @@ public interface IotRuleSceneAction { | @@ -23,7 +23,7 @@ public interface IotRuleSceneAction { | ||
| 23 | * 2. 非空的情况:设备触发 | 23 | * 2. 非空的情况:设备触发 |
| 24 | * @param config 配置 | 24 | * @param config 配置 |
| 25 | */ | 25 | */ |
| 26 | - void execute(@Nullable IotDeviceMessage message, IotRuleSceneActionConfig config) throws Exception; | 26 | + void execute(@Nullable IotDeviceMessage message, IotRuleSceneDO.ActionConfig config) throws Exception; |
| 27 | 27 | ||
| 28 | /** | 28 | /** |
| 29 | * 获得类型 | 29 | * 获得类型 |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/IotRuleSceneAlertAction.java
| 1 | package cn.iocoder.yudao.module.iot.service.rule.action; | 1 | package cn.iocoder.yudao.module.iot.service.rule.action; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config.IotRuleSceneActionConfig; | 3 | +import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; |
| 4 | import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum; | 4 | import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum; |
| 5 | import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | 5 | import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; |
| 6 | import org.springframework.stereotype.Component; | 6 | import org.springframework.stereotype.Component; |
| @@ -16,7 +16,7 @@ import javax.annotation.Nullable; | @@ -16,7 +16,7 @@ import javax.annotation.Nullable; | ||
| 16 | public class IotRuleSceneAlertAction implements IotRuleSceneAction { | 16 | public class IotRuleSceneAlertAction implements IotRuleSceneAction { |
| 17 | 17 | ||
| 18 | @Override | 18 | @Override |
| 19 | - public void execute(@Nullable IotDeviceMessage message, IotRuleSceneActionConfig config) { | 19 | + public void execute(@Nullable IotDeviceMessage message, IotRuleSceneDO.ActionConfig config) { |
| 20 | // TODO @芋艿:待实现 | 20 | // TODO @芋艿:待实现 |
| 21 | } | 21 | } |
| 22 | 22 |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/IotRuleSceneDataBridgeAction.java
| @@ -2,8 +2,8 @@ package cn.iocoder.yudao.module.iot.service.rule.action; | @@ -2,8 +2,8 @@ package cn.iocoder.yudao.module.iot.service.rule.action; | ||
| 2 | 2 | ||
| 3 | import cn.hutool.core.lang.Assert; | 3 | import cn.hutool.core.lang.Assert; |
| 4 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | 4 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| 5 | -import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config.IotRuleSceneActionConfig; | ||
| 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; | 5 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; |
| 6 | +import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; | ||
| 7 | import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum; | 7 | import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum; |
| 8 | import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | 8 | import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; |
| 9 | import cn.iocoder.yudao.module.iot.service.rule.IotDataBridgeService; | 9 | import cn.iocoder.yudao.module.iot.service.rule.IotDataBridgeService; |
| @@ -29,7 +29,7 @@ public class IotRuleSceneDataBridgeAction implements IotRuleSceneAction { | @@ -29,7 +29,7 @@ public class IotRuleSceneDataBridgeAction implements IotRuleSceneAction { | ||
| 29 | private List<IotDataBridgeExecute<?>> dataBridgeExecutes; | 29 | private List<IotDataBridgeExecute<?>> dataBridgeExecutes; |
| 30 | 30 | ||
| 31 | @Override | 31 | @Override |
| 32 | - public void execute(IotDeviceMessage message, IotRuleSceneActionConfig config) throws Exception { | 32 | + public void execute(IotDeviceMessage message, IotRuleSceneDO.ActionConfig config) throws Exception { |
| 33 | // 1.1 如果消息为空,直接返回 | 33 | // 1.1 如果消息为空,直接返回 |
| 34 | if (message == null) { | 34 | if (message == null) { |
| 35 | return; | 35 | return; |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/IotRuleSceneDeviceControlAction.java
| @@ -2,9 +2,8 @@ package cn.iocoder.yudao.module.iot.service.rule.action; | @@ -2,9 +2,8 @@ package cn.iocoder.yudao.module.iot.service.rule.action; | ||
| 2 | 2 | ||
| 3 | import cn.hutool.core.lang.Assert; | 3 | import cn.hutool.core.lang.Assert; |
| 4 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.control.IotDeviceDownstreamReqVO; | 4 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.control.IotDeviceDownstreamReqVO; |
| 5 | -import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config.IotRuleSceneActionConfig; | ||
| 6 | -import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config.IotRuleSceneActionDeviceControl; | ||
| 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | 5 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 6 | +import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; | ||
| 8 | import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum; | 7 | import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum; |
| 9 | import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | 8 | import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; |
| 10 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; | 9 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; |
| @@ -28,8 +27,8 @@ public class IotRuleSceneDeviceControlAction implements IotRuleSceneAction { | @@ -28,8 +27,8 @@ public class IotRuleSceneDeviceControlAction implements IotRuleSceneAction { | ||
| 28 | private IotDeviceService deviceService; | 27 | private IotDeviceService deviceService; |
| 29 | 28 | ||
| 30 | @Override | 29 | @Override |
| 31 | - public void execute(IotDeviceMessage message, IotRuleSceneActionConfig config) { | ||
| 32 | - IotRuleSceneActionDeviceControl control = config.getDeviceControl(); | 30 | + public void execute(IotDeviceMessage message, IotRuleSceneDO.ActionConfig config) { |
| 31 | + IotRuleSceneDO.ActionDeviceControl control = config.getDeviceControl(); | ||
| 33 | Assert.notNull(control, "设备控制配置不能为空"); | 32 | Assert.notNull(control, "设备控制配置不能为空"); |
| 34 | // 遍历每个设备,下发消息 | 33 | // 遍历每个设备,下发消息 |
| 35 | control.getDeviceNames().forEach(deviceName -> { | 34 | control.getDeviceNames().forEach(deviceName -> { |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/databridge/AbstractCacheableDataBridgeExecute.java
| @@ -101,7 +101,7 @@ public abstract class AbstractCacheableDataBridgeExecute<Config, Producer> imple | @@ -101,7 +101,7 @@ public abstract class AbstractCacheableDataBridgeExecute<Config, Producer> imple | ||
| 101 | @Override | 101 | @Override |
| 102 | @SuppressWarnings({"unchecked"}) | 102 | @SuppressWarnings({"unchecked"}) |
| 103 | public void execute(IotDeviceMessage message, IotDataBridgeDO dataBridge) { | 103 | public void execute(IotDeviceMessage message, IotDataBridgeDO dataBridge) { |
| 104 | - if (ObjUtil.notEqual(message.getType(), getType())) { | 104 | + if (ObjUtil.notEqual(dataBridge.getType(), getType())) { |
| 105 | return; | 105 | return; |
| 106 | } | 106 | } |
| 107 | try { | 107 | try { |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/databridge/IotRedisStreamMQDataBridgeExecute.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/databridge/IotRedisStreamDataBridgeExecute.java
| 1 | package cn.iocoder.yudao.module.iot.service.rule.action.databridge; | 1 | package cn.iocoder.yudao.module.iot.service.rule.action.databridge; |
| 2 | 2 | ||
| 3 | -import cn.hutool.core.util.ReflectUtil; | ||
| 4 | import cn.hutool.core.util.StrUtil; | 3 | import cn.hutool.core.util.StrUtil; |
| 5 | -import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config.IotDataBridgeRedisStreamMQConfig; | 4 | +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config.IotDataBridgeRedisStreamConfig; |
| 6 | import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgeTypeEnum; | 5 | import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgeTypeEnum; |
| 7 | import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | 6 | import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; |
| 8 | -import com.fasterxml.jackson.databind.ObjectMapper; | ||
| 9 | -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; | ||
| 10 | import lombok.extern.slf4j.Slf4j; | 7 | import lombok.extern.slf4j.Slf4j; |
| 11 | import org.redisson.Redisson; | 8 | import org.redisson.Redisson; |
| 12 | import org.redisson.api.RedissonClient; | 9 | import org.redisson.api.RedissonClient; |
| @@ -21,14 +18,14 @@ import org.springframework.data.redis.serializer.RedisSerializer; | @@ -21,14 +18,14 @@ import org.springframework.data.redis.serializer.RedisSerializer; | ||
| 21 | import org.springframework.stereotype.Component; | 18 | import org.springframework.stereotype.Component; |
| 22 | 19 | ||
| 23 | /** | 20 | /** |
| 24 | - * Redis Stream MQ 的 {@link IotDataBridgeExecute} 实现类 | 21 | + * Redis Stream 的 {@link IotDataBridgeExecute} 实现类 |
| 25 | * | 22 | * |
| 26 | * @author HUIHUI | 23 | * @author HUIHUI |
| 27 | */ | 24 | */ |
| 28 | @Component | 25 | @Component |
| 29 | @Slf4j | 26 | @Slf4j |
| 30 | -public class IotRedisStreamMQDataBridgeExecute extends | ||
| 31 | - AbstractCacheableDataBridgeExecute<IotDataBridgeRedisStreamMQConfig, RedisTemplate<String, Object>> { | 27 | +public class IotRedisStreamDataBridgeExecute extends |
| 28 | + AbstractCacheableDataBridgeExecute<IotDataBridgeRedisStreamConfig, RedisTemplate<String, Object>> { | ||
| 32 | 29 | ||
| 33 | @Override | 30 | @Override |
| 34 | public Integer getType() { | 31 | public Integer getType() { |
| @@ -36,7 +33,7 @@ public class IotRedisStreamMQDataBridgeExecute extends | @@ -36,7 +33,7 @@ public class IotRedisStreamMQDataBridgeExecute extends | ||
| 36 | } | 33 | } |
| 37 | 34 | ||
| 38 | @Override | 35 | @Override |
| 39 | - public void execute0(IotDeviceMessage message, IotDataBridgeRedisStreamMQConfig config) throws Exception { | 36 | + public void execute0(IotDeviceMessage message, IotDataBridgeRedisStreamConfig config) throws Exception { |
| 40 | // 1. 获取 RedisTemplate | 37 | // 1. 获取 RedisTemplate |
| 41 | RedisTemplate<String, Object> redisTemplate = getProducer(config); | 38 | RedisTemplate<String, Object> redisTemplate = getProducer(config); |
| 42 | 39 | ||
| @@ -48,7 +45,7 @@ public class IotRedisStreamMQDataBridgeExecute extends | @@ -48,7 +45,7 @@ public class IotRedisStreamMQDataBridgeExecute extends | ||
| 48 | } | 45 | } |
| 49 | 46 | ||
| 50 | @Override | 47 | @Override |
| 51 | - protected RedisTemplate<String, Object> initProducer(IotDataBridgeRedisStreamMQConfig config) { | 48 | + protected RedisTemplate<String, Object> initProducer(IotDataBridgeRedisStreamConfig config) { |
| 52 | // 1.1 创建 Redisson 配置 | 49 | // 1.1 创建 Redisson 配置 |
| 53 | Config redissonConfig = new Config(); | 50 | Config redissonConfig = new Config(); |
| 54 | SingleServerConfig serverConfig = redissonConfig.useSingleServer() | 51 | SingleServerConfig serverConfig = redissonConfig.useSingleServer() |
| @@ -59,20 +56,17 @@ public class IotRedisStreamMQDataBridgeExecute extends | @@ -59,20 +56,17 @@ public class IotRedisStreamMQDataBridgeExecute extends | ||
| 59 | serverConfig.setPassword(config.getPassword()); | 56 | serverConfig.setPassword(config.getPassword()); |
| 60 | } | 57 | } |
| 61 | 58 | ||
| 62 | - // TODO @huihui:看看能不能简化一些。按道理说,不用这么多的哈。 | ||
| 63 | - // 2.1 创建 RedissonClient | 59 | + // TODO @芋艿:看看怎么优化 |
| 60 | + // 创建 RedisTemplate 并配置 | ||
| 64 | RedissonClient redisson = Redisson.create(redissonConfig); | 61 | RedissonClient redisson = Redisson.create(redissonConfig); |
| 65 | - // 2.2 创建并配置 RedisTemplate | ||
| 66 | RedisTemplate<String, Object> template = new RedisTemplate<>(); | 62 | RedisTemplate<String, Object> template = new RedisTemplate<>(); |
| 67 | - // 设置 RedisConnection 工厂。😈 它就是实现多种 Java Redis 客户端接入的秘密工厂。感兴趣的胖友,可以自己去撸下。 | ||
| 68 | template.setConnectionFactory(new RedissonConnectionFactory(redisson)); | 63 | template.setConnectionFactory(new RedissonConnectionFactory(redisson)); |
| 69 | - // 使用 String 序列化方式,序列化 KEY 。 | 64 | + // 设置序列化器 |
| 70 | template.setKeySerializer(RedisSerializer.string()); | 65 | template.setKeySerializer(RedisSerializer.string()); |
| 71 | template.setHashKeySerializer(RedisSerializer.string()); | 66 | template.setHashKeySerializer(RedisSerializer.string()); |
| 72 | - // 使用 JSON 序列化方式(库是 Jackson ),序列化 VALUE 。 | ||
| 73 | - template.setValueSerializer(buildRedisSerializer()); | ||
| 74 | - template.setHashValueSerializer(buildRedisSerializer()); | ||
| 75 | - template.afterPropertiesSet();// 初始化 | 67 | + template.setValueSerializer(RedisSerializer.json()); |
| 68 | + template.setHashValueSerializer(RedisSerializer.json()); | ||
| 69 | + template.afterPropertiesSet(); | ||
| 76 | return template; | 70 | return template; |
| 77 | } | 71 | } |
| 78 | 72 | ||
| @@ -84,13 +78,4 @@ public class IotRedisStreamMQDataBridgeExecute extends | @@ -84,13 +78,4 @@ public class IotRedisStreamMQDataBridgeExecute extends | ||
| 84 | } | 78 | } |
| 85 | } | 79 | } |
| 86 | 80 | ||
| 87 | - // TODO @huihui:看看能不能简化一些。按道理说,不用这么多的哈。 | ||
| 88 | - public static RedisSerializer<?> buildRedisSerializer() { | ||
| 89 | - RedisSerializer<Object> json = RedisSerializer.json(); | ||
| 90 | - // 解决 LocalDateTime 的序列化 | ||
| 91 | - ObjectMapper objectMapper = (ObjectMapper) ReflectUtil.getFieldValue(json, "mapper"); | ||
| 92 | - objectMapper.registerModules(new JavaTimeModule()); | ||
| 93 | - return json; | ||
| 94 | - } | ||
| 95 | - | ||
| 96 | } | 81 | } |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelService.java
| @@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | @@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 4 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelListReqVO; | 4 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelListReqVO; |
| 5 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelPageReqVO; | 5 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelPageReqVO; |
| 6 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelSaveReqVO; | 6 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelSaveReqVO; |
| 7 | -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelTSLRespVO; | ||
| 8 | import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; | 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; |
| 9 | import jakarta.validation.Valid; | 8 | import jakarta.validation.Valid; |
| 10 | 9 | ||
| @@ -91,12 +90,4 @@ public interface IotThingModelService { | @@ -91,12 +90,4 @@ public interface IotThingModelService { | ||
| 91 | */ | 90 | */ |
| 92 | Long getThingModelCount(LocalDateTime createTime); | 91 | Long getThingModelCount(LocalDateTime createTime); |
| 93 | 92 | ||
| 94 | - /** | ||
| 95 | - * 通过产品 ID 获取产品物模型 TSL | ||
| 96 | - * | ||
| 97 | - * @param productId 产品 ID | ||
| 98 | - * @return 产品物模型 TSL | ||
| 99 | - */ | ||
| 100 | - IotThingModelTSLRespVO getThingModelTslByProductId(Long productId); | ||
| 101 | - | ||
| 102 | } | 93 | } |
| 103 | \ No newline at end of file | 94 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelServiceImpl.java
| 1 | package cn.iocoder.yudao.module.iot.service.thingmodel; | 1 | package cn.iocoder.yudao.module.iot.service.thingmodel; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.collection.CollUtil; | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | -import cn.hutool.core.util.ObjUtil; | ||
| 5 | import cn.hutool.core.util.ObjectUtil; | 4 | import cn.hutool.core.util.ObjectUtil; |
| 6 | import cn.hutool.core.util.StrUtil; | 5 | import cn.hutool.core.util.StrUtil; |
| 7 | import cn.hutool.extra.spring.SpringUtil; | 6 | import cn.hutool.extra.spring.SpringUtil; |
| @@ -14,7 +13,6 @@ import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelS | @@ -14,7 +13,6 @@ import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelS | ||
| 14 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelListReqVO; | 13 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelListReqVO; |
| 15 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelPageReqVO; | 14 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelPageReqVO; |
| 16 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelSaveReqVO; | 15 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelSaveReqVO; |
| 17 | -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelTSLRespVO; | ||
| 18 | import cn.iocoder.yudao.module.iot.convert.thingmodel.IotThingModelConvert; | 16 | import cn.iocoder.yudao.module.iot.convert.thingmodel.IotThingModelConvert; |
| 19 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; | 17 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; |
| 20 | import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; | 18 | import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; |
| @@ -151,31 +149,6 @@ public class IotThingModelServiceImpl implements IotThingModelService { | @@ -151,31 +149,6 @@ public class IotThingModelServiceImpl implements IotThingModelService { | ||
| 151 | return thingModelMapper.selectList(reqVO); | 149 | return thingModelMapper.selectList(reqVO); |
| 152 | } | 150 | } |
| 153 | 151 | ||
| 154 | - // TODO @puhui999:这个转换,放在 controller 貌似也行? | ||
| 155 | - @Override | ||
| 156 | - public IotThingModelTSLRespVO getThingModelTslByProductId(Long productId) { | ||
| 157 | - IotThingModelTSLRespVO tslRespVO = new IotThingModelTSLRespVO(); | ||
| 158 | - // 1. 获得产品所有物模型定义 | ||
| 159 | - List<IotThingModelDO> thingModels = thingModelMapper.selectListByProductId(productId); | ||
| 160 | - if (CollUtil.isEmpty(thingModels)) { | ||
| 161 | - return tslRespVO; | ||
| 162 | - } | ||
| 163 | - | ||
| 164 | - // 2.1 设置公共部分参数 | ||
| 165 | - IotThingModelDO thingModel = thingModels.get(0); | ||
| 166 | - tslRespVO.setProductId(thingModel.getProductId()).setProductKey(thingModel.getProductKey()); | ||
| 167 | - // 2.2 处理属性列表 | ||
| 168 | - tslRespVO.setProperties(convertList(filterList(thingModels, item -> | ||
| 169 | - ObjUtil.equal(IotThingModelTypeEnum.PROPERTY.getType(), item.getType())), IotThingModelDO::getProperty)); | ||
| 170 | - // 2.3 处理服务列表 | ||
| 171 | - tslRespVO.setServices(convertList(filterList(thingModels, item -> | ||
| 172 | - ObjUtil.equal(IotThingModelTypeEnum.SERVICE.getType(), item.getType())), IotThingModelDO::getService)); | ||
| 173 | - // 2.4 处理事件列表 | ||
| 174 | - tslRespVO.setEvents(convertList(filterList(thingModels, item -> | ||
| 175 | - ObjUtil.equal(IotThingModelTypeEnum.EVENT.getType(), item.getType())), IotThingModelDO::getEvent)); | ||
| 176 | - return tslRespVO; | ||
| 177 | - } | ||
| 178 | - | ||
| 179 | /** | 152 | /** |
| 180 | * 校验功能是否存在 | 153 | * 校验功能是否存在 |
| 181 | * | 154 | * |
yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/rule/action/databridge/IotDataBridgeExecuteTest.java
| @@ -22,7 +22,7 @@ import static org.mockito.ArgumentMatchers.anyString; | @@ -22,7 +22,7 @@ import static org.mockito.ArgumentMatchers.anyString; | ||
| 22 | import static org.mockito.Mockito.when; | 22 | import static org.mockito.Mockito.when; |
| 23 | 23 | ||
| 24 | /** | 24 | /** |
| 25 | - * {@link IotDataBridgeExecute} 实现类的测试 | 25 | + * {@link IotDataBridgeExecute} 实现类的单元测试 |
| 26 | * | 26 | * |
| 27 | * @author HUIHUI | 27 | * @author HUIHUI |
| 28 | */ | 28 | */ |
| @@ -41,114 +41,125 @@ public class IotDataBridgeExecuteTest extends BaseMockitoUnitTest { | @@ -41,114 +41,125 @@ public class IotDataBridgeExecuteTest extends BaseMockitoUnitTest { | ||
| 41 | @BeforeEach | 41 | @BeforeEach |
| 42 | public void setUp() { | 42 | public void setUp() { |
| 43 | // 创建共享的测试消息 | 43 | // 创建共享的测试消息 |
| 44 | - message = IotDeviceMessage.builder().requestId("TEST-001").reportTime(LocalDateTime.now()).tenantId(1L) | ||
| 45 | - .productKey("testProduct").deviceName("testDevice").deviceKey("testDeviceKey") | ||
| 46 | - .type("property").identifier("temperature").data("{\"value\": 60}") | 44 | + message = IotDeviceMessage.builder() |
| 45 | + .requestId("TEST-001") | ||
| 46 | + .reportTime(LocalDateTime.now()) | ||
| 47 | + .tenantId(1L) | ||
| 48 | + .productKey("testProduct") | ||
| 49 | + .deviceName("testDevice") | ||
| 50 | + .deviceKey("testDeviceKey") | ||
| 51 | + .type("property") | ||
| 52 | + .identifier("temperature") | ||
| 53 | + .data("{\"value\": 60}") | ||
| 47 | .build(); | 54 | .build(); |
| 48 | - | ||
| 49 | - // 配置 RestTemplate mock 返回成功响应 | ||
| 50 | - // TODO @puhui999:这个应该放到 testHttpDataBridge 里 | ||
| 51 | - when(restTemplate.exchange(anyString(), any(HttpMethod.class), any(), any(Class.class))) | ||
| 52 | - .thenReturn(new ResponseEntity<>("Success", HttpStatus.OK)); | ||
| 53 | } | 55 | } |
| 54 | 56 | ||
| 55 | @Test | 57 | @Test |
| 56 | - public void testKafkaMQDataBridge() { | 58 | + public void testKafkaMQDataBridge() throws Exception { |
| 57 | // 1. 创建执行器实例 | 59 | // 1. 创建执行器实例 |
| 58 | IotKafkaMQDataBridgeExecute action = new IotKafkaMQDataBridgeExecute(); | 60 | IotKafkaMQDataBridgeExecute action = new IotKafkaMQDataBridgeExecute(); |
| 59 | 61 | ||
| 60 | // 2. 创建配置 | 62 | // 2. 创建配置 |
| 61 | - // TODO @puhui999:可以改成链式哈。 | ||
| 62 | - IotDataBridgeKafkaMQConfig config = new IotDataBridgeKafkaMQConfig(); | ||
| 63 | - config.setBootstrapServers("127.0.0.1:9092"); | ||
| 64 | - config.setTopic("test-topic"); | ||
| 65 | - config.setSsl(false); | ||
| 66 | - config.setUsername(null); | ||
| 67 | - config.setPassword(null); | ||
| 68 | - | ||
| 69 | - // 3. 执行两次测试,验证缓存 | ||
| 70 | - log.info("[testKafkaMQDataBridge][第一次执行,应该会创建新的 producer]"); | ||
| 71 | - action.execute(message, new IotDataBridgeDO().setType(action.getType()).setConfig(config)); | ||
| 72 | - | ||
| 73 | - log.info("[testKafkaMQDataBridge][第二次执行,应该会复用缓存的 producer]"); | ||
| 74 | - action.execute(message, new IotDataBridgeDO().setType(action.getType()).setConfig(config)); | 63 | + IotDataBridgeKafkaMQConfig config = new IotDataBridgeKafkaMQConfig() |
| 64 | + .setBootstrapServers("127.0.0.1:9092") | ||
| 65 | + .setTopic("test-topic") | ||
| 66 | + .setSsl(false) | ||
| 67 | + .setUsername(null) | ||
| 68 | + .setPassword(null); | ||
| 69 | + | ||
| 70 | + // 3. 执行测试并验证缓存 | ||
| 71 | + executeAndVerifyCache(action, config, "KafkaMQ"); | ||
| 75 | } | 72 | } |
| 76 | 73 | ||
| 77 | @Test | 74 | @Test |
| 78 | - public void testRabbitMQDataBridge() { | 75 | + public void testRabbitMQDataBridge() throws Exception { |
| 79 | // 1. 创建执行器实例 | 76 | // 1. 创建执行器实例 |
| 80 | IotRabbitMQDataBridgeExecute action = new IotRabbitMQDataBridgeExecute(); | 77 | IotRabbitMQDataBridgeExecute action = new IotRabbitMQDataBridgeExecute(); |
| 81 | 78 | ||
| 82 | // 2. 创建配置 | 79 | // 2. 创建配置 |
| 83 | - IotDataBridgeRabbitMQConfig config = new IotDataBridgeRabbitMQConfig(); | ||
| 84 | - config.setHost("localhost"); | ||
| 85 | - config.setPort(5672); | ||
| 86 | - config.setVirtualHost("/"); | ||
| 87 | - config.setUsername("admin"); | ||
| 88 | - config.setPassword("123456"); | ||
| 89 | - config.setExchange("test-exchange"); | ||
| 90 | - config.setRoutingKey("test-key"); | ||
| 91 | - config.setQueue("test-queue"); | ||
| 92 | - | ||
| 93 | - // 3. 执行两次测试,验证缓存 | ||
| 94 | - log.info("[testRabbitMQDataBridge][第一次执行,应该会创建新的 producer]"); | ||
| 95 | - action.execute(message, new IotDataBridgeDO().setType(action.getType()).setConfig(config)); | ||
| 96 | - | ||
| 97 | - log.info("[testRabbitMQDataBridge][第二次执行,应该会复用缓存的 producer]"); | ||
| 98 | - action.execute(message, new IotDataBridgeDO().setType(action.getType()).setConfig(config)); | 80 | + IotDataBridgeRabbitMQConfig config = new IotDataBridgeRabbitMQConfig() |
| 81 | + .setHost("localhost") | ||
| 82 | + .setPort(5672) | ||
| 83 | + .setVirtualHost("/") | ||
| 84 | + .setUsername("admin") | ||
| 85 | + .setPassword("123456") | ||
| 86 | + .setExchange("test-exchange") | ||
| 87 | + .setRoutingKey("test-key") | ||
| 88 | + .setQueue("test-queue"); | ||
| 89 | + | ||
| 90 | + // 3. 执行测试并验证缓存 | ||
| 91 | + executeAndVerifyCache(action, config, "RabbitMQ"); | ||
| 99 | } | 92 | } |
| 100 | 93 | ||
| 101 | @Test | 94 | @Test |
| 102 | - public void testRedisStreamMQDataBridge() { | 95 | + public void testRedisStreamDataBridge() throws Exception { |
| 103 | // 1. 创建执行器实例 | 96 | // 1. 创建执行器实例 |
| 104 | - IotRedisStreamMQDataBridgeExecute action = new IotRedisStreamMQDataBridgeExecute(); | 97 | + IotRedisStreamDataBridgeExecute action = new IotRedisStreamDataBridgeExecute(); |
| 105 | 98 | ||
| 106 | // 2. 创建配置 | 99 | // 2. 创建配置 |
| 107 | - IotDataBridgeRedisStreamMQConfig config = new IotDataBridgeRedisStreamMQConfig(); | ||
| 108 | - config.setHost("127.0.0.1"); | ||
| 109 | - config.setPort(6379); | ||
| 110 | - config.setDatabase(0); | ||
| 111 | - config.setPassword("123456"); | ||
| 112 | - config.setTopic("test-stream"); | ||
| 113 | - | ||
| 114 | - // 3. 执行两次测试,验证缓存 | ||
| 115 | - log.info("[testRedisStreamMQDataBridge][第一次执行,应该会创建新的 producer]"); | ||
| 116 | - action.execute(message, new IotDataBridgeDO().setType(action.getType()).setConfig(config)); | ||
| 117 | - | ||
| 118 | - log.info("[testRedisStreamMQDataBridge][第二次执行,应该会复用缓存的 producer]"); | ||
| 119 | - action.execute(message, new IotDataBridgeDO().setType(action.getType()).setConfig(config)); | 100 | + IotDataBridgeRedisStreamConfig config = new IotDataBridgeRedisStreamConfig() |
| 101 | + .setHost("127.0.0.1") | ||
| 102 | + .setPort(6379) | ||
| 103 | + .setDatabase(0) | ||
| 104 | + .setPassword("123456") | ||
| 105 | + .setTopic("test-stream"); | ||
| 106 | + | ||
| 107 | + // 3. 执行测试并验证缓存 | ||
| 108 | + executeAndVerifyCache(action, config, "RedisStream"); | ||
| 120 | } | 109 | } |
| 121 | 110 | ||
| 122 | @Test | 111 | @Test |
| 123 | - public void testRocketMQDataBridge() { | 112 | + public void testRocketMQDataBridge() throws Exception { |
| 124 | // 1. 创建执行器实例 | 113 | // 1. 创建执行器实例 |
| 125 | IotRocketMQDataBridgeExecute action = new IotRocketMQDataBridgeExecute(); | 114 | IotRocketMQDataBridgeExecute action = new IotRocketMQDataBridgeExecute(); |
| 126 | 115 | ||
| 127 | // 2. 创建配置 | 116 | // 2. 创建配置 |
| 128 | - IotDataBridgeRocketMQConfig config = new IotDataBridgeRocketMQConfig(); | ||
| 129 | - config.setNameServer("127.0.0.1:9876"); | ||
| 130 | - config.setGroup("test-group"); | ||
| 131 | - config.setTopic("test-topic"); | ||
| 132 | - config.setTags("test-tag"); | ||
| 133 | - | ||
| 134 | - // 3. 执行两次测试,验证缓存 | ||
| 135 | - log.info("[testRocketMQDataBridge][第一次执行,应该会创建新的 producer]"); | ||
| 136 | - action.execute(message, new IotDataBridgeDO().setType(action.getType()).setConfig(config)); | ||
| 137 | - | ||
| 138 | - log.info("[testRocketMQDataBridge][第二次执行,应该会复用缓存的 producer]"); | ||
| 139 | - action.execute(message, new IotDataBridgeDO().setType(action.getType()).setConfig(config)); | 117 | + IotDataBridgeRocketMQConfig config = new IotDataBridgeRocketMQConfig() |
| 118 | + .setNameServer("127.0.0.1:9876") | ||
| 119 | + .setGroup("test-group") | ||
| 120 | + .setTopic("test-topic") | ||
| 121 | + .setTags("test-tag"); | ||
| 122 | + | ||
| 123 | + // 3. 执行测试并验证缓存 | ||
| 124 | + executeAndVerifyCache(action, config, "RocketMQ"); | ||
| 140 | } | 125 | } |
| 141 | 126 | ||
| 142 | @Test | 127 | @Test |
| 143 | public void testHttpDataBridge() throws Exception { | 128 | public void testHttpDataBridge() throws Exception { |
| 144 | - // 创建配置 | ||
| 145 | - IotDataBridgeHttpConfig config = new IotDataBridgeHttpConfig(); | ||
| 146 | - config.setUrl("https://doc.iocoder.cn/"); | ||
| 147 | - config.setMethod(HttpMethod.GET.name()); | 129 | + // 1. 配置 RestTemplate mock 返回成功响应 |
| 130 | + when(restTemplate.exchange(anyString(), any(HttpMethod.class), any(), any(Class.class))) | ||
| 131 | + .thenReturn(new ResponseEntity<>("Success", HttpStatus.OK)); | ||
| 148 | 132 | ||
| 149 | - // 执行测试 | 133 | + // 2. 创建配置 |
| 134 | + IotDataBridgeHttpConfig config = new IotDataBridgeHttpConfig() | ||
| 135 | + .setUrl("https://doc.iocoder.cn/") | ||
| 136 | + .setMethod(HttpMethod.GET.name()); | ||
| 137 | + | ||
| 138 | + // 3. 执行测试 | ||
| 150 | log.info("[testHttpDataBridge][执行HTTP数据桥接测试]"); | 139 | log.info("[testHttpDataBridge][执行HTTP数据桥接测试]"); |
| 151 | - httpDataBridgeExecute.execute(message, new IotDataBridgeDO().setType(httpDataBridgeExecute.getType()).setConfig(config)); | 140 | + httpDataBridgeExecute.execute(message, new IotDataBridgeDO() |
| 141 | + .setType(httpDataBridgeExecute.getType()) | ||
| 142 | + .setConfig(config)); | ||
| 143 | + } | ||
| 144 | + | ||
| 145 | + /** | ||
| 146 | + * 执行测试并验证缓存的通用方法 | ||
| 147 | + * | ||
| 148 | + * @param action 执行器实例 | ||
| 149 | + * @param config 配置对象 | ||
| 150 | + * @param mqType MQ类型 | ||
| 151 | + * @throws Exception 如果执行过程中发生异常 | ||
| 152 | + */ | ||
| 153 | + private void executeAndVerifyCache(IotDataBridgeExecute<?> action, IotDataBridgeAbstractConfig config, String mqType) throws Exception { | ||
| 154 | + log.info("[test{}DataBridge][第一次执行,应该会创建新的 producer]", mqType); | ||
| 155 | + action.execute(message, new IotDataBridgeDO() | ||
| 156 | + .setType(action.getType()) | ||
| 157 | + .setConfig(config)); | ||
| 158 | + | ||
| 159 | + log.info("[test{}DataBridge][第二次执行,应该会复用缓存的 producer]", mqType); | ||
| 160 | + action.execute(message, new IotDataBridgeDO() | ||
| 161 | + .setType(action.getType()) | ||
| 162 | + .setConfig(config)); | ||
| 152 | } | 163 | } |
| 153 | 164 | ||
| 154 | } | 165 | } |