From 6d6547be392e6e22a345476775775d83f8660a72 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Tue, 18 Mar 2025 16:36:18 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E3=80=90=E5=8A=9F=E8=83=BD=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E3=80=91IoT:=20=E8=A7=84=E5=88=99=E5=9C=BA=E6=99=AF?= =?UTF-8?q?=E5=9F=BA=E7=A1=80=20CRUD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/iot/enums/ErrorCodeConstants.java | 3 + ...TriggerConditionParameterOperatorEnum.java | 2 +- .../admin/rule/IotRuleSceneController.java | 58 ++++++++- .../rule/vo/scene/IotRuleScenePageReqVO.java | 33 ++++++ .../rule/vo/scene/IotRuleSceneRespVO.java | 33 ++++++ .../rule/vo/scene/IotRuleSceneSaveReqVO.java | 37 ++++++ .../IotThinkModelFunctionController.http | 112 ------------------ .../dal/mysql/rule/IotRuleSceneMapper.java | 17 +++ .../iot/service/rule/IotRuleSceneService.java | 42 +++++++ .../service/rule/IotRuleSceneServiceImpl.java | 53 ++++++++- 10 files changed, 272 insertions(+), 118 deletions(-) create mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/IotRuleScenePageReqVO.java create mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/IotRuleSceneRespVO.java create mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/IotRuleSceneSaveReqVO.java delete mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thinkmodelfunction/IotThinkModelFunctionController.http diff --git a/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java b/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java index 230baca3f1..c719aeaa28 100644 --- a/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java +++ b/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java @@ -72,4 +72,7 @@ public interface ErrorCodeConstants { // ========== IoT 数据桥梁 1-050-010-000 ========== ErrorCode DATA_BRIDGE_NOT_EXISTS = new ErrorCode(1_050_010_000, "IoT 数据桥梁不存在"); + // ========== IoT 规则场景(场景联动) 1-050-011-000 ========== + ErrorCode RULE_SCENE_NOT_EXISTS = new ErrorCode(1_050_011_000, "IoT 规则场景(场景联动)不存在"); + } \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/rule/IotRuleSceneTriggerConditionParameterOperatorEnum.java b/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/rule/IotRuleSceneTriggerConditionParameterOperatorEnum.java index 5ed90ccae7..952e504412 100644 --- a/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/rule/IotRuleSceneTriggerConditionParameterOperatorEnum.java +++ b/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/rule/IotRuleSceneTriggerConditionParameterOperatorEnum.java @@ -50,7 +50,7 @@ public enum IotRuleSceneTriggerConditionParameterOperatorEnum implements ArrayVa /** * Spring 表达式 - 目标值数组 */ - public static final String SPRING_EXPRESSION_VALUE_List = "values"; + public static final String SPRING_EXPRESSION_VALUE_LIST = "values"; public static IotRuleSceneTriggerConditionParameterOperatorEnum operatorOf(String operator) { return ArrayUtil.firstMatch(item -> item.getOperator().equals(operator), values()); diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/IotRuleSceneController.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/IotRuleSceneController.java index 04e2f4570a..49e2ccde35 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/IotRuleSceneController.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/IotRuleSceneController.java @@ -1,13 +1,24 @@ package cn.iocoder.yudao.module.iot.controller.admin.rule; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleScenePageReqVO; +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleSceneRespVO; +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleSceneSaveReqVO; +import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; import cn.iocoder.yudao.module.iot.service.rule.IotRuleSceneService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; import jakarta.annotation.security.PermitAll; +import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @Tag(name = "管理后台 - IoT 规则场景") @RestController @@ -18,6 +29,47 @@ public class IotRuleSceneController { @Resource private IotRuleSceneService ruleSceneService; + @PostMapping("/create") + @Operation(summary = "创建规则场景(场景联动)") + @PreAuthorize("@ss.hasPermission('iot:rule-scene:create')") + public CommonResult createRuleScene(@Valid @RequestBody IotRuleSceneSaveReqVO createReqVO) { + return success(ruleSceneService.createRuleScene(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新规则场景(场景联动)") + @PreAuthorize("@ss.hasPermission('iot:rule-scene:update')") + public CommonResult updateRuleScene(@Valid @RequestBody IotRuleSceneSaveReqVO updateReqVO) { + ruleSceneService.updateRuleScene(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除规则场景(场景联动)") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('iot:rule-scene:delete')") + public CommonResult deleteRuleScene(@RequestParam("id") Long id) { + ruleSceneService.deleteRuleScene(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得规则场景(场景联动)") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('iot:rule-scene:query')") + public CommonResult getRuleScene(@RequestParam("id") Long id) { + IotRuleSceneDO ruleScene = ruleSceneService.getRuleScene(id); + return success(BeanUtils.toBean(ruleScene, IotRuleSceneRespVO.class)); + } + + @GetMapping("/page") + @Operation(summary = "获得规则场景(场景联动)分页") + @PreAuthorize("@ss.hasPermission('iot:rule-scene:query')") + public CommonResult> getRuleScenePage(@Valid IotRuleScenePageReqVO pageReqVO) { + PageResult pageResult = ruleSceneService.getRuleScenePage(pageReqVO); + return success(BeanUtils.toBean(pageResult, IotRuleSceneRespVO.class)); + } + @GetMapping("/test") @PermitAll public void test() { diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/IotRuleScenePageReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/IotRuleScenePageReqVO.java new file mode 100644 index 0000000000..43d0e4a5c9 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/IotRuleScenePageReqVO.java @@ -0,0 +1,33 @@ +package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - IoT 规则场景(场景联动)分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class IotRuleScenePageReqVO extends PageParam { + + @Schema(description = "场景名称", example = "赵六") + private String name; + + @Schema(description = "场景描述", example = "你猜") + private String description; + + @Schema(description = "场景状态", example = "1") + private Integer status; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/IotRuleSceneRespVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/IotRuleSceneRespVO.java new file mode 100644 index 0000000000..0919e63d66 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/IotRuleSceneRespVO.java @@ -0,0 +1,33 @@ +package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - IoT 规则场景(场景联动) Response VO") +@Data +public class IotRuleSceneRespVO { + + @Schema(description = "场景编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "15865") + private Long id; + + @Schema(description = "场景名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六") + private String name; + + @Schema(description = "场景描述", example = "你猜") + private String description; + + @Schema(description = "场景状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Integer status; + + @Schema(description = "触发器数组", requiredMode = Schema.RequiredMode.REQUIRED) + private String triggers; + + @Schema(description = "执行器数组", requiredMode = Schema.RequiredMode.REQUIRED) + private String actions; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + private LocalDateTime createTime; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/IotRuleSceneSaveReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/IotRuleSceneSaveReqVO.java new file mode 100644 index 0000000000..828234fb84 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/IotRuleSceneSaveReqVO.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +@Schema(description = "管理后台 - IoT 规则场景(场景联动)新增/修改 Request VO") +@Data +public class IotRuleSceneSaveReqVO { + + @Schema(description = "场景编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "15865") + private Long id; + + @Schema(description = "场景名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六") + @NotEmpty(message = "场景名称不能为空") + private String name; + + @Schema(description = "场景描述", example = "你猜") + private String description; + + @Schema(description = "场景状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") + @NotNull(message = "场景状态不能为空") + @InEnum(CommonStatusEnum.class) + private Integer status; + + @Schema(description = "触发器数组", requiredMode = Schema.RequiredMode.REQUIRED) + @NotEmpty(message = "触发器数组不能为空") + private String triggers; + + @Schema(description = "执行器数组", requiredMode = Schema.RequiredMode.REQUIRED) + @NotEmpty(message = "执行器数组不能为空") + private String actions; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thinkmodelfunction/IotThinkModelFunctionController.http b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thinkmodelfunction/IotThinkModelFunctionController.http deleted file mode 100644 index 84446b0ced..0000000000 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thinkmodelfunction/IotThinkModelFunctionController.http +++ /dev/null @@ -1,112 +0,0 @@ -### 请求 /iot/think-model-function/create 接口 => 成功 -POST {{baseUrl}}/iot/think-model-function/create -Content-Type: application/json -tenant-id: {{adminTenantId}} -Authorization: Bearer {{token}} - -{ - "productId": 1001, - "productKey": "smart-sensor-001", - "identifier": "Temperature", - "name": "温度", - "description": "当前温度值", - "type": 1, - "property": { - "identifier": "Temperature", - "name": "温度", - "accessMode": "r", - "required": true, - "dataType": { - "type": "float", - "specs": { - "min": -10.0, - "max": 100.0, - "step": 0.1, - "unit": "℃" - } - }, - "description": "当前温度值" - } -} - -### 请求 /iot/think-model-function/create 接口 => 成功 -POST {{baseUrl}}/iot/think-model-function/create -Content-Type: application/json -tenant-id: {{adminTenantId}} -Authorization: Bearer {{token}} - -{ - "productId": 1001, - "productKey": "smart-sensor-001", - "identifier": "Humidity", - "name": "湿度", - "description": "当前湿度值", - "type": 1, - "property": { - "identifier": "Humidity", - "name": "湿度", - "accessMode": "r", - "required": true, - "dataType": { - "type": "float", - "specs": { - "min": 0.0, - "max": 100.0, - "step": 0.1, - "unit": "%" - } - }, - "description": "当前湿度值" - } -} - - - - -### 请求 /iot/think-model-function/update 接口 => 成功 -PUT {{baseUrl}}/iot/think-model-function/update -Content-Type: application/json -tenant-id: {{adminTenantId}} -Authorization: Bearer {{token}} - -{ - "id": 11, - "productId": 1001, - "productKey": "smart-sensor-001", - "identifier": "Temperature", - "name": "温度", - "description": "当前温度值", - "type": 1, - "property": { - "identifier": "Temperature", - "name": "温度", - "accessMode": "r", - "required": true, - "dataType": { - "type": "float", - "specs": { - "min": -111.0, - "max": 222.0, - "step": 0.1, - "unit": "℃" - } - }, - "description": "当前温度值" - } -} - -### 请求 /iot/think-model-function/delete 接口 => 成功 -DELETE {{baseUrl}}/iot/think-model-function/delete?id=7 -tenant-id: {{adminTenantId}} -Authorization: Bearer {{token}} - -### 请求 /iot/think-model-function/get 接口 => 成功 -GET {{baseUrl}}/iot/think-model-function/get?id=10 -tenant-id: {{adminTenantId}} -Authorization: Bearer {{token}} - - -### 请求 /iot/think-model-function/list-by-product-id 接口 => 成功 -GET {{baseUrl}}/iot/think-model-function/list-by-product-id?productId=1001 -tenant-id: {{adminTenantId}} -Authorization: Bearer {{token}} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/rule/IotRuleSceneMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/rule/IotRuleSceneMapper.java index e5e069a0cb..4f933727e7 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/rule/IotRuleSceneMapper.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/rule/IotRuleSceneMapper.java @@ -1,10 +1,27 @@ package cn.iocoder.yudao.module.iot.dal.mysql.rule; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleScenePageReqVO; import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; import org.apache.ibatis.annotations.Mapper; +/** + * IoT 规则场景(场景联动) Mapper + * + * @author HUIHUI + */ @Mapper public interface IotRuleSceneMapper extends BaseMapperX { + default PageResult selectPage(IotRuleScenePageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(IotRuleSceneDO::getName, reqVO.getName()) + .likeIfPresent(IotRuleSceneDO::getDescription, reqVO.getDescription()) + .eqIfPresent(IotRuleSceneDO::getStatus, reqVO.getStatus()) + .betweenIfPresent(IotRuleSceneDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(IotRuleSceneDO::getId)); + } + } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/IotRuleSceneService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/IotRuleSceneService.java index 6927b11725..e2be7f40f7 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/IotRuleSceneService.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/IotRuleSceneService.java @@ -1,8 +1,12 @@ package cn.iocoder.yudao.module.iot.service.rule; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleScenePageReqVO; +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleSceneSaveReqVO; import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneTriggerTypeEnum; import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; +import jakarta.validation.Valid; import java.util.List; @@ -13,6 +17,44 @@ import java.util.List; */ public interface IotRuleSceneService { + /** + * 创建规则场景(场景联动) + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createRuleScene(@Valid IotRuleSceneSaveReqVO createReqVO); + + /** + * 更新规则场景(场景联动) + * + * @param updateReqVO 更新信息 + */ + void updateRuleScene(@Valid IotRuleSceneSaveReqVO updateReqVO); + + /** + * 删除规则场景(场景联动) + * + * @param id 编号 + */ + void deleteRuleScene(Long id); + + /** + * 获得规则场景(场景联动) + * + * @param id 编号 + * @return 规则场景(场景联动) + */ + IotRuleSceneDO getRuleScene(Long id); + + /** + * 获得规则场景(场景联动)分页 + * + * @param pageReqVO 分页查询 + * @return 规则场景(场景联动)分页 + */ + PageResult getRuleScenePage(IotRuleScenePageReqVO pageReqVO); + /** * 【缓存】获得指定设备的场景列表 * diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/IotRuleSceneServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/IotRuleSceneServiceImpl.java index 2219d4bad1..c3e027fbb0 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/IotRuleSceneServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/IotRuleSceneServiceImpl.java @@ -8,11 +8,15 @@ import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.number.NumberUtils; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.framework.common.util.spring.SpringExpressionUtils; import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleScenePageReqVO; +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleSceneSaveReqVO; import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; import cn.iocoder.yudao.module.iot.dal.mysql.rule.IotRuleSceneMapper; import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum; @@ -39,8 +43,10 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList; +import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.RULE_SCENE_NOT_EXISTS; /** * IoT 规则场景 Service 实现类 @@ -61,6 +67,49 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { @Resource(name = "iotSchedulerManager") private IotSchedulerManager schedulerManager; + @Override + public Long createRuleScene(IotRuleSceneSaveReqVO createReqVO) { + // 插入 + IotRuleSceneDO ruleScene = BeanUtils.toBean(createReqVO, IotRuleSceneDO.class); + ruleSceneMapper.insert(ruleScene); + // 返回 + return ruleScene.getId(); + } + + @Override + public void updateRuleScene(IotRuleSceneSaveReqVO updateReqVO) { + // 校验存在 + validateRuleSceneExists(updateReqVO.getId()); + // 更新 + IotRuleSceneDO updateObj = BeanUtils.toBean(updateReqVO, IotRuleSceneDO.class); + ruleSceneMapper.updateById(updateObj); + } + + @Override + public void deleteRuleScene(Long id) { + // 校验存在 + validateRuleSceneExists(id); + // 删除 + ruleSceneMapper.deleteById(id); + } + + private void validateRuleSceneExists(Long id) { + if (ruleSceneMapper.selectById(id) == null) { + throw exception(RULE_SCENE_NOT_EXISTS); + } + } + + @Override + public IotRuleSceneDO getRuleScene(Long id) { + return ruleSceneMapper.selectById(id); + } + + @Override + public PageResult getRuleScenePage(IotRuleScenePageReqVO pageReqVO) { + return ruleSceneMapper.selectPage(pageReqVO); + } + + // TODO 芋艿,缓存待实现 @Override @TenantIgnore // 忽略租户隔离:因为 IotRuleSceneMessageHandler 调用时,一般未传递租户,所以需要忽略 @@ -331,7 +380,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { springExpressionVariables.put(IotRuleSceneTriggerConditionParameterOperatorEnum.SPRING_EXPRESSION_SOURCE, messageValue); springExpressionVariables.put(IotRuleSceneTriggerConditionParameterOperatorEnum.SPRING_EXPRESSION_VALUE, parameter.getValue()); List parameterValues = StrUtil.splitTrim(parameter.getValue(), CharPool.COMMA); - springExpressionVariables.put(IotRuleSceneTriggerConditionParameterOperatorEnum.SPRING_EXPRESSION_VALUE_List, parameterValues); + springExpressionVariables.put(IotRuleSceneTriggerConditionParameterOperatorEnum.SPRING_EXPRESSION_VALUE_LIST, parameterValues); // 特殊:解决数字的比较。因为 Spring 是基于它的 compareTo 方法,对数字的比较存在问题! if (ObjectUtils.equalsAny(operator, IotRuleSceneTriggerConditionParameterOperatorEnum.BETWEEN, IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_BETWEEN, @@ -345,7 +394,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { NumberUtil.parseDouble(messageValue)); springExpressionVariables.put(IotRuleSceneTriggerConditionParameterOperatorEnum.SPRING_EXPRESSION_VALUE, NumberUtil.parseDouble(parameter.getValue())); - springExpressionVariables.put(IotRuleSceneTriggerConditionParameterOperatorEnum.SPRING_EXPRESSION_VALUE_List, + springExpressionVariables.put(IotRuleSceneTriggerConditionParameterOperatorEnum.SPRING_EXPRESSION_VALUE_LIST, convertList(parameterValues, NumberUtil::parseDouble)); } // 2.2 计算 Spring 表达式 From f118d66006d7e9f1ac7ef39177022692b19612bd Mon Sep 17 00:00:00 2001 From: puhui999 Date: Tue, 18 Mar 2025 16:51:08 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E3=80=90=E4=BB=A3=E7=A0=81=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E3=80=91IoT:=20=E8=A7=84=E5=88=99=E5=9C=BA=E6=99=AF?= =?UTF-8?q?=20config=20=E6=8A=BD=E7=A6=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rule/vo/scene/IotRuleSceneRespVO.java | 7 +- .../rule/vo/scene/IotRuleSceneSaveReqVO.java | 8 +- .../config/IotRuleSceneActionConfig.java | 37 ++++ .../IotRuleSceneActionDeviceControl.java | 57 +++++ .../config/IotRuleSceneTriggerCondition.java | 37 ++++ ...IotRuleSceneTriggerConditionParameter.java | 37 ++++ .../config/IotRuleSceneTriggerConfig.java | 53 +++++ .../dal/dataobject/rule/IotRuleSceneDO.java | 196 +----------------- .../service/rule/IotRuleSceneServiceImpl.java | 90 ++++---- .../rule/action/IotRuleSceneAction.java | 7 +- .../rule/action/IotRuleSceneAlertAction.java | 4 +- .../action/IotRuleSceneDataBridgeAction.java | 4 +- .../IotRuleSceneDeviceControlAction.java | 7 +- 13 files changed, 298 insertions(+), 246 deletions(-) create mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/config/IotRuleSceneActionConfig.java create mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/config/IotRuleSceneActionDeviceControl.java create mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/config/IotRuleSceneTriggerCondition.java create mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/config/IotRuleSceneTriggerConditionParameter.java create mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/config/IotRuleSceneTriggerConfig.java diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/IotRuleSceneRespVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/IotRuleSceneRespVO.java index 0919e63d66..17aad11859 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/IotRuleSceneRespVO.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/IotRuleSceneRespVO.java @@ -1,9 +1,12 @@ package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene; +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config.IotRuleSceneActionConfig; +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config.IotRuleSceneTriggerConfig; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.time.LocalDateTime; +import java.util.List; @Schema(description = "管理后台 - IoT 规则场景(场景联动) Response VO") @Data @@ -22,10 +25,10 @@ public class IotRuleSceneRespVO { private Integer status; @Schema(description = "触发器数组", requiredMode = Schema.RequiredMode.REQUIRED) - private String triggers; + private List triggers; @Schema(description = "执行器数组", requiredMode = Schema.RequiredMode.REQUIRED) - private String actions; + private List actions; @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) private LocalDateTime createTime; diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/IotRuleSceneSaveReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/IotRuleSceneSaveReqVO.java index 828234fb84..4bfc19d9a2 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/IotRuleSceneSaveReqVO.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/IotRuleSceneSaveReqVO.java @@ -2,11 +2,15 @@ package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config.IotRuleSceneActionConfig; +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config.IotRuleSceneTriggerConfig; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import lombok.Data; +import java.util.List; + @Schema(description = "管理后台 - IoT 规则场景(场景联动)新增/修改 Request VO") @Data public class IotRuleSceneSaveReqVO { @@ -28,10 +32,10 @@ public class IotRuleSceneSaveReqVO { @Schema(description = "触发器数组", requiredMode = Schema.RequiredMode.REQUIRED) @NotEmpty(message = "触发器数组不能为空") - private String triggers; + private List triggers; @Schema(description = "执行器数组", requiredMode = Schema.RequiredMode.REQUIRED) @NotEmpty(message = "执行器数组不能为空") - private String actions; + private List actions; } \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/config/IotRuleSceneActionConfig.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/config/IotRuleSceneActionConfig.java new file mode 100644 index 0000000000..40bab940f8 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/config/IotRuleSceneActionConfig.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config; + +import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; +import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum; +import lombok.Data; + +/** + * 执行器配置 + * + * @author 芋道源码 + */ +@Data +public class IotRuleSceneActionConfig { + + /** + * 执行类型 + * + * 枚举 {@link IotRuleSceneActionTypeEnum} + */ + private Integer type; + + /** + * 设备控制 + * + * 必填:当 {@link #type} 为 {@link IotRuleSceneActionTypeEnum#DEVICE_CONTROL} 时 + */ + private IotRuleSceneActionDeviceControl deviceControl; + + /** + * 数据桥接编号 + * + * 必填:当 {@link #type} 为 {@link IotRuleSceneActionTypeEnum#DATA_BRIDGE} 时 + * 关联:{@link IotDataBridgeDO#getId()} + */ + private Long dataBridgeId; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/config/IotRuleSceneActionDeviceControl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/config/IotRuleSceneActionDeviceControl.java new file mode 100644 index 0000000000..31796fb21e --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/config/IotRuleSceneActionDeviceControl.java @@ -0,0 +1,57 @@ +package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config; + +import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; +import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; +import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum; +import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * 执行设备控制 + * + * @author 芋道源码 + */ +@Data +public class IotRuleSceneActionDeviceControl { + + /** + * 产品标识 + * + * 关联 {@link IotProductDO#getProductKey()} + */ + private String productKey; + /** + * 设备名称数组 + * + * 关联 {@link IotDeviceDO#getDeviceName()} + */ + private List deviceNames; + + /** + * 消息类型 + * + * 枚举 {@link IotDeviceMessageTypeEnum#PROPERTY}、{@link IotDeviceMessageTypeEnum#SERVICE} + */ + private String type; + /** + * 消息标识符 + * + * 枚举 {@link IotDeviceMessageIdentifierEnum} + * + * 1. 属性设置:对应 {@link IotDeviceMessageIdentifierEnum#PROPERTY_SET} + * 2. 服务调用:对应 {@link IotDeviceMessageIdentifierEnum#SERVICE_INVOKE} + */ + private String identifier; + + /** + * 具体数据 + * + * 1. 属性设置:在 {@link #type} 是 {@link IotDeviceMessageTypeEnum#PROPERTY} 时,对应 properties + * 2. 服务调用:在 {@link #type} 是 {@link IotDeviceMessageTypeEnum#SERVICE} 时,对应 params + */ + private Map data; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/config/IotRuleSceneTriggerCondition.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/config/IotRuleSceneTriggerCondition.java new file mode 100644 index 0000000000..1f5e2adfec --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/config/IotRuleSceneTriggerCondition.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config; + +import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum; +import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum; +import lombok.Data; + +import java.util.List; + +/** + * 触发条件 + * + * @author 芋道源码 + */ +@Data +public class IotRuleSceneTriggerCondition { + + /** + * 消息类型 + * + * 枚举 {@link IotDeviceMessageTypeEnum} + */ + private String type; + /** + * 消息标识符 + * + * 枚举 {@link IotDeviceMessageIdentifierEnum} + */ + private String identifier; + + /** + * 参数数组 + * + * 参数与参数之间,是“或”的关系 + */ + private List parameters; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/config/IotRuleSceneTriggerConditionParameter.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/config/IotRuleSceneTriggerConditionParameter.java new file mode 100644 index 0000000000..38d4594220 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/config/IotRuleSceneTriggerConditionParameter.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config; + +import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; +import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneTriggerConditionParameterOperatorEnum; +import lombok.Data; + +/** + * 触发条件参数 + * + * @author 芋道源码 + */ +@Data +public class IotRuleSceneTriggerConditionParameter { + + /** + * 标识符(属性、事件、服务) + * + * 关联 {@link IotThingModelDO#getIdentifier()} + */ + private String identifier; + + /** + * 操作符 + * + * 枚举 {@link IotRuleSceneTriggerConditionParameterOperatorEnum} + */ + private String operator; + + /** + * 比较值 + * + * 如果有多个值,则使用 "," 分隔,类似 "1,2,3"。 + * 例如说,{@link IotRuleSceneTriggerConditionParameterOperatorEnum#IN}、{@link IotRuleSceneTriggerConditionParameterOperatorEnum#BETWEEN} + */ + private String value; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/config/IotRuleSceneTriggerConfig.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/config/IotRuleSceneTriggerConfig.java new file mode 100644 index 0000000000..0be36c1d6e --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/config/IotRuleSceneTriggerConfig.java @@ -0,0 +1,53 @@ +package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config; + +import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; +import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; +import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneTriggerTypeEnum; +import lombok.Data; + +import java.util.List; + +/** + * 触发器配置 + * + * @author 芋道源码 + */ +@Data +public class IotRuleSceneTriggerConfig { + + /** + * 触发类型 + * + * 枚举 {@link IotRuleSceneTriggerTypeEnum} + */ + private Integer type; + + /** + * 产品标识 + * + * 关联 {@link IotProductDO#getProductKey()} + */ + private String productKey; + /** + * 设备名称数组 + * + * 关联 {@link IotDeviceDO#getDeviceName()} + */ + private List deviceNames; + + /** + * 触发条件数组 + * + * 必填:当 {@link #type} 为 {@link IotRuleSceneTriggerTypeEnum#DEVICE} 时 + * 条件与条件之间,是“或”的关系 + */ + private List conditions; + + /** + * CRON 表达式 + * + * 必填:当 {@link #type} 为 {@link IotRuleSceneTriggerTypeEnum#TIMER} 时 + */ + private String cronExpression; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/rule/IotRuleSceneDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/rule/IotRuleSceneDO.java index f50101a4ed..49741cc79b 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/rule/IotRuleSceneDO.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/rule/IotRuleSceneDO.java @@ -1,23 +1,19 @@ package cn.iocoder.yudao.module.iot.dal.dataobject.rule; import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; -import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; -import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; -import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; -import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum; -import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum; -import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum; -import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneTriggerConditionParameterOperatorEnum; -import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneTriggerTypeEnum; +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config.IotRuleSceneActionConfig; +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config.IotRuleSceneTriggerConfig; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; -import lombok.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; import java.util.List; -import java.util.Map; /** * IoT 规则场景(场景联动) DO @@ -56,188 +52,12 @@ public class IotRuleSceneDO extends TenantBaseDO { * 触发器数组 */ @TableField(typeHandler = JacksonTypeHandler.class) - private List triggers; + private List triggers; /** * 执行器数组 */ @TableField(typeHandler = JacksonTypeHandler.class) - private List actions; - - /** - * 触发器配置 - */ - @Data - public static class TriggerConfig { - - /** - * 触发类型 - * - * 枚举 {@link IotRuleSceneTriggerTypeEnum} - */ - private Integer type; - - /** - * 产品标识 - * - * 关联 {@link IotProductDO#getProductKey()} - */ - private String productKey; - /** - * 设备名称数组 - * - * 关联 {@link IotDeviceDO#getDeviceName()} - */ - private List deviceNames; - - /** - * 触发条件数组 - * - * 必填:当 {@link #type} 为 {@link IotRuleSceneTriggerTypeEnum#DEVICE} 时 - * 条件与条件之间,是“或”的关系 - */ - private List conditions; - - /** - * CRON 表达式 - * - * 必填:当 {@link #type} 为 {@link IotRuleSceneTriggerTypeEnum#TIMER} 时 - */ - private String cronExpression; - - } - - /** - * 触发条件 - */ - @Data - public static class TriggerCondition { - - /** - * 消息类型 - * - * 枚举 {@link IotDeviceMessageTypeEnum} - */ - private String type; - /** - * 消息标识符 - * - * 枚举 {@link IotDeviceMessageIdentifierEnum} - */ - private String identifier; - - /** - * 参数数组 - * - * 参数与参数之间,是“或”的关系 - */ - private List parameters; - - } - - /** - * 触发条件参数 - */ - @Data - public static class TriggerConditionParameter { - - /** - * 标识符(属性、事件、服务) - * - * 关联 {@link IotThingModelDO#getIdentifier()} - */ - private String identifier; - - /** - * 操作符 - * - * 枚举 {@link IotRuleSceneTriggerConditionParameterOperatorEnum} - */ - private String operator; - - /** - * 比较值 - * - * 如果有多个值,则使用 "," 分隔,类似 "1,2,3"。 - * 例如说,{@link IotRuleSceneTriggerConditionParameterOperatorEnum#IN}、{@link IotRuleSceneTriggerConditionParameterOperatorEnum#BETWEEN} - */ - private String value; - - } - - /** - * 执行器配置 - */ - @Data - public static class ActionConfig { - - /** - * 执行类型 - * - * 枚举 {@link IotRuleSceneActionTypeEnum} - */ - private Integer type; - - /** - * 设备控制 - * - * 必填:当 {@link #type} 为 {@link IotRuleSceneActionTypeEnum#DEVICE_CONTROL} 时 - */ - private ActionDeviceControl deviceControl; - - /** - * 数据桥接编号 - * - * 必填:当 {@link #type} 为 {@link IotRuleSceneActionTypeEnum#DATA_BRIDGE} 时 - * 关联:{@link IotDataBridgeDO#getId()} - */ - private Long dataBridgeId; - - } - - /** - * 执行设备控制 - */ - @Data - public static class ActionDeviceControl { - - /** - * 产品标识 - * - * 关联 {@link IotProductDO#getProductKey()} - */ - private String productKey; - /** - * 设备名称数组 - * - * 关联 {@link IotDeviceDO#getDeviceName()} - */ - private List deviceNames; - - /** - * 消息类型 - * - * 枚举 {@link IotDeviceMessageTypeEnum#PROPERTY}、{@link IotDeviceMessageTypeEnum#SERVICE} - */ - private String type; - /** - * 消息标识符 - * - * 枚举 {@link IotDeviceMessageIdentifierEnum} - * - * 1. 属性设置:对应 {@link IotDeviceMessageIdentifierEnum#PROPERTY_SET} - * 2. 服务调用:对应 {@link IotDeviceMessageIdentifierEnum#SERVICE_INVOKE} - */ - private String identifier; - - /** - * 具体数据 - * - * 1. 属性设置:在 {@link #type} 是 {@link IotDeviceMessageTypeEnum#PROPERTY} 时,对应 properties - * 2. 服务调用:在 {@link #type} 是 {@link IotDeviceMessageTypeEnum#SERVICE} 时,对应 params - */ - private Map data; - - } + private List actions; } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/IotRuleSceneServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/IotRuleSceneServiceImpl.java index c3e027fbb0..d5ca74f555 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/IotRuleSceneServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/IotRuleSceneServiceImpl.java @@ -17,6 +17,7 @@ import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleScenePageReqVO; import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleSceneSaveReqVO; +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config.*; import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; import cn.iocoder.yudao.module.iot.dal.mysql.rule.IotRuleSceneMapper; import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum; @@ -117,82 +118,82 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { if (true) { IotRuleSceneDO ruleScene01 = new IotRuleSceneDO(); ruleScene01.setTriggers(CollUtil.newArrayList()); - IotRuleSceneDO.TriggerConfig trigger01 = new IotRuleSceneDO.TriggerConfig(); + IotRuleSceneTriggerConfig trigger01 = new IotRuleSceneTriggerConfig(); trigger01.setType(IotRuleSceneTriggerTypeEnum.DEVICE.getType()); trigger01.setConditions(CollUtil.newArrayList()); // 属性 - IotRuleSceneDO.TriggerCondition condition01 = new IotRuleSceneDO.TriggerCondition(); + IotRuleSceneTriggerCondition condition01 = new IotRuleSceneTriggerCondition(); condition01.setType(IotDeviceMessageTypeEnum.PROPERTY.getType()); condition01.setIdentifier(IotDeviceMessageIdentifierEnum.PROPERTY_REPORT.getIdentifier()); condition01.setParameters(CollUtil.newArrayList()); -// IotRuleSceneDO.TriggerConditionParameter parameter010 = new IotRuleSceneDO.TriggerConditionParameter(); +// IotRuleSceneTriggerConditionParameter parameter010 = new IotRuleSceneTriggerConditionParameter(); // parameter010.setIdentifier("width"); // parameter010.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.getOperator()); // parameter010.setValue("abc"); // condition01.getParameters().add(parameter010); - IotRuleSceneDO.TriggerConditionParameter parameter011 = new IotRuleSceneDO.TriggerConditionParameter(); + IotRuleSceneTriggerConditionParameter parameter011 = new IotRuleSceneTriggerConditionParameter(); parameter011.setIdentifier("width"); parameter011.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.getOperator()); parameter011.setValue("1"); condition01.getParameters().add(parameter011); - IotRuleSceneDO.TriggerConditionParameter parameter012 = new IotRuleSceneDO.TriggerConditionParameter(); + IotRuleSceneTriggerConditionParameter parameter012 = new IotRuleSceneTriggerConditionParameter(); parameter012.setIdentifier("width"); parameter012.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_EQUALS.getOperator()); parameter012.setValue("2"); condition01.getParameters().add(parameter012); - IotRuleSceneDO.TriggerConditionParameter parameter013 = new IotRuleSceneDO.TriggerConditionParameter(); + IotRuleSceneTriggerConditionParameter parameter013 = new IotRuleSceneTriggerConditionParameter(); parameter013.setIdentifier("width"); parameter013.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.GREATER_THAN.getOperator()); parameter013.setValue("0"); condition01.getParameters().add(parameter013); - IotRuleSceneDO.TriggerConditionParameter parameter014 = new IotRuleSceneDO.TriggerConditionParameter(); + IotRuleSceneTriggerConditionParameter parameter014 = new IotRuleSceneTriggerConditionParameter(); parameter014.setIdentifier("width"); parameter014.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.GREATER_THAN_OR_EQUALS.getOperator()); parameter014.setValue("0"); condition01.getParameters().add(parameter014); - IotRuleSceneDO.TriggerConditionParameter parameter015 = new IotRuleSceneDO.TriggerConditionParameter(); + IotRuleSceneTriggerConditionParameter parameter015 = new IotRuleSceneTriggerConditionParameter(); parameter015.setIdentifier("width"); parameter015.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.LESS_THAN.getOperator()); parameter015.setValue("2"); condition01.getParameters().add(parameter015); - IotRuleSceneDO.TriggerConditionParameter parameter016 = new IotRuleSceneDO.TriggerConditionParameter(); + IotRuleSceneTriggerConditionParameter parameter016 = new IotRuleSceneTriggerConditionParameter(); parameter016.setIdentifier("width"); parameter016.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.LESS_THAN_OR_EQUALS.getOperator()); parameter016.setValue("2"); condition01.getParameters().add(parameter016); - IotRuleSceneDO.TriggerConditionParameter parameter017 = new IotRuleSceneDO.TriggerConditionParameter(); + IotRuleSceneTriggerConditionParameter parameter017 = new IotRuleSceneTriggerConditionParameter(); parameter017.setIdentifier("width"); parameter017.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.IN.getOperator()); parameter017.setValue("1,2,3"); condition01.getParameters().add(parameter017); - IotRuleSceneDO.TriggerConditionParameter parameter018 = new IotRuleSceneDO.TriggerConditionParameter(); + IotRuleSceneTriggerConditionParameter parameter018 = new IotRuleSceneTriggerConditionParameter(); parameter018.setIdentifier("width"); parameter018.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_IN.getOperator()); parameter018.setValue("0,2,3"); condition01.getParameters().add(parameter018); - IotRuleSceneDO.TriggerConditionParameter parameter019 = new IotRuleSceneDO.TriggerConditionParameter(); + IotRuleSceneTriggerConditionParameter parameter019 = new IotRuleSceneTriggerConditionParameter(); parameter019.setIdentifier("width"); parameter019.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.BETWEEN.getOperator()); parameter019.setValue("1,3"); condition01.getParameters().add(parameter019); - IotRuleSceneDO.TriggerConditionParameter parameter020 = new IotRuleSceneDO.TriggerConditionParameter(); + IotRuleSceneTriggerConditionParameter parameter020 = new IotRuleSceneTriggerConditionParameter(); parameter020.setIdentifier("width"); parameter020.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_BETWEEN.getOperator()); parameter020.setValue("2,3"); condition01.getParameters().add(parameter020); trigger01.getConditions().add(condition01); // 状态 - IotRuleSceneDO.TriggerCondition condition02 = new IotRuleSceneDO.TriggerCondition(); + IotRuleSceneTriggerCondition condition02 = new IotRuleSceneTriggerCondition(); condition02.setType(IotDeviceMessageTypeEnum.STATE.getType()); condition02.setIdentifier(IotDeviceMessageIdentifierEnum.STATE_ONLINE.getIdentifier()); condition02.setParameters(CollUtil.newArrayList()); trigger01.getConditions().add(condition02); // 事件 - IotRuleSceneDO.TriggerCondition condition03 = new IotRuleSceneDO.TriggerCondition(); + IotRuleSceneTriggerCondition condition03 = new IotRuleSceneTriggerCondition(); condition03.setType(IotDeviceMessageTypeEnum.EVENT.getType()); condition03.setIdentifier("xxx"); condition03.setParameters(CollUtil.newArrayList()); - IotRuleSceneDO.TriggerConditionParameter parameter030 = new IotRuleSceneDO.TriggerConditionParameter(); + IotRuleSceneTriggerConditionParameter parameter030 = new IotRuleSceneTriggerConditionParameter(); parameter030.setIdentifier("width"); parameter030.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.getOperator()); parameter030.setValue("1"); @@ -201,21 +202,21 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { // 动作 ruleScene01.setActions(CollUtil.newArrayList()); // 设备控制 - IotRuleSceneDO.ActionConfig action01 = new IotRuleSceneDO.ActionConfig(); + IotRuleSceneActionConfig action01 = new IotRuleSceneActionConfig(); action01.setType(IotRuleSceneActionTypeEnum.DEVICE_CONTROL.getType()); - IotRuleSceneDO.ActionDeviceControl actionDeviceControl01 = new IotRuleSceneDO.ActionDeviceControl(); - actionDeviceControl01.setProductKey("4aymZgOTOOCrDKRT"); - actionDeviceControl01.setDeviceNames(ListUtil.of("small")); - actionDeviceControl01.setType(IotDeviceMessageTypeEnum.PROPERTY.getType()); - actionDeviceControl01.setIdentifier(IotDeviceMessageIdentifierEnum.PROPERTY_SET.getIdentifier()); - actionDeviceControl01.setData(MapUtil.builder() + IotRuleSceneActionDeviceControl iotRuleSceneActionDeviceControl01 = new IotRuleSceneActionDeviceControl(); + iotRuleSceneActionDeviceControl01.setProductKey("4aymZgOTOOCrDKRT"); + iotRuleSceneActionDeviceControl01.setDeviceNames(ListUtil.of("small")); + iotRuleSceneActionDeviceControl01.setType(IotDeviceMessageTypeEnum.PROPERTY.getType()); + iotRuleSceneActionDeviceControl01.setIdentifier(IotDeviceMessageIdentifierEnum.PROPERTY_SET.getIdentifier()); + iotRuleSceneActionDeviceControl01.setData(MapUtil.builder() .put("power", 1) .put("color", "red") .build()); - action01.setDeviceControl(actionDeviceControl01); + action01.setDeviceControl(iotRuleSceneActionDeviceControl01); // ruleScene01.getActions().add(action01); // TODO 芋艿:先不测试了 // 数据桥接(http) - IotRuleSceneDO.ActionConfig action02 = new IotRuleSceneDO.ActionConfig(); + IotRuleSceneActionConfig action02 = new IotRuleSceneActionConfig(); action02.setType(IotRuleSceneActionTypeEnum.DATA_BRIDGE.getType()); action02.setDataBridgeId(1L); ruleScene01.getActions().add(action02); @@ -225,7 +226,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { List list = ruleSceneMapper.selectList(); // TODO @芋艿:需要考虑开启状态 return filterList(list, ruleScene -> { - for (IotRuleSceneDO.TriggerConfig trigger : ruleScene.getTriggers()) { + for (IotRuleSceneTriggerConfig trigger : ruleScene.getTriggers()) { if (ObjUtil.notEqual(trigger.getProductKey(), productKey)) { continue; } @@ -260,22 +261,22 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { IotRuleSceneDO scene = new IotRuleSceneDO().setStatus(CommonStatusEnum.ENABLE.getStatus()); if (true) { scene.setTenantId(1L); - IotRuleSceneDO.TriggerConfig triggerConfig = new IotRuleSceneDO.TriggerConfig(); - triggerConfig.setType(IotRuleSceneTriggerTypeEnum.TIMER.getType()); - scene.setTriggers(ListUtil.toList(triggerConfig)); + IotRuleSceneTriggerConfig iotRuleSceneTriggerConfig = new IotRuleSceneTriggerConfig(); + iotRuleSceneTriggerConfig.setType(IotRuleSceneTriggerTypeEnum.TIMER.getType()); + scene.setTriggers(ListUtil.toList(iotRuleSceneTriggerConfig)); // 动作 - IotRuleSceneDO.ActionConfig action01 = new IotRuleSceneDO.ActionConfig(); + IotRuleSceneActionConfig action01 = new IotRuleSceneActionConfig(); action01.setType(IotRuleSceneActionTypeEnum.DEVICE_CONTROL.getType()); - IotRuleSceneDO.ActionDeviceControl actionDeviceControl01 = new IotRuleSceneDO.ActionDeviceControl(); - actionDeviceControl01.setProductKey("4aymZgOTOOCrDKRT"); - actionDeviceControl01.setDeviceNames(ListUtil.of("small")); - actionDeviceControl01.setType(IotDeviceMessageTypeEnum.PROPERTY.getType()); - actionDeviceControl01.setIdentifier(IotDeviceMessageIdentifierEnum.PROPERTY_SET.getIdentifier()); - actionDeviceControl01.setData(MapUtil.builder() + IotRuleSceneActionDeviceControl iotRuleSceneActionDeviceControl01 = new IotRuleSceneActionDeviceControl(); + iotRuleSceneActionDeviceControl01.setProductKey("4aymZgOTOOCrDKRT"); + iotRuleSceneActionDeviceControl01.setDeviceNames(ListUtil.of("small")); + iotRuleSceneActionDeviceControl01.setType(IotDeviceMessageTypeEnum.PROPERTY.getType()); + iotRuleSceneActionDeviceControl01.setIdentifier(IotDeviceMessageIdentifierEnum.PROPERTY_SET.getIdentifier()); + iotRuleSceneActionDeviceControl01.setData(MapUtil.builder() .put("power", 1) .put("color", "red") .build()); - action01.setDeviceControl(actionDeviceControl01); + action01.setDeviceControl(iotRuleSceneActionDeviceControl01); scene.setActions(ListUtil.toList(action01)); } if (scene == null) { @@ -287,7 +288,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { return; } // 1.2 判断是否有定时触发器,避免脏数据 - IotRuleSceneDO.TriggerConfig config = CollUtil.findOne(scene.getTriggers(), + IotRuleSceneTriggerConfig config = CollUtil.findOne(scene.getTriggers(), trigger -> ObjUtil.equals(trigger.getType(), IotRuleSceneTriggerTypeEnum.TIMER.getType())); if (config == null) { log.error("[executeRuleSceneByTimer][规则场景({}) 不存在定时触发器]", scene); @@ -316,7 +317,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { // 2. 匹配 trigger 触发器的条件 return filterList(ruleScenes, ruleScene -> { - for (IotRuleSceneDO.TriggerConfig trigger : ruleScene.getTriggers()) { + for (IotRuleSceneTriggerConfig trigger : ruleScene.getTriggers()) { // 2.1 非设备触发,不匹配 if (ObjUtil.notEqual(trigger.getType(), IotRuleSceneTriggerTypeEnum.DEVICE.getType())) { return false; @@ -327,13 +328,13 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { return false; } // 2.3 多个条件,只需要满足一个即可 - IotRuleSceneDO.TriggerCondition matchedCondition = CollUtil.findOne(trigger.getConditions(), condition -> { + IotRuleSceneTriggerCondition matchedCondition = CollUtil.findOne(trigger.getConditions(), condition -> { if (ObjUtil.notEqual(message.getType(), condition.getType()) || ObjUtil.notEqual(message.getIdentifier(), condition.getIdentifier())) { return false; } // 多个条件参数,必须全部满足。所以,下面的逻辑就是找到一个不满足的条件参数 - IotRuleSceneDO.TriggerConditionParameter notMatchedParameter = CollUtil.findOne(condition.getParameters(), + IotRuleSceneTriggerConditionParameter notMatchedParameter = CollUtil.findOne(condition.getParameters(), parameter -> !isTriggerConditionParameterMatched(message, parameter, ruleScene, trigger)); return notMatchedParameter == null; }); @@ -348,6 +349,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { } // TODO @芋艿:【可优化】可以考虑增加下单测,边界太多了。 + /** * 判断触发器的条件参数是否匹配 * @@ -358,8 +360,8 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { * @return 是否匹配 */ @SuppressWarnings({"unchecked", "DataFlowIssue"}) - private boolean isTriggerConditionParameterMatched(IotDeviceMessage message, IotRuleSceneDO.TriggerConditionParameter parameter, - IotRuleSceneDO ruleScene, IotRuleSceneDO.TriggerConfig trigger) { + private boolean isTriggerConditionParameterMatched(IotDeviceMessage message, IotRuleSceneTriggerConditionParameter parameter, + IotRuleSceneDO ruleScene, IotRuleSceneTriggerConfig trigger) { // 1.1 校验操作符是否合法 IotRuleSceneTriggerConditionParameterOperatorEnum operator = IotRuleSceneTriggerConditionParameterOperatorEnum.operatorOf(parameter.getOperator()); @@ -459,7 +461,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { schedulerManager.addOrUpdateJob(IotRuleSceneJob.class, IotRuleSceneJob.buildJobName(id), "0/10 * * * * ?", - jobDataMap); + jobDataMap); } if (false) { Long id = 1L; diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/IotRuleSceneAction.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/IotRuleSceneAction.java index c7b921c044..e115c629b5 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/IotRuleSceneAction.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/IotRuleSceneAction.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.iot.service.rule.action; -import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config.IotRuleSceneActionConfig; import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum; import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; @@ -14,15 +14,16 @@ import javax.annotation.Nullable; public interface IotRuleSceneAction { // TODO @芋艿:groovy 或者 javascript 实现数据的转换;可以考虑基于 hutool 的 ScriptUtil 做 + /** * 执行场景 * * @param message 消息,允许空 * 1. 空的情况:定时触发 * 2. 非空的情况:设备触发 - * @param config 配置 + * @param config 配置 */ - void execute(@Nullable IotDeviceMessage message, IotRuleSceneDO.ActionConfig config) throws Exception; + void execute(@Nullable IotDeviceMessage message, IotRuleSceneActionConfig config) throws Exception; /** * 获得类型 diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/IotRuleSceneAlertAction.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/IotRuleSceneAlertAction.java index eadc173787..a9c475a2b1 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/IotRuleSceneAlertAction.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/IotRuleSceneAlertAction.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.iot.service.rule.action; -import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config.IotRuleSceneActionConfig; import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum; import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; import org.springframework.stereotype.Component; @@ -16,7 +16,7 @@ import javax.annotation.Nullable; public class IotRuleSceneAlertAction implements IotRuleSceneAction { @Override - public void execute(@Nullable IotDeviceMessage message, IotRuleSceneDO.ActionConfig config) { + public void execute(@Nullable IotDeviceMessage message, IotRuleSceneActionConfig config) { // TODO @芋艿:待实现 } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/IotRuleSceneDataBridgeAction.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/IotRuleSceneDataBridgeAction.java index b38e181f93..86405ca444 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/IotRuleSceneDataBridgeAction.java +++ b/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; import cn.hutool.core.lang.Assert; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config.IotRuleSceneActionConfig; import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; -import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum; import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; import cn.iocoder.yudao.module.iot.service.rule.IotDataBridgeService; @@ -29,7 +29,7 @@ public class IotRuleSceneDataBridgeAction implements IotRuleSceneAction { private List> dataBridgeExecutes; @Override - public void execute(IotDeviceMessage message, IotRuleSceneDO.ActionConfig config) throws Exception { + public void execute(IotDeviceMessage message, IotRuleSceneActionConfig config) throws Exception { // 1.1 如果消息为空,直接返回 if (message == null) { return; diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/IotRuleSceneDeviceControlAction.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/IotRuleSceneDeviceControlAction.java index d8fd76b5e7..3408ea0317 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/IotRuleSceneDeviceControlAction.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/IotRuleSceneDeviceControlAction.java @@ -2,8 +2,9 @@ package cn.iocoder.yudao.module.iot.service.rule.action; import cn.hutool.core.lang.Assert; import cn.iocoder.yudao.module.iot.controller.admin.device.vo.control.IotDeviceDownstreamReqVO; +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config.IotRuleSceneActionConfig; +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config.IotRuleSceneActionDeviceControl; import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; -import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum; import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; @@ -27,8 +28,8 @@ public class IotRuleSceneDeviceControlAction implements IotRuleSceneAction { private IotDeviceService deviceService; @Override - public void execute(IotDeviceMessage message, IotRuleSceneDO.ActionConfig config) { - IotRuleSceneDO.ActionDeviceControl control = config.getDeviceControl(); + public void execute(IotDeviceMessage message, IotRuleSceneActionConfig config) { + IotRuleSceneActionDeviceControl control = config.getDeviceControl(); Assert.notNull(control, "设备控制配置不能为空"); // 遍历每个设备,下发消息 control.getDeviceNames().forEach(deviceName -> { From 38e8c85276a52ff3bfe4e9f1c66cc1de5581636e Mon Sep 17 00:00:00 2001 From: puhui999 Date: Tue, 18 Mar 2025 17:36:44 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E3=80=90=E4=BB=A3=E7=A0=81=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E3=80=91redis=20=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yudao-server/pom.xml | 10 +++++----- .../src/main/resources/application-local.yaml | 11 ++++++----- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/yudao-server/pom.xml b/yudao-server/pom.xml index efd53c84a5..492e31db56 100644 --- a/yudao-server/pom.xml +++ b/yudao-server/pom.xml @@ -109,11 +109,11 @@ - - - - - + + cn.iocoder.boot + yudao-module-iot-biz + ${revision} + diff --git a/yudao-server/src/main/resources/application-local.yaml b/yudao-server/src/main/resources/application-local.yaml index c98a3277bb..085cb4025e 100644 --- a/yudao-server/src/main/resources/application-local.yaml +++ b/yudao-server/src/main/resources/application-local.yaml @@ -76,11 +76,12 @@ spring: validation-query: SELECT SERVER_STATUS() # TDengine 数据源的有效性检查 SQL # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 - redis: - host: 127.0.0.1 # 地址 - port: 6379 # 端口 - database: 0 # 数据库索引 -# password: dev # 密码,建议生产环境开启 + data: + redis: + host: 127.0.0.1 # 地址 + port: 6379 # 端口 + database: 0 # 数据库索引 +# password: dev # 密码,建议生产环境开启 --- #################### 定时任务相关配置 #################### From 2073ecb2f36f83060c78016b102cb0100b7dff97 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Fri, 21 Mar 2025 16:45:28 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E3=80=90=E5=8A=9F=E8=83=BD=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E3=80=91IoT:=20=E7=89=A9=E6=A8=A1=E5=9E=8B=20TSL=20?= =?UTF-8?q?=E8=8E=B7=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../thingmodel/IotThingModelController.http | 5 ++-- .../thingmodel/IotThingModelController.java | 14 ++++----- .../thingmodel/vo/IotThingModelRespVO.java | 6 ---- .../thingmodel/vo/IotThingModelTSLRespVO.java | 30 +++++++++++++++++++ .../thingmodel/IotThingModelService.java | 9 ++++++ .../thingmodel/IotThingModelServiceImpl.java | 26 ++++++++++++++++ 6 files changed, 72 insertions(+), 18 deletions(-) create mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/vo/IotThingModelTSLRespVO.java diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/IotThingModelController.http b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/IotThingModelController.http index 1e1f72103e..e041cdc8af 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/IotThingModelController.http +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/IotThingModelController.http @@ -174,8 +174,7 @@ GET {{baseUrl}}/iot/product-thing-model/get?id=67 tenant-id: {{adminTenentId}} Authorization: Bearer {{token}} - -### 请求 /iot/product-thing-model/list-by-product-id 接口 => 成功 -GET {{baseUrl}}/iot/product-thing-model/list-by-product-id?productId=1001 +### 请求 /iot/product-thing-model/tsl-by-product-id 接口 => 成功 +GET {{baseUrl}}/iot/product-thing-model/tsl-by-product-id?productId=1001 tenant-id: {{adminTenentId}} Authorization: Bearer {{token}} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/IotThingModelController.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/IotThingModelController.java index 382940fc48..dc65277636 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/IotThingModelController.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/IotThingModelController.java @@ -3,10 +3,7 @@ package cn.iocoder.yudao.module.iot.controller.admin.thingmodel; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelListReqVO; -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelPageReqVO; -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelRespVO; -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelSaveReqVO; +import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.*; import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; import cn.iocoder.yudao.module.iot.service.thingmodel.IotThingModelService; import io.swagger.v3.oas.annotations.Operation; @@ -64,13 +61,12 @@ public class IotThingModelController { return success(BeanUtils.toBean(thingModel, IotThingModelRespVO.class)); } - @GetMapping("/list-by-product-id") - @Operation(summary = "获得产品物模型") + @GetMapping("/tsl-by-product-id") + @Operation(summary = "获得产品物模型 TSL") @Parameter(name = "productId", description = "产品ID", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('iot:thing-model:query')") - public CommonResult> getThingModelListByProductId(@RequestParam("productId") Long productId) { - List list = thingModelService.getThingModelListByProductId(productId); - return success(BeanUtils.toBean(list, IotThingModelRespVO.class)); + public CommonResult getThingModelTslByProductId(@RequestParam("productId") Long productId) { + return success(thingModelService.getThingModelTslByProductId(productId)); } // TODO @puhui @super:getThingModelListByProductId 和 getThingModelListByProductId 可以融合么? diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/vo/IotThingModelRespVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/vo/IotThingModelRespVO.java index 15a5b9f959..2b7f17ac72 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/vo/IotThingModelRespVO.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/vo/IotThingModelRespVO.java @@ -3,8 +3,6 @@ package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo; import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelEvent; import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelProperty; import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelService; -import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; -import com.alibaba.excel.annotation.ExcelProperty; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -12,18 +10,15 @@ import java.time.LocalDateTime; @Schema(description = "管理后台 - IoT 产品物模型 Response VO") @Data -@ExcelIgnoreUnannotated public class IotThingModelRespVO { @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "21816") - @ExcelProperty("产品ID") private Long id; @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") private Long productId; @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "temperature_sensor") - @ExcelProperty("产品标识") private String productKey; @Schema(description = "功能标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "temperature") @@ -48,7 +43,6 @@ public class IotThingModelRespVO { private ThingModelService service; @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) - @ExcelProperty("创建时间") private LocalDateTime createTime; } \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/vo/IotThingModelTSLRespVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/vo/IotThingModelTSLRespVO.java new file mode 100644 index 0000000000..a5b28fd4e3 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/vo/IotThingModelTSLRespVO.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo; + +import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelEvent; +import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelProperty; +import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelService; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +@Schema(description = "管理后台 - IoT 产品物模型 TSL Response VO") +@Data +public class IotThingModelTSLRespVO { + + @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + private Long productId; + + @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "temperature_sensor") + private String productKey; + + @Schema(description = "属性列表", requiredMode = Schema.RequiredMode.REQUIRED) + private List properties; + + @Schema(description = "服务列表", requiredMode = Schema.RequiredMode.REQUIRED) + private List events; + + @Schema(description = "事件列表", requiredMode = Schema.RequiredMode.REQUIRED) + private List services; + +} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelService.java index 8834772d35..e15465e9b6 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelService.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelService.java @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelListReqVO; import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelPageReqVO; import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelSaveReqVO; +import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelTSLRespVO; import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; import jakarta.validation.Valid; @@ -90,4 +91,12 @@ public interface IotThingModelService { */ Long getThingModelCount(LocalDateTime createTime); + /** + * 通过产品 ID 获取产品物模型 TSL + * + * @param productId 产品 ID + * @return 产品物模型 TSL + */ + IotThingModelTSLRespVO getThingModelTslByProductId(Long productId); + } \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelServiceImpl.java index 9487ff2de6..ae159fdb92 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/thingmodel/IotThingModelServiceImpl.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.iot.service.thingmodel; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.extra.spring.SpringUtil; @@ -13,6 +14,7 @@ import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelS import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelListReqVO; import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelPageReqVO; import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelSaveReqVO; +import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelTSLRespVO; import cn.iocoder.yudao.module.iot.convert.thingmodel.IotThingModelConvert; import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; @@ -149,6 +151,30 @@ public class IotThingModelServiceImpl implements IotThingModelService { return thingModelMapper.selectList(reqVO); } + @Override + public IotThingModelTSLRespVO getThingModelTslByProductId(Long productId) { + IotThingModelTSLRespVO tslRespVO = new IotThingModelTSLRespVO(); + // 1. 获得产品所有物模型定义 + List thingModelList = thingModelMapper.selectListByProductId(productId); + if (CollUtil.isEmpty(thingModelList)) { + return tslRespVO; + } + + // 2.1 设置公共部分参数 + IotThingModelDO thingModel = thingModelList.get(0); + tslRespVO.setProductId(thingModel.getProductId()).setProductKey(thingModel.getProductKey()); + // 2.2 处理属性列表 + tslRespVO.setProperties(convertList(filterList(thingModelList, item -> + ObjUtil.equal(IotThingModelTypeEnum.PROPERTY.getType(), item.getType())), IotThingModelDO::getProperty)); + // 2.3 处理服务列表 + tslRespVO.setServices(convertList(filterList(thingModelList, item -> + ObjUtil.equal(IotThingModelTypeEnum.SERVICE.getType(), item.getType())), IotThingModelDO::getService)); + // 2.4 处理事件列表 + tslRespVO.setEvents(convertList(filterList(thingModelList, item -> + ObjUtil.equal(IotThingModelTypeEnum.EVENT.getType(), item.getType())), IotThingModelDO::getEvent)); + return tslRespVO; + } + /** * 校验功能是否存在 *