Commit 35dd91d6c9e3a40da0507969b671fb9a470df0e8

Authored by 芋道源码
Committed by Gitee
2 parents 638976da 2073ecb2

!1296 【功能新增】IoT: 规则场景

Merge pull request !1296 from puhui999/iot
Showing 28 changed files with 649 additions and 388 deletions
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 { @@ -72,4 +72,7 @@ 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 规则场景(场景联动)不存在");
  77 +
75 } 78 }
76 \ No newline at end of file 79 \ No newline at end of file
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 @@ -50,7 +50,7 @@ public enum IotRuleSceneTriggerConditionParameterOperatorEnum implements ArrayVa
50 /** 50 /**
51 * Spring 表达式 - 目标值数组 51 * Spring 表达式 - 目标值数组
52 */ 52 */
53 - public static final String SPRING_EXPRESSION_VALUE_List = "values"; 53 + public static final String SPRING_EXPRESSION_VALUE_LIST = "values";
54 54
55 public static IotRuleSceneTriggerConditionParameterOperatorEnum operatorOf(String operator) { 55 public static IotRuleSceneTriggerConditionParameterOperatorEnum operatorOf(String operator) {
56 return ArrayUtil.firstMatch(item -> item.getOperator().equals(operator), values()); 56 return ArrayUtil.firstMatch(item -> item.getOperator().equals(operator), values());
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/IotRuleSceneController.java
1 package cn.iocoder.yudao.module.iot.controller.admin.rule; 1 package cn.iocoder.yudao.module.iot.controller.admin.rule;
2 2
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  6 +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleScenePageReqVO;
  7 +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleSceneRespVO;
  8 +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleSceneSaveReqVO;
  9 +import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO;
3 import cn.iocoder.yudao.module.iot.service.rule.IotRuleSceneService; 10 import cn.iocoder.yudao.module.iot.service.rule.IotRuleSceneService;
  11 +import io.swagger.v3.oas.annotations.Operation;
  12 +import io.swagger.v3.oas.annotations.Parameter;
4 import io.swagger.v3.oas.annotations.tags.Tag; 13 import io.swagger.v3.oas.annotations.tags.Tag;
5 import jakarta.annotation.Resource; 14 import jakarta.annotation.Resource;
6 import jakarta.annotation.security.PermitAll; 15 import jakarta.annotation.security.PermitAll;
  16 +import jakarta.validation.Valid;
  17 +import org.springframework.security.access.prepost.PreAuthorize;
7 import org.springframework.validation.annotation.Validated; 18 import org.springframework.validation.annotation.Validated;
8 -import org.springframework.web.bind.annotation.GetMapping;  
9 -import org.springframework.web.bind.annotation.RequestMapping;  
10 -import org.springframework.web.bind.annotation.RestController; 19 +import org.springframework.web.bind.annotation.*;
  20 +
  21 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
11 22
12 @Tag(name = "管理后台 - IoT 规则场景") 23 @Tag(name = "管理后台 - IoT 规则场景")
13 @RestController 24 @RestController
@@ -18,6 +29,47 @@ public class IotRuleSceneController { @@ -18,6 +29,47 @@ public class IotRuleSceneController {
18 @Resource 29 @Resource
19 private IotRuleSceneService ruleSceneService; 30 private IotRuleSceneService ruleSceneService;
20 31
  32 + @PostMapping("/create")
  33 + @Operation(summary = "创建规则场景(场景联动)")
  34 + @PreAuthorize("@ss.hasPermission('iot:rule-scene:create')")
  35 + public CommonResult<Long> createRuleScene(@Valid @RequestBody IotRuleSceneSaveReqVO createReqVO) {
  36 + return success(ruleSceneService.createRuleScene(createReqVO));
  37 + }
  38 +
  39 + @PutMapping("/update")
  40 + @Operation(summary = "更新规则场景(场景联动)")
  41 + @PreAuthorize("@ss.hasPermission('iot:rule-scene:update')")
  42 + public CommonResult<Boolean> updateRuleScene(@Valid @RequestBody IotRuleSceneSaveReqVO updateReqVO) {
  43 + ruleSceneService.updateRuleScene(updateReqVO);
  44 + return success(true);
  45 + }
  46 +
  47 + @DeleteMapping("/delete")
  48 + @Operation(summary = "删除规则场景(场景联动)")
  49 + @Parameter(name = "id", description = "编号", required = true)
  50 + @PreAuthorize("@ss.hasPermission('iot:rule-scene:delete')")
  51 + public CommonResult<Boolean> deleteRuleScene(@RequestParam("id") Long id) {
  52 + ruleSceneService.deleteRuleScene(id);
  53 + return success(true);
  54 + }
  55 +
  56 + @GetMapping("/get")
  57 + @Operation(summary = "获得规则场景(场景联动)")
  58 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  59 + @PreAuthorize("@ss.hasPermission('iot:rule-scene:query')")
  60 + public CommonResult<IotRuleSceneRespVO> getRuleScene(@RequestParam("id") Long id) {
  61 + IotRuleSceneDO ruleScene = ruleSceneService.getRuleScene(id);
  62 + return success(BeanUtils.toBean(ruleScene, IotRuleSceneRespVO.class));
  63 + }
  64 +
  65 + @GetMapping("/page")
  66 + @Operation(summary = "获得规则场景(场景联动)分页")
  67 + @PreAuthorize("@ss.hasPermission('iot:rule-scene:query')")
  68 + public CommonResult<PageResult<IotRuleSceneRespVO>> getRuleScenePage(@Valid IotRuleScenePageReqVO pageReqVO) {
  69 + PageResult<IotRuleSceneDO> pageResult = ruleSceneService.getRuleScenePage(pageReqVO);
  70 + return success(BeanUtils.toBean(pageResult, IotRuleSceneRespVO.class));
  71 + }
  72 +
21 @GetMapping("/test") 73 @GetMapping("/test")
22 @PermitAll 74 @PermitAll
23 public void test() { 75 public void test() {
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/scene/IotRuleScenePageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +import org.springframework.format.annotation.DateTimeFormat;
  9 +
  10 +import java.time.LocalDateTime;
  11 +
  12 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  13 +
  14 +@Schema(description = "管理后台 - IoT 规则场景(场景联动)分页 Request VO")
  15 +@Data
  16 +@EqualsAndHashCode(callSuper = true)
  17 +@ToString(callSuper = true)
  18 +public class IotRuleScenePageReqVO extends PageParam {
  19 +
  20 + @Schema(description = "场景名称", example = "赵六")
  21 + private String name;
  22 +
  23 + @Schema(description = "场景描述", example = "你猜")
  24 + private String description;
  25 +
  26 + @Schema(description = "场景状态", example = "1")
  27 + private Integer status;
  28 +
  29 + @Schema(description = "创建时间")
  30 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  31 + private LocalDateTime[] createTime;
  32 +
  33 +}
0 \ No newline at end of file 34 \ 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/IotRuleSceneRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene;
  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;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import lombok.Data;
  7 +
  8 +import java.time.LocalDateTime;
  9 +import java.util.List;
  10 +
  11 +@Schema(description = "管理后台 - IoT 规则场景(场景联动) Response VO")
  12 +@Data
  13 +public class IotRuleSceneRespVO {
  14 +
  15 + @Schema(description = "场景编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "15865")
  16 + private Long id;
  17 +
  18 + @Schema(description = "场景名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
  19 + private String name;
  20 +
  21 + @Schema(description = "场景描述", example = "你猜")
  22 + private String description;
  23 +
  24 + @Schema(description = "场景状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  25 + private Integer status;
  26 +
  27 + @Schema(description = "触发器数组", requiredMode = Schema.RequiredMode.REQUIRED)
  28 + private List<IotRuleSceneTriggerConfig> triggers;
  29 +
  30 + @Schema(description = "执行器数组", requiredMode = Schema.RequiredMode.REQUIRED)
  31 + private List<IotRuleSceneActionConfig> actions;
  32 +
  33 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  34 + private LocalDateTime createTime;
  35 +
  36 +}
0 \ No newline at end of file 37 \ 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/IotRuleSceneSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  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;
  7 +import io.swagger.v3.oas.annotations.media.Schema;
  8 +import jakarta.validation.constraints.NotEmpty;
  9 +import jakarta.validation.constraints.NotNull;
  10 +import lombok.Data;
  11 +
  12 +import java.util.List;
  13 +
  14 +@Schema(description = "管理后台 - IoT 规则场景(场景联动)新增/修改 Request VO")
  15 +@Data
  16 +public class IotRuleSceneSaveReqVO {
  17 +
  18 + @Schema(description = "场景编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "15865")
  19 + private Long id;
  20 +
  21 + @Schema(description = "场景名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
  22 + @NotEmpty(message = "场景名称不能为空")
  23 + private String name;
  24 +
  25 + @Schema(description = "场景描述", example = "你猜")
  26 + private String description;
  27 +
  28 + @Schema(description = "场景状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  29 + @NotNull(message = "场景状态不能为空")
  30 + @InEnum(CommonStatusEnum.class)
  31 + private Integer status;
  32 +
  33 + @Schema(description = "触发器数组", requiredMode = Schema.RequiredMode.REQUIRED)
  34 + @NotEmpty(message = "触发器数组不能为空")
  35 + private List<IotRuleSceneTriggerConfig> triggers;
  36 +
  37 + @Schema(description = "执行器数组", requiredMode = Schema.RequiredMode.REQUIRED)
  38 + @NotEmpty(message = "执行器数组不能为空")
  39 + private List<IotRuleSceneActionConfig> actions;
  40 +
  41 +}
0 \ No newline at end of file 42 \ 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 0 → 100644
  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 +/**
  8 + * 执行器配置
  9 + *
  10 + * @author 芋道源码
  11 + */
  12 +@Data
  13 +public class IotRuleSceneActionConfig {
  14 +
  15 + /**
  16 + * 执行类型
  17 + *
  18 + * 枚举 {@link IotRuleSceneActionTypeEnum}
  19 + */
  20 + private Integer type;
  21 +
  22 + /**
  23 + * 设备控制
  24 + *
  25 + * 必填:当 {@link #type} 为 {@link IotRuleSceneActionTypeEnum#DEVICE_CONTROL} 时
  26 + */
  27 + private IotRuleSceneActionDeviceControl deviceControl;
  28 +
  29 + /**
  30 + * 数据桥接编号
  31 + *
  32 + * 必填:当 {@link #type} 为 {@link IotRuleSceneActionTypeEnum#DATA_BRIDGE} 时
  33 + * 关联:{@link IotDataBridgeDO#getId()}
  34 + */
  35 + private Long dataBridgeId;
  36 +
  37 +}
0 \ No newline at end of file 38 \ 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 0 → 100644
  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 +/**
  13 + * 执行设备控制
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@Data
  18 +public class IotRuleSceneActionDeviceControl {
  19 +
  20 + /**
  21 + * 产品标识
  22 + *
  23 + * 关联 {@link IotProductDO#getProductKey()}
  24 + */
  25 + private String productKey;
  26 + /**
  27 + * 设备名称数组
  28 + *
  29 + * 关联 {@link IotDeviceDO#getDeviceName()}
  30 + */
  31 + private List<String> deviceNames;
  32 +
  33 + /**
  34 + * 消息类型
  35 + *
  36 + * 枚举 {@link IotDeviceMessageTypeEnum#PROPERTY}、{@link IotDeviceMessageTypeEnum#SERVICE}
  37 + */
  38 + private String type;
  39 + /**
  40 + * 消息标识符
  41 + *
  42 + * 枚举 {@link IotDeviceMessageIdentifierEnum}
  43 + *
  44 + * 1. 属性设置:对应 {@link IotDeviceMessageIdentifierEnum#PROPERTY_SET}
  45 + * 2. 服务调用:对应 {@link IotDeviceMessageIdentifierEnum#SERVICE_INVOKE}
  46 + */
  47 + private String identifier;
  48 +
  49 + /**
  50 + * 具体数据
  51 + *
  52 + * 1. 属性设置:在 {@link #type} 是 {@link IotDeviceMessageTypeEnum#PROPERTY} 时,对应 properties
  53 + * 2. 服务调用:在 {@link #type} 是 {@link IotDeviceMessageTypeEnum#SERVICE} 时,对应 params
  54 + */
  55 + private Map<String, Object> data;
  56 +
  57 +}
0 \ No newline at end of file 58 \ 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 0 → 100644
  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 +/**
  10 + * 触发条件
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Data
  15 +public class IotRuleSceneTriggerCondition {
  16 +
  17 + /**
  18 + * 消息类型
  19 + *
  20 + * 枚举 {@link IotDeviceMessageTypeEnum}
  21 + */
  22 + private String type;
  23 + /**
  24 + * 消息标识符
  25 + *
  26 + * 枚举 {@link IotDeviceMessageIdentifierEnum}
  27 + */
  28 + private String identifier;
  29 +
  30 + /**
  31 + * 参数数组
  32 + *
  33 + * 参数与参数之间,是“或”的关系
  34 + */
  35 + private List<IotRuleSceneTriggerConditionParameter> parameters;
  36 +
  37 +}
0 \ No newline at end of file 38 \ 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 0 → 100644
  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 +/**
  8 + * 触发条件参数
  9 + *
  10 + * @author 芋道源码
  11 + */
  12 +@Data
  13 +public class IotRuleSceneTriggerConditionParameter {
  14 +
  15 + /**
  16 + * 标识符(属性、事件、服务)
  17 + *
  18 + * 关联 {@link IotThingModelDO#getIdentifier()}
  19 + */
  20 + private String identifier;
  21 +
  22 + /**
  23 + * 操作符
  24 + *
  25 + * 枚举 {@link IotRuleSceneTriggerConditionParameterOperatorEnum}
  26 + */
  27 + private String operator;
  28 +
  29 + /**
  30 + * 比较值
  31 + *
  32 + * 如果有多个值,则使用 "," 分隔,类似 "1,2,3"。
  33 + * 例如说,{@link IotRuleSceneTriggerConditionParameterOperatorEnum#IN}、{@link IotRuleSceneTriggerConditionParameterOperatorEnum#BETWEEN}
  34 + */
  35 + private String value;
  36 +
  37 +}
0 \ No newline at end of file 38 \ 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 0 → 100644
  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 +/**
  11 + * 触发器配置
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@Data
  16 +public class IotRuleSceneTriggerConfig {
  17 +
  18 + /**
  19 + * 触发类型
  20 + *
  21 + * 枚举 {@link IotRuleSceneTriggerTypeEnum}
  22 + */
  23 + private Integer type;
  24 +
  25 + /**
  26 + * 产品标识
  27 + *
  28 + * 关联 {@link IotProductDO#getProductKey()}
  29 + */
  30 + private String productKey;
  31 + /**
  32 + * 设备名称数组
  33 + *
  34 + * 关联 {@link IotDeviceDO#getDeviceName()}
  35 + */
  36 + private List<String> deviceNames;
  37 +
  38 + /**
  39 + * 触发条件数组
  40 + *
  41 + * 必填:当 {@link #type} 为 {@link IotRuleSceneTriggerTypeEnum#DEVICE} 时
  42 + * 条件与条件之间,是“或”的关系
  43 + */
  44 + private List<IotRuleSceneTriggerCondition> conditions;
  45 +
  46 + /**
  47 + * CRON 表达式
  48 + *
  49 + * 必填:当 {@link #type} 为 {@link IotRuleSceneTriggerTypeEnum#TIMER} 时
  50 + */
  51 + private String cronExpression;
  52 +
  53 +}
0 \ No newline at end of file 54 \ 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,8 +174,7 @@ GET {{baseUrl}}/iot/product-thing-model/get?id=67 @@ -174,8 +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 -  
178 -### 请求 /iot/product-thing-model/list-by-product-id 接口 => 成功  
179 -GET {{baseUrl}}/iot/product-thing-model/list-by-product-id?productId=1001 177 +### 请求 /iot/product-thing-model/tsl-by-product-id 接口 => 成功
  178 +GET {{baseUrl}}/iot/product-thing-model/tsl-by-product-id?productId=1001
180 tenant-id: {{adminTenentId}} 179 tenant-id: {{adminTenentId}}
181 Authorization: Bearer {{token}} 180 Authorization: Bearer {{token}}
182 \ 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
@@ -3,10 +3,7 @@ package cn.iocoder.yudao.module.iot.controller.admin.thingmodel; @@ -3,10 +3,7 @@ package cn.iocoder.yudao.module.iot.controller.admin.thingmodel;
3 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
6 -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelListReqVO;  
7 -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelPageReqVO;  
8 -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelRespVO;  
9 -import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelSaveReqVO; 6 +import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.*;
10 import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; 7 import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO;
11 import cn.iocoder.yudao.module.iot.service.thingmodel.IotThingModelService; 8 import cn.iocoder.yudao.module.iot.service.thingmodel.IotThingModelService;
12 import io.swagger.v3.oas.annotations.Operation; 9 import io.swagger.v3.oas.annotations.Operation;
@@ -64,13 +61,12 @@ public class IotThingModelController { @@ -64,13 +61,12 @@ public class IotThingModelController {
64 return success(BeanUtils.toBean(thingModel, IotThingModelRespVO.class)); 61 return success(BeanUtils.toBean(thingModel, IotThingModelRespVO.class));
65 } 62 }
66 63
67 - @GetMapping("/list-by-product-id")  
68 - @Operation(summary = "获得产品物模型") 64 + @GetMapping("/tsl-by-product-id")
  65 + @Operation(summary = "获得产品物模型 TSL")
69 @Parameter(name = "productId", description = "产品ID", required = true, example = "1024") 66 @Parameter(name = "productId", description = "产品ID", required = true, example = "1024")
70 @PreAuthorize("@ss.hasPermission('iot:thing-model:query')") 67 @PreAuthorize("@ss.hasPermission('iot:thing-model:query')")
71 - public CommonResult<List<IotThingModelRespVO>> getThingModelListByProductId(@RequestParam("productId") Long productId) {  
72 - List<IotThingModelDO> list = thingModelService.getThingModelListByProductId(productId);  
73 - return success(BeanUtils.toBean(list, IotThingModelRespVO.class)); 68 + public CommonResult<IotThingModelTSLRespVO> getThingModelTslByProductId(@RequestParam("productId") Long productId) {
  69 + return success(thingModelService.getThingModelTslByProductId(productId));
74 } 70 }
75 71
76 // TODO @puhui @super:getThingModelListByProductId 和 getThingModelListByProductId 可以融合么? 72 // TODO @puhui @super:getThingModelListByProductId 和 getThingModelListByProductId 可以融合么?
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; @@ -3,8 +3,6 @@ package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo;
3 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelEvent; 3 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelEvent;
4 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelProperty; 4 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelProperty;
5 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelService; 5 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelService;
6 -import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;  
7 -import com.alibaba.excel.annotation.ExcelProperty;  
8 import io.swagger.v3.oas.annotations.media.Schema; 6 import io.swagger.v3.oas.annotations.media.Schema;
9 import lombok.Data; 7 import lombok.Data;
10 8
@@ -12,18 +10,15 @@ import java.time.LocalDateTime; @@ -12,18 +10,15 @@ import java.time.LocalDateTime;
12 10
13 @Schema(description = "管理后台 - IoT 产品物模型 Response VO") 11 @Schema(description = "管理后台 - IoT 产品物模型 Response VO")
14 @Data 12 @Data
15 -@ExcelIgnoreUnannotated  
16 public class IotThingModelRespVO { 13 public class IotThingModelRespVO {
17 14
18 @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "21816") 15 @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "21816")
19 - @ExcelProperty("产品ID")  
20 private Long id; 16 private Long id;
21 17
22 @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") 18 @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
23 private Long productId; 19 private Long productId;
24 20
25 @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "temperature_sensor") 21 @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "temperature_sensor")
26 - @ExcelProperty("产品标识")  
27 private String productKey; 22 private String productKey;
28 23
29 @Schema(description = "功能标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "temperature") 24 @Schema(description = "功能标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "temperature")
@@ -48,7 +43,6 @@ public class IotThingModelRespVO { @@ -48,7 +43,6 @@ public class IotThingModelRespVO {
48 private ThingModelService service; 43 private ThingModelService service;
49 44
50 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 45 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
51 - @ExcelProperty("创建时间")  
52 private LocalDateTime createTime; 46 private LocalDateTime createTime;
53 47
54 } 48 }
55 \ No newline at end of file 49 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thingmodel/vo/IotThingModelTSLRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo;
  2 +
  3 +import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelEvent;
  4 +import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelProperty;
  5 +import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelService;
  6 +import io.swagger.v3.oas.annotations.media.Schema;
  7 +import lombok.Data;
  8 +
  9 +import java.util.List;
  10 +
  11 +@Schema(description = "管理后台 - IoT 产品物模型 TSL Response VO")
  12 +@Data
  13 +public class IotThingModelTSLRespVO {
  14 +
  15 + @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  16 + private Long productId;
  17 +
  18 + @Schema(description = "产品标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "temperature_sensor")
  19 + private String productKey;
  20 +
  21 + @Schema(description = "属性列表", requiredMode = Schema.RequiredMode.REQUIRED)
  22 + private List<ThingModelProperty> properties;
  23 +
  24 + @Schema(description = "服务列表", requiredMode = Schema.RequiredMode.REQUIRED)
  25 + private List<ThingModelEvent> events;
  26 +
  27 + @Schema(description = "事件列表", requiredMode = Schema.RequiredMode.REQUIRED)
  28 + private List<ThingModelService> services;
  29 +
  30 +}
0 \ No newline at end of file 31 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/thinkmodelfunction/IotThinkModelFunctionController.http deleted
1 -### 请求 /iot/think-model-function/create 接口 => 成功  
2 -POST {{baseUrl}}/iot/think-model-function/create  
3 -Content-Type: application/json  
4 -tenant-id: {{adminTenantId}}  
5 -Authorization: Bearer {{token}}  
6 -  
7 -{  
8 - "productId": 1001,  
9 - "productKey": "smart-sensor-001",  
10 - "identifier": "Temperature",  
11 - "name": "温度",  
12 - "description": "当前温度值",  
13 - "type": 1,  
14 - "property": {  
15 - "identifier": "Temperature",  
16 - "name": "温度",  
17 - "accessMode": "r",  
18 - "required": true,  
19 - "dataType": {  
20 - "type": "float",  
21 - "specs": {  
22 - "min": -10.0,  
23 - "max": 100.0,  
24 - "step": 0.1,  
25 - "unit": "℃"  
26 - }  
27 - },  
28 - "description": "当前温度值"  
29 - }  
30 -}  
31 -  
32 -### 请求 /iot/think-model-function/create 接口 => 成功  
33 -POST {{baseUrl}}/iot/think-model-function/create  
34 -Content-Type: application/json  
35 -tenant-id: {{adminTenantId}}  
36 -Authorization: Bearer {{token}}  
37 -  
38 -{  
39 - "productId": 1001,  
40 - "productKey": "smart-sensor-001",  
41 - "identifier": "Humidity",  
42 - "name": "湿度",  
43 - "description": "当前湿度值",  
44 - "type": 1,  
45 - "property": {  
46 - "identifier": "Humidity",  
47 - "name": "湿度",  
48 - "accessMode": "r",  
49 - "required": true,  
50 - "dataType": {  
51 - "type": "float",  
52 - "specs": {  
53 - "min": 0.0,  
54 - "max": 100.0,  
55 - "step": 0.1,  
56 - "unit": "%"  
57 - }  
58 - },  
59 - "description": "当前湿度值"  
60 - }  
61 -}  
62 -  
63 -  
64 -  
65 -  
66 -### 请求 /iot/think-model-function/update 接口 => 成功  
67 -PUT {{baseUrl}}/iot/think-model-function/update  
68 -Content-Type: application/json  
69 -tenant-id: {{adminTenantId}}  
70 -Authorization: Bearer {{token}}  
71 -  
72 -{  
73 - "id": 11,  
74 - "productId": 1001,  
75 - "productKey": "smart-sensor-001",  
76 - "identifier": "Temperature",  
77 - "name": "温度",  
78 - "description": "当前温度值",  
79 - "type": 1,  
80 - "property": {  
81 - "identifier": "Temperature",  
82 - "name": "温度",  
83 - "accessMode": "r",  
84 - "required": true,  
85 - "dataType": {  
86 - "type": "float",  
87 - "specs": {  
88 - "min": -111.0,  
89 - "max": 222.0,  
90 - "step": 0.1,  
91 - "unit": "℃"  
92 - }  
93 - },  
94 - "description": "当前温度值"  
95 - }  
96 -}  
97 -  
98 -### 请求 /iot/think-model-function/delete 接口 => 成功  
99 -DELETE {{baseUrl}}/iot/think-model-function/delete?id=7  
100 -tenant-id: {{adminTenantId}}  
101 -Authorization: Bearer {{token}}  
102 -  
103 -### 请求 /iot/think-model-function/get 接口 => 成功  
104 -GET {{baseUrl}}/iot/think-model-function/get?id=10  
105 -tenant-id: {{adminTenantId}}  
106 -Authorization: Bearer {{token}}  
107 -  
108 -  
109 -### 请求 /iot/think-model-function/list-by-product-id 接口 => 成功  
110 -GET {{baseUrl}}/iot/think-model-function/list-by-product-id?productId=1001  
111 -tenant-id: {{adminTenantId}}  
112 -Authorization: Bearer {{token}}  
113 \ 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/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.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; 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;
12 import com.baomidou.mybatisplus.annotation.KeySequence; 6 import com.baomidou.mybatisplus.annotation.KeySequence;
13 import com.baomidou.mybatisplus.annotation.TableField; 7 import com.baomidou.mybatisplus.annotation.TableField;
14 import com.baomidou.mybatisplus.annotation.TableId; 8 import com.baomidou.mybatisplus.annotation.TableId;
15 import com.baomidou.mybatisplus.annotation.TableName; 9 import com.baomidou.mybatisplus.annotation.TableName;
16 import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; 10 import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
17 -import lombok.*; 11 +import lombok.AllArgsConstructor;
  12 +import lombok.Builder;
  13 +import lombok.Data;
  14 +import lombok.NoArgsConstructor;
18 15
19 import java.util.List; 16 import java.util.List;
20 -import java.util.Map;  
21 17
22 /** 18 /**
23 * IoT 规则场景(场景联动) DO 19 * IoT 规则场景(场景联动) DO
@@ -56,188 +52,12 @@ public class IotRuleSceneDO extends TenantBaseDO { @@ -56,188 +52,12 @@ public class IotRuleSceneDO extends TenantBaseDO {
56 * 触发器数组 52 * 触发器数组
57 */ 53 */
58 @TableField(typeHandler = JacksonTypeHandler.class) 54 @TableField(typeHandler = JacksonTypeHandler.class)
59 - private List<TriggerConfig> triggers; 55 + private List<IotRuleSceneTriggerConfig> triggers;
60 56
61 /** 57 /**
62 * 执行器数组 58 * 执行器数组
63 */ 59 */
64 @TableField(typeHandler = JacksonTypeHandler.class) 60 @TableField(typeHandler = JacksonTypeHandler.class)
65 - private List<ActionConfig> actions;  
66 -  
67 - /**  
68 - * 触发器配置  
69 - */  
70 - @Data  
71 - public static class TriggerConfig {  
72 -  
73 - /**  
74 - * 触发类型  
75 - *  
76 - * 枚举 {@link IotRuleSceneTriggerTypeEnum}  
77 - */  
78 - private Integer type;  
79 -  
80 - /**  
81 - * 产品标识  
82 - *  
83 - * 关联 {@link IotProductDO#getProductKey()}  
84 - */  
85 - private String productKey;  
86 - /**  
87 - * 设备名称数组  
88 - *  
89 - * 关联 {@link IotDeviceDO#getDeviceName()}  
90 - */  
91 - private List<String> deviceNames;  
92 -  
93 - /**  
94 - * 触发条件数组  
95 - *  
96 - * 必填:当 {@link #type} 为 {@link IotRuleSceneTriggerTypeEnum#DEVICE} 时  
97 - * 条件与条件之间,是“或”的关系  
98 - */  
99 - private List<TriggerCondition> conditions;  
100 -  
101 - /**  
102 - * CRON 表达式  
103 - *  
104 - * 必填:当 {@link #type} 为 {@link IotRuleSceneTriggerTypeEnum#TIMER} 时  
105 - */  
106 - private String cronExpression;  
107 -  
108 - }  
109 -  
110 - /**  
111 - * 触发条件  
112 - */  
113 - @Data  
114 - public static class TriggerCondition {  
115 -  
116 - /**  
117 - * 消息类型  
118 - *  
119 - * 枚举 {@link IotDeviceMessageTypeEnum}  
120 - */  
121 - private String type;  
122 - /**  
123 - * 消息标识符  
124 - *  
125 - * 枚举 {@link IotDeviceMessageIdentifierEnum}  
126 - */  
127 - private String identifier;  
128 -  
129 - /**  
130 - * 参数数组  
131 - *  
132 - * 参数与参数之间,是“或”的关系  
133 - */  
134 - private List<TriggerConditionParameter> parameters;  
135 -  
136 - }  
137 -  
138 - /**  
139 - * 触发条件参数  
140 - */  
141 - @Data  
142 - public static class TriggerConditionParameter {  
143 -  
144 - /**  
145 - * 标识符(属性、事件、服务)  
146 - *  
147 - * 关联 {@link IotThingModelDO#getIdentifier()}  
148 - */  
149 - private String identifier;  
150 -  
151 - /**  
152 - * 操作符  
153 - *  
154 - * 枚举 {@link IotRuleSceneTriggerConditionParameterOperatorEnum}  
155 - */  
156 - private String operator;  
157 -  
158 - /**  
159 - * 比较值  
160 - *  
161 - * 如果有多个值,则使用 "," 分隔,类似 "1,2,3"。  
162 - * 例如说,{@link IotRuleSceneTriggerConditionParameterOperatorEnum#IN}、{@link IotRuleSceneTriggerConditionParameterOperatorEnum#BETWEEN}  
163 - */  
164 - private String value;  
165 -  
166 - }  
167 -  
168 - /**  
169 - * 执行器配置  
170 - */  
171 - @Data  
172 - public static class ActionConfig {  
173 -  
174 - /**  
175 - * 执行类型  
176 - *  
177 - * 枚举 {@link IotRuleSceneActionTypeEnum}  
178 - */  
179 - private Integer type;  
180 -  
181 - /**  
182 - * 设备控制  
183 - *  
184 - * 必填:当 {@link #type} 为 {@link IotRuleSceneActionTypeEnum#DEVICE_CONTROL} 时  
185 - */  
186 - private ActionDeviceControl deviceControl;  
187 -  
188 - /**  
189 - * 数据桥接编号  
190 - *  
191 - * 必填:当 {@link #type} 为 {@link IotRuleSceneActionTypeEnum#DATA_BRIDGE} 时  
192 - * 关联:{@link IotDataBridgeDO#getId()}  
193 - */  
194 - private Long dataBridgeId;  
195 -  
196 - }  
197 -  
198 - /**  
199 - * 执行设备控制  
200 - */  
201 - @Data  
202 - public static class ActionDeviceControl {  
203 -  
204 - /**  
205 - * 产品标识  
206 - *  
207 - * 关联 {@link IotProductDO#getProductKey()}  
208 - */  
209 - private String productKey;  
210 - /**  
211 - * 设备名称数组  
212 - *  
213 - * 关联 {@link IotDeviceDO#getDeviceName()}  
214 - */  
215 - private List<String> deviceNames;  
216 -  
217 - /**  
218 - * 消息类型  
219 - *  
220 - * 枚举 {@link IotDeviceMessageTypeEnum#PROPERTY}、{@link IotDeviceMessageTypeEnum#SERVICE}  
221 - */  
222 - private String type;  
223 - /**  
224 - * 消息标识符  
225 - *  
226 - * 枚举 {@link IotDeviceMessageIdentifierEnum}  
227 - *  
228 - * 1. 属性设置:对应 {@link IotDeviceMessageIdentifierEnum#PROPERTY_SET}  
229 - * 2. 服务调用:对应 {@link IotDeviceMessageIdentifierEnum#SERVICE_INVOKE}  
230 - */  
231 - private String identifier;  
232 -  
233 - /**  
234 - * 具体数据  
235 - *  
236 - * 1. 属性设置:在 {@link #type} 是 {@link IotDeviceMessageTypeEnum#PROPERTY} 时,对应 properties  
237 - * 2. 服务调用:在 {@link #type} 是 {@link IotDeviceMessageTypeEnum#SERVICE} 时,对应 params  
238 - */  
239 - private Map<String, Object> data;  
240 -  
241 - } 61 + private List<IotRuleSceneActionConfig> actions;
242 62
243 } 63 }
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/rule/IotRuleSceneMapper.java
1 package cn.iocoder.yudao.module.iot.dal.mysql.rule; 1 package cn.iocoder.yudao.module.iot.dal.mysql.rule;
2 2
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
3 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleScenePageReqVO;
4 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; 7 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO;
5 import org.apache.ibatis.annotations.Mapper; 8 import org.apache.ibatis.annotations.Mapper;
6 9
  10 +/**
  11 + * IoT 规则场景(场景联动) Mapper
  12 + *
  13 + * @author HUIHUI
  14 + */
7 @Mapper 15 @Mapper
8 public interface IotRuleSceneMapper extends BaseMapperX<IotRuleSceneDO> { 16 public interface IotRuleSceneMapper extends BaseMapperX<IotRuleSceneDO> {
9 17
  18 + default PageResult<IotRuleSceneDO> selectPage(IotRuleScenePageReqVO reqVO) {
  19 + return selectPage(reqVO, new LambdaQueryWrapperX<IotRuleSceneDO>()
  20 + .likeIfPresent(IotRuleSceneDO::getName, reqVO.getName())
  21 + .likeIfPresent(IotRuleSceneDO::getDescription, reqVO.getDescription())
  22 + .eqIfPresent(IotRuleSceneDO::getStatus, reqVO.getStatus())
  23 + .betweenIfPresent(IotRuleSceneDO::getCreateTime, reqVO.getCreateTime())
  24 + .orderByDesc(IotRuleSceneDO::getId));
  25 + }
  26 +
10 } 27 }
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/IotRuleSceneService.java
1 package cn.iocoder.yudao.module.iot.service.rule; 1 package cn.iocoder.yudao.module.iot.service.rule;
2 2
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleScenePageReqVO;
  5 +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleSceneSaveReqVO;
3 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; 6 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO;
4 import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneTriggerTypeEnum; 7 import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneTriggerTypeEnum;
5 import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; 8 import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage;
  9 +import jakarta.validation.Valid;
6 10
7 import java.util.List; 11 import java.util.List;
8 12
@@ -14,6 +18,44 @@ import java.util.List; @@ -14,6 +18,44 @@ import java.util.List;
14 public interface IotRuleSceneService { 18 public interface IotRuleSceneService {
15 19
16 /** 20 /**
  21 + * 创建规则场景(场景联动)
  22 + *
  23 + * @param createReqVO 创建信息
  24 + * @return 编号
  25 + */
  26 + Long createRuleScene(@Valid IotRuleSceneSaveReqVO createReqVO);
  27 +
  28 + /**
  29 + * 更新规则场景(场景联动)
  30 + *
  31 + * @param updateReqVO 更新信息
  32 + */
  33 + void updateRuleScene(@Valid IotRuleSceneSaveReqVO updateReqVO);
  34 +
  35 + /**
  36 + * 删除规则场景(场景联动)
  37 + *
  38 + * @param id 编号
  39 + */
  40 + void deleteRuleScene(Long id);
  41 +
  42 + /**
  43 + * 获得规则场景(场景联动)
  44 + *
  45 + * @param id 编号
  46 + * @return 规则场景(场景联动)
  47 + */
  48 + IotRuleSceneDO getRuleScene(Long id);
  49 +
  50 + /**
  51 + * 获得规则场景(场景联动)分页
  52 + *
  53 + * @param pageReqVO 分页查询
  54 + * @return 规则场景(场景联动)分页
  55 + */
  56 + PageResult<IotRuleSceneDO> getRuleScenePage(IotRuleScenePageReqVO pageReqVO);
  57 +
  58 + /**
17 * 【缓存】获得指定设备的场景列表 59 * 【缓存】获得指定设备的场景列表
18 * 60 *
19 * @param productKey 产品 Key 61 * @param productKey 产品 Key
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/IotRuleSceneServiceImpl.java
@@ -8,11 +8,16 @@ import cn.hutool.core.util.NumberUtil; @@ -8,11 +8,16 @@ import cn.hutool.core.util.NumberUtil;
8 import cn.hutool.core.util.ObjUtil; 8 import cn.hutool.core.util.ObjUtil;
9 import cn.hutool.core.util.StrUtil; 9 import cn.hutool.core.util.StrUtil;
10 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 10 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  11 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
11 import cn.iocoder.yudao.framework.common.util.number.NumberUtils; 12 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
  13 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
12 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; 14 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
13 import cn.iocoder.yudao.framework.common.util.spring.SpringExpressionUtils; 15 import cn.iocoder.yudao.framework.common.util.spring.SpringExpressionUtils;
14 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; 16 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
15 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;
  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.*;
16 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; 21 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO;
17 import cn.iocoder.yudao.module.iot.dal.mysql.rule.IotRuleSceneMapper; 22 import cn.iocoder.yudao.module.iot.dal.mysql.rule.IotRuleSceneMapper;
18 import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum; 23 import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum;
@@ -39,8 +44,10 @@ import java.util.HashMap; @@ -39,8 +44,10 @@ import java.util.HashMap;
39 import java.util.List; 44 import java.util.List;
40 import java.util.Map; 45 import java.util.Map;
41 46
  47 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
42 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; 48 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
43 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList; 49 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList;
  50 +import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.RULE_SCENE_NOT_EXISTS;
44 51
45 /** 52 /**
46 * IoT 规则场景 Service 实现类 53 * IoT 规则场景 Service 实现类
@@ -61,6 +68,49 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { @@ -61,6 +68,49 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService {
61 @Resource(name = "iotSchedulerManager") 68 @Resource(name = "iotSchedulerManager")
62 private IotSchedulerManager schedulerManager; 69 private IotSchedulerManager schedulerManager;
63 70
  71 + @Override
  72 + public Long createRuleScene(IotRuleSceneSaveReqVO createReqVO) {
  73 + // 插入
  74 + IotRuleSceneDO ruleScene = BeanUtils.toBean(createReqVO, IotRuleSceneDO.class);
  75 + ruleSceneMapper.insert(ruleScene);
  76 + // 返回
  77 + return ruleScene.getId();
  78 + }
  79 +
  80 + @Override
  81 + public void updateRuleScene(IotRuleSceneSaveReqVO updateReqVO) {
  82 + // 校验存在
  83 + validateRuleSceneExists(updateReqVO.getId());
  84 + // 更新
  85 + IotRuleSceneDO updateObj = BeanUtils.toBean(updateReqVO, IotRuleSceneDO.class);
  86 + ruleSceneMapper.updateById(updateObj);
  87 + }
  88 +
  89 + @Override
  90 + public void deleteRuleScene(Long id) {
  91 + // 校验存在
  92 + validateRuleSceneExists(id);
  93 + // 删除
  94 + ruleSceneMapper.deleteById(id);
  95 + }
  96 +
  97 + private void validateRuleSceneExists(Long id) {
  98 + if (ruleSceneMapper.selectById(id) == null) {
  99 + throw exception(RULE_SCENE_NOT_EXISTS);
  100 + }
  101 + }
  102 +
  103 + @Override
  104 + public IotRuleSceneDO getRuleScene(Long id) {
  105 + return ruleSceneMapper.selectById(id);
  106 + }
  107 +
  108 + @Override
  109 + public PageResult<IotRuleSceneDO> getRuleScenePage(IotRuleScenePageReqVO pageReqVO) {
  110 + return ruleSceneMapper.selectPage(pageReqVO);
  111 + }
  112 +
  113 +
64 // TODO 芋艿,缓存待实现 114 // TODO 芋艿,缓存待实现
65 @Override 115 @Override
66 @TenantIgnore // 忽略租户隔离:因为 IotRuleSceneMessageHandler 调用时,一般未传递租户,所以需要忽略 116 @TenantIgnore // 忽略租户隔离:因为 IotRuleSceneMessageHandler 调用时,一般未传递租户,所以需要忽略
@@ -68,82 +118,82 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { @@ -68,82 +118,82 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService {
68 if (true) { 118 if (true) {
69 IotRuleSceneDO ruleScene01 = new IotRuleSceneDO(); 119 IotRuleSceneDO ruleScene01 = new IotRuleSceneDO();
70 ruleScene01.setTriggers(CollUtil.newArrayList()); 120 ruleScene01.setTriggers(CollUtil.newArrayList());
71 - IotRuleSceneDO.TriggerConfig trigger01 = new IotRuleSceneDO.TriggerConfig(); 121 + IotRuleSceneTriggerConfig trigger01 = new IotRuleSceneTriggerConfig();
72 trigger01.setType(IotRuleSceneTriggerTypeEnum.DEVICE.getType()); 122 trigger01.setType(IotRuleSceneTriggerTypeEnum.DEVICE.getType());
73 trigger01.setConditions(CollUtil.newArrayList()); 123 trigger01.setConditions(CollUtil.newArrayList());
74 // 属性 124 // 属性
75 - IotRuleSceneDO.TriggerCondition condition01 = new IotRuleSceneDO.TriggerCondition(); 125 + IotRuleSceneTriggerCondition condition01 = new IotRuleSceneTriggerCondition();
76 condition01.setType(IotDeviceMessageTypeEnum.PROPERTY.getType()); 126 condition01.setType(IotDeviceMessageTypeEnum.PROPERTY.getType());
77 condition01.setIdentifier(IotDeviceMessageIdentifierEnum.PROPERTY_REPORT.getIdentifier()); 127 condition01.setIdentifier(IotDeviceMessageIdentifierEnum.PROPERTY_REPORT.getIdentifier());
78 condition01.setParameters(CollUtil.newArrayList()); 128 condition01.setParameters(CollUtil.newArrayList());
79 -// IotRuleSceneDO.TriggerConditionParameter parameter010 = new IotRuleSceneDO.TriggerConditionParameter(); 129 +// IotRuleSceneTriggerConditionParameter parameter010 = new IotRuleSceneTriggerConditionParameter();
80 // parameter010.setIdentifier("width"); 130 // parameter010.setIdentifier("width");
81 // parameter010.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.getOperator()); 131 // parameter010.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.getOperator());
82 // parameter010.setValue("abc"); 132 // parameter010.setValue("abc");
83 // condition01.getParameters().add(parameter010); 133 // condition01.getParameters().add(parameter010);
84 - IotRuleSceneDO.TriggerConditionParameter parameter011 = new IotRuleSceneDO.TriggerConditionParameter(); 134 + IotRuleSceneTriggerConditionParameter parameter011 = new IotRuleSceneTriggerConditionParameter();
85 parameter011.setIdentifier("width"); 135 parameter011.setIdentifier("width");
86 parameter011.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.getOperator()); 136 parameter011.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.getOperator());
87 parameter011.setValue("1"); 137 parameter011.setValue("1");
88 condition01.getParameters().add(parameter011); 138 condition01.getParameters().add(parameter011);
89 - IotRuleSceneDO.TriggerConditionParameter parameter012 = new IotRuleSceneDO.TriggerConditionParameter(); 139 + IotRuleSceneTriggerConditionParameter parameter012 = new IotRuleSceneTriggerConditionParameter();
90 parameter012.setIdentifier("width"); 140 parameter012.setIdentifier("width");
91 parameter012.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_EQUALS.getOperator()); 141 parameter012.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_EQUALS.getOperator());
92 parameter012.setValue("2"); 142 parameter012.setValue("2");
93 condition01.getParameters().add(parameter012); 143 condition01.getParameters().add(parameter012);
94 - IotRuleSceneDO.TriggerConditionParameter parameter013 = new IotRuleSceneDO.TriggerConditionParameter(); 144 + IotRuleSceneTriggerConditionParameter parameter013 = new IotRuleSceneTriggerConditionParameter();
95 parameter013.setIdentifier("width"); 145 parameter013.setIdentifier("width");
96 parameter013.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.GREATER_THAN.getOperator()); 146 parameter013.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.GREATER_THAN.getOperator());
97 parameter013.setValue("0"); 147 parameter013.setValue("0");
98 condition01.getParameters().add(parameter013); 148 condition01.getParameters().add(parameter013);
99 - IotRuleSceneDO.TriggerConditionParameter parameter014 = new IotRuleSceneDO.TriggerConditionParameter(); 149 + IotRuleSceneTriggerConditionParameter parameter014 = new IotRuleSceneTriggerConditionParameter();
100 parameter014.setIdentifier("width"); 150 parameter014.setIdentifier("width");
101 parameter014.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.GREATER_THAN_OR_EQUALS.getOperator()); 151 parameter014.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.GREATER_THAN_OR_EQUALS.getOperator());
102 parameter014.setValue("0"); 152 parameter014.setValue("0");
103 condition01.getParameters().add(parameter014); 153 condition01.getParameters().add(parameter014);
104 - IotRuleSceneDO.TriggerConditionParameter parameter015 = new IotRuleSceneDO.TriggerConditionParameter(); 154 + IotRuleSceneTriggerConditionParameter parameter015 = new IotRuleSceneTriggerConditionParameter();
105 parameter015.setIdentifier("width"); 155 parameter015.setIdentifier("width");
106 parameter015.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.LESS_THAN.getOperator()); 156 parameter015.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.LESS_THAN.getOperator());
107 parameter015.setValue("2"); 157 parameter015.setValue("2");
108 condition01.getParameters().add(parameter015); 158 condition01.getParameters().add(parameter015);
109 - IotRuleSceneDO.TriggerConditionParameter parameter016 = new IotRuleSceneDO.TriggerConditionParameter(); 159 + IotRuleSceneTriggerConditionParameter parameter016 = new IotRuleSceneTriggerConditionParameter();
110 parameter016.setIdentifier("width"); 160 parameter016.setIdentifier("width");
111 parameter016.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.LESS_THAN_OR_EQUALS.getOperator()); 161 parameter016.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.LESS_THAN_OR_EQUALS.getOperator());
112 parameter016.setValue("2"); 162 parameter016.setValue("2");
113 condition01.getParameters().add(parameter016); 163 condition01.getParameters().add(parameter016);
114 - IotRuleSceneDO.TriggerConditionParameter parameter017 = new IotRuleSceneDO.TriggerConditionParameter(); 164 + IotRuleSceneTriggerConditionParameter parameter017 = new IotRuleSceneTriggerConditionParameter();
115 parameter017.setIdentifier("width"); 165 parameter017.setIdentifier("width");
116 parameter017.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.IN.getOperator()); 166 parameter017.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.IN.getOperator());
117 parameter017.setValue("1,2,3"); 167 parameter017.setValue("1,2,3");
118 condition01.getParameters().add(parameter017); 168 condition01.getParameters().add(parameter017);
119 - IotRuleSceneDO.TriggerConditionParameter parameter018 = new IotRuleSceneDO.TriggerConditionParameter(); 169 + IotRuleSceneTriggerConditionParameter parameter018 = new IotRuleSceneTriggerConditionParameter();
120 parameter018.setIdentifier("width"); 170 parameter018.setIdentifier("width");
121 parameter018.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_IN.getOperator()); 171 parameter018.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_IN.getOperator());
122 parameter018.setValue("0,2,3"); 172 parameter018.setValue("0,2,3");
123 condition01.getParameters().add(parameter018); 173 condition01.getParameters().add(parameter018);
124 - IotRuleSceneDO.TriggerConditionParameter parameter019 = new IotRuleSceneDO.TriggerConditionParameter(); 174 + IotRuleSceneTriggerConditionParameter parameter019 = new IotRuleSceneTriggerConditionParameter();
125 parameter019.setIdentifier("width"); 175 parameter019.setIdentifier("width");
126 parameter019.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.BETWEEN.getOperator()); 176 parameter019.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.BETWEEN.getOperator());
127 parameter019.setValue("1,3"); 177 parameter019.setValue("1,3");
128 condition01.getParameters().add(parameter019); 178 condition01.getParameters().add(parameter019);
129 - IotRuleSceneDO.TriggerConditionParameter parameter020 = new IotRuleSceneDO.TriggerConditionParameter(); 179 + IotRuleSceneTriggerConditionParameter parameter020 = new IotRuleSceneTriggerConditionParameter();
130 parameter020.setIdentifier("width"); 180 parameter020.setIdentifier("width");
131 parameter020.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_BETWEEN.getOperator()); 181 parameter020.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_BETWEEN.getOperator());
132 parameter020.setValue("2,3"); 182 parameter020.setValue("2,3");
133 condition01.getParameters().add(parameter020); 183 condition01.getParameters().add(parameter020);
134 trigger01.getConditions().add(condition01); 184 trigger01.getConditions().add(condition01);
135 // 状态 185 // 状态
136 - IotRuleSceneDO.TriggerCondition condition02 = new IotRuleSceneDO.TriggerCondition(); 186 + IotRuleSceneTriggerCondition condition02 = new IotRuleSceneTriggerCondition();
137 condition02.setType(IotDeviceMessageTypeEnum.STATE.getType()); 187 condition02.setType(IotDeviceMessageTypeEnum.STATE.getType());
138 condition02.setIdentifier(IotDeviceMessageIdentifierEnum.STATE_ONLINE.getIdentifier()); 188 condition02.setIdentifier(IotDeviceMessageIdentifierEnum.STATE_ONLINE.getIdentifier());
139 condition02.setParameters(CollUtil.newArrayList()); 189 condition02.setParameters(CollUtil.newArrayList());
140 trigger01.getConditions().add(condition02); 190 trigger01.getConditions().add(condition02);
141 // 事件 191 // 事件
142 - IotRuleSceneDO.TriggerCondition condition03 = new IotRuleSceneDO.TriggerCondition(); 192 + IotRuleSceneTriggerCondition condition03 = new IotRuleSceneTriggerCondition();
143 condition03.setType(IotDeviceMessageTypeEnum.EVENT.getType()); 193 condition03.setType(IotDeviceMessageTypeEnum.EVENT.getType());
144 condition03.setIdentifier("xxx"); 194 condition03.setIdentifier("xxx");
145 condition03.setParameters(CollUtil.newArrayList()); 195 condition03.setParameters(CollUtil.newArrayList());
146 - IotRuleSceneDO.TriggerConditionParameter parameter030 = new IotRuleSceneDO.TriggerConditionParameter(); 196 + IotRuleSceneTriggerConditionParameter parameter030 = new IotRuleSceneTriggerConditionParameter();
147 parameter030.setIdentifier("width"); 197 parameter030.setIdentifier("width");
148 parameter030.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.getOperator()); 198 parameter030.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.getOperator());
149 parameter030.setValue("1"); 199 parameter030.setValue("1");
@@ -152,21 +202,21 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { @@ -152,21 +202,21 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService {
152 // 动作 202 // 动作
153 ruleScene01.setActions(CollUtil.newArrayList()); 203 ruleScene01.setActions(CollUtil.newArrayList());
154 // 设备控制 204 // 设备控制
155 - IotRuleSceneDO.ActionConfig action01 = new IotRuleSceneDO.ActionConfig(); 205 + IotRuleSceneActionConfig action01 = new IotRuleSceneActionConfig();
156 action01.setType(IotRuleSceneActionTypeEnum.DEVICE_CONTROL.getType()); 206 action01.setType(IotRuleSceneActionTypeEnum.DEVICE_CONTROL.getType());
157 - IotRuleSceneDO.ActionDeviceControl actionDeviceControl01 = new IotRuleSceneDO.ActionDeviceControl();  
158 - actionDeviceControl01.setProductKey("4aymZgOTOOCrDKRT");  
159 - actionDeviceControl01.setDeviceNames(ListUtil.of("small"));  
160 - actionDeviceControl01.setType(IotDeviceMessageTypeEnum.PROPERTY.getType());  
161 - actionDeviceControl01.setIdentifier(IotDeviceMessageIdentifierEnum.PROPERTY_SET.getIdentifier());  
162 - actionDeviceControl01.setData(MapUtil.<String, Object>builder() 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()
163 .put("power", 1) 213 .put("power", 1)
164 .put("color", "red") 214 .put("color", "red")
165 .build()); 215 .build());
166 - action01.setDeviceControl(actionDeviceControl01); 216 + action01.setDeviceControl(iotRuleSceneActionDeviceControl01);
167 // ruleScene01.getActions().add(action01); // TODO 芋艿:先不测试了 217 // ruleScene01.getActions().add(action01); // TODO 芋艿:先不测试了
168 // 数据桥接(http) 218 // 数据桥接(http)
169 - IotRuleSceneDO.ActionConfig action02 = new IotRuleSceneDO.ActionConfig(); 219 + IotRuleSceneActionConfig action02 = new IotRuleSceneActionConfig();
170 action02.setType(IotRuleSceneActionTypeEnum.DATA_BRIDGE.getType()); 220 action02.setType(IotRuleSceneActionTypeEnum.DATA_BRIDGE.getType());
171 action02.setDataBridgeId(1L); 221 action02.setDataBridgeId(1L);
172 ruleScene01.getActions().add(action02); 222 ruleScene01.getActions().add(action02);
@@ -176,7 +226,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { @@ -176,7 +226,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService {
176 List<IotRuleSceneDO> list = ruleSceneMapper.selectList(); 226 List<IotRuleSceneDO> list = ruleSceneMapper.selectList();
177 // TODO @芋艿:需要考虑开启状态 227 // TODO @芋艿:需要考虑开启状态
178 return filterList(list, ruleScene -> { 228 return filterList(list, ruleScene -> {
179 - for (IotRuleSceneDO.TriggerConfig trigger : ruleScene.getTriggers()) { 229 + for (IotRuleSceneTriggerConfig trigger : ruleScene.getTriggers()) {
180 if (ObjUtil.notEqual(trigger.getProductKey(), productKey)) { 230 if (ObjUtil.notEqual(trigger.getProductKey(), productKey)) {
181 continue; 231 continue;
182 } 232 }
@@ -211,22 +261,22 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { @@ -211,22 +261,22 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService {
211 IotRuleSceneDO scene = new IotRuleSceneDO().setStatus(CommonStatusEnum.ENABLE.getStatus()); 261 IotRuleSceneDO scene = new IotRuleSceneDO().setStatus(CommonStatusEnum.ENABLE.getStatus());
212 if (true) { 262 if (true) {
213 scene.setTenantId(1L); 263 scene.setTenantId(1L);
214 - IotRuleSceneDO.TriggerConfig triggerConfig = new IotRuleSceneDO.TriggerConfig();  
215 - triggerConfig.setType(IotRuleSceneTriggerTypeEnum.TIMER.getType());  
216 - scene.setTriggers(ListUtil.toList(triggerConfig)); 264 + IotRuleSceneTriggerConfig iotRuleSceneTriggerConfig = new IotRuleSceneTriggerConfig();
  265 + iotRuleSceneTriggerConfig.setType(IotRuleSceneTriggerTypeEnum.TIMER.getType());
  266 + scene.setTriggers(ListUtil.toList(iotRuleSceneTriggerConfig));
217 // 动作 267 // 动作
218 - IotRuleSceneDO.ActionConfig action01 = new IotRuleSceneDO.ActionConfig(); 268 + IotRuleSceneActionConfig action01 = new IotRuleSceneActionConfig();
219 action01.setType(IotRuleSceneActionTypeEnum.DEVICE_CONTROL.getType()); 269 action01.setType(IotRuleSceneActionTypeEnum.DEVICE_CONTROL.getType());
220 - IotRuleSceneDO.ActionDeviceControl actionDeviceControl01 = new IotRuleSceneDO.ActionDeviceControl();  
221 - actionDeviceControl01.setProductKey("4aymZgOTOOCrDKRT");  
222 - actionDeviceControl01.setDeviceNames(ListUtil.of("small"));  
223 - actionDeviceControl01.setType(IotDeviceMessageTypeEnum.PROPERTY.getType());  
224 - actionDeviceControl01.setIdentifier(IotDeviceMessageIdentifierEnum.PROPERTY_SET.getIdentifier());  
225 - actionDeviceControl01.setData(MapUtil.<String, Object>builder() 270 + IotRuleSceneActionDeviceControl iotRuleSceneActionDeviceControl01 = new IotRuleSceneActionDeviceControl();
  271 + iotRuleSceneActionDeviceControl01.setProductKey("4aymZgOTOOCrDKRT");
  272 + iotRuleSceneActionDeviceControl01.setDeviceNames(ListUtil.of("small"));
  273 + iotRuleSceneActionDeviceControl01.setType(IotDeviceMessageTypeEnum.PROPERTY.getType());
  274 + iotRuleSceneActionDeviceControl01.setIdentifier(IotDeviceMessageIdentifierEnum.PROPERTY_SET.getIdentifier());
  275 + iotRuleSceneActionDeviceControl01.setData(MapUtil.<String, Object>builder()
226 .put("power", 1) 276 .put("power", 1)
227 .put("color", "red") 277 .put("color", "red")
228 .build()); 278 .build());
229 - action01.setDeviceControl(actionDeviceControl01); 279 + action01.setDeviceControl(iotRuleSceneActionDeviceControl01);
230 scene.setActions(ListUtil.toList(action01)); 280 scene.setActions(ListUtil.toList(action01));
231 } 281 }
232 if (scene == null) { 282 if (scene == null) {
@@ -238,7 +288,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { @@ -238,7 +288,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService {
238 return; 288 return;
239 } 289 }
240 // 1.2 判断是否有定时触发器,避免脏数据 290 // 1.2 判断是否有定时触发器,避免脏数据
241 - IotRuleSceneDO.TriggerConfig config = CollUtil.findOne(scene.getTriggers(), 291 + IotRuleSceneTriggerConfig config = CollUtil.findOne(scene.getTriggers(),
242 trigger -> ObjUtil.equals(trigger.getType(), IotRuleSceneTriggerTypeEnum.TIMER.getType())); 292 trigger -> ObjUtil.equals(trigger.getType(), IotRuleSceneTriggerTypeEnum.TIMER.getType()));
243 if (config == null) { 293 if (config == null) {
244 log.error("[executeRuleSceneByTimer][规则场景({}) 不存在定时触发器]", scene); 294 log.error("[executeRuleSceneByTimer][规则场景({}) 不存在定时触发器]", scene);
@@ -267,7 +317,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { @@ -267,7 +317,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService {
267 317
268 // 2. 匹配 trigger 触发器的条件 318 // 2. 匹配 trigger 触发器的条件
269 return filterList(ruleScenes, ruleScene -> { 319 return filterList(ruleScenes, ruleScene -> {
270 - for (IotRuleSceneDO.TriggerConfig trigger : ruleScene.getTriggers()) { 320 + for (IotRuleSceneTriggerConfig trigger : ruleScene.getTriggers()) {
271 // 2.1 非设备触发,不匹配 321 // 2.1 非设备触发,不匹配
272 if (ObjUtil.notEqual(trigger.getType(), IotRuleSceneTriggerTypeEnum.DEVICE.getType())) { 322 if (ObjUtil.notEqual(trigger.getType(), IotRuleSceneTriggerTypeEnum.DEVICE.getType())) {
273 return false; 323 return false;
@@ -278,13 +328,13 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { @@ -278,13 +328,13 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService {
278 return false; 328 return false;
279 } 329 }
280 // 2.3 多个条件,只需要满足一个即可 330 // 2.3 多个条件,只需要满足一个即可
281 - IotRuleSceneDO.TriggerCondition matchedCondition = CollUtil.findOne(trigger.getConditions(), condition -> { 331 + IotRuleSceneTriggerCondition matchedCondition = CollUtil.findOne(trigger.getConditions(), condition -> {
282 if (ObjUtil.notEqual(message.getType(), condition.getType()) 332 if (ObjUtil.notEqual(message.getType(), condition.getType())
283 || ObjUtil.notEqual(message.getIdentifier(), condition.getIdentifier())) { 333 || ObjUtil.notEqual(message.getIdentifier(), condition.getIdentifier())) {
284 return false; 334 return false;
285 } 335 }
286 // 多个条件参数,必须全部满足。所以,下面的逻辑就是找到一个不满足的条件参数 336 // 多个条件参数,必须全部满足。所以,下面的逻辑就是找到一个不满足的条件参数
287 - IotRuleSceneDO.TriggerConditionParameter notMatchedParameter = CollUtil.findOne(condition.getParameters(), 337 + IotRuleSceneTriggerConditionParameter notMatchedParameter = CollUtil.findOne(condition.getParameters(),
288 parameter -> !isTriggerConditionParameterMatched(message, parameter, ruleScene, trigger)); 338 parameter -> !isTriggerConditionParameterMatched(message, parameter, ruleScene, trigger));
289 return notMatchedParameter == null; 339 return notMatchedParameter == null;
290 }); 340 });
@@ -299,6 +349,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { @@ -299,6 +349,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService {
299 } 349 }
300 350
301 // TODO @芋艿:【可优化】可以考虑增加下单测,边界太多了。 351 // TODO @芋艿:【可优化】可以考虑增加下单测,边界太多了。
  352 +
302 /** 353 /**
303 * 判断触发器的条件参数是否匹配 354 * 判断触发器的条件参数是否匹配
304 * 355 *
@@ -309,8 +360,8 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { @@ -309,8 +360,8 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService {
309 * @return 是否匹配 360 * @return 是否匹配
310 */ 361 */
311 @SuppressWarnings({"unchecked", "DataFlowIssue"}) 362 @SuppressWarnings({"unchecked", "DataFlowIssue"})
312 - private boolean isTriggerConditionParameterMatched(IotDeviceMessage message, IotRuleSceneDO.TriggerConditionParameter parameter,  
313 - IotRuleSceneDO ruleScene, IotRuleSceneDO.TriggerConfig trigger) { 363 + private boolean isTriggerConditionParameterMatched(IotDeviceMessage message, IotRuleSceneTriggerConditionParameter parameter,
  364 + IotRuleSceneDO ruleScene, IotRuleSceneTriggerConfig trigger) {
314 // 1.1 校验操作符是否合法 365 // 1.1 校验操作符是否合法
315 IotRuleSceneTriggerConditionParameterOperatorEnum operator = 366 IotRuleSceneTriggerConditionParameterOperatorEnum operator =
316 IotRuleSceneTriggerConditionParameterOperatorEnum.operatorOf(parameter.getOperator()); 367 IotRuleSceneTriggerConditionParameterOperatorEnum.operatorOf(parameter.getOperator());
@@ -331,7 +382,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { @@ -331,7 +382,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService {
331 springExpressionVariables.put(IotRuleSceneTriggerConditionParameterOperatorEnum.SPRING_EXPRESSION_SOURCE, messageValue); 382 springExpressionVariables.put(IotRuleSceneTriggerConditionParameterOperatorEnum.SPRING_EXPRESSION_SOURCE, messageValue);
332 springExpressionVariables.put(IotRuleSceneTriggerConditionParameterOperatorEnum.SPRING_EXPRESSION_VALUE, parameter.getValue()); 383 springExpressionVariables.put(IotRuleSceneTriggerConditionParameterOperatorEnum.SPRING_EXPRESSION_VALUE, parameter.getValue());
333 List<String> parameterValues = StrUtil.splitTrim(parameter.getValue(), CharPool.COMMA); 384 List<String> parameterValues = StrUtil.splitTrim(parameter.getValue(), CharPool.COMMA);
334 - springExpressionVariables.put(IotRuleSceneTriggerConditionParameterOperatorEnum.SPRING_EXPRESSION_VALUE_List, parameterValues); 385 + springExpressionVariables.put(IotRuleSceneTriggerConditionParameterOperatorEnum.SPRING_EXPRESSION_VALUE_LIST, parameterValues);
335 // 特殊:解决数字的比较。因为 Spring 是基于它的 compareTo 方法,对数字的比较存在问题! 386 // 特殊:解决数字的比较。因为 Spring 是基于它的 compareTo 方法,对数字的比较存在问题!
336 if (ObjectUtils.equalsAny(operator, IotRuleSceneTriggerConditionParameterOperatorEnum.BETWEEN, 387 if (ObjectUtils.equalsAny(operator, IotRuleSceneTriggerConditionParameterOperatorEnum.BETWEEN,
337 IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_BETWEEN, 388 IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_BETWEEN,
@@ -345,7 +396,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { @@ -345,7 +396,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService {
345 NumberUtil.parseDouble(messageValue)); 396 NumberUtil.parseDouble(messageValue));
346 springExpressionVariables.put(IotRuleSceneTriggerConditionParameterOperatorEnum.SPRING_EXPRESSION_VALUE, 397 springExpressionVariables.put(IotRuleSceneTriggerConditionParameterOperatorEnum.SPRING_EXPRESSION_VALUE,
347 NumberUtil.parseDouble(parameter.getValue())); 398 NumberUtil.parseDouble(parameter.getValue()));
348 - springExpressionVariables.put(IotRuleSceneTriggerConditionParameterOperatorEnum.SPRING_EXPRESSION_VALUE_List, 399 + springExpressionVariables.put(IotRuleSceneTriggerConditionParameterOperatorEnum.SPRING_EXPRESSION_VALUE_LIST,
349 convertList(parameterValues, NumberUtil::parseDouble)); 400 convertList(parameterValues, NumberUtil::parseDouble));
350 } 401 }
351 // 2.2 计算 Spring 表达式 402 // 2.2 计算 Spring 表达式
@@ -410,7 +461,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { @@ -410,7 +461,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService {
410 schedulerManager.addOrUpdateJob(IotRuleSceneJob.class, 461 schedulerManager.addOrUpdateJob(IotRuleSceneJob.class,
411 IotRuleSceneJob.buildJobName(id), 462 IotRuleSceneJob.buildJobName(id),
412 "0/10 * * * * ?", 463 "0/10 * * * * ?",
413 - jobDataMap); 464 + jobDataMap);
414 } 465 }
415 if (false) { 466 if (false) {
416 Long id = 1L; 467 Long id = 1L;
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.dal.dataobject.rule.IotRuleSceneDO; 3 +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config.IotRuleSceneActionConfig;
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
@@ -14,15 +14,16 @@ import javax.annotation.Nullable; @@ -14,15 +14,16 @@ import javax.annotation.Nullable;
14 public interface IotRuleSceneAction { 14 public interface IotRuleSceneAction {
15 15
16 // TODO @芋艿:groovy 或者 javascript 实现数据的转换;可以考虑基于 hutool 的 ScriptUtil 做 16 // TODO @芋艿:groovy 或者 javascript 实现数据的转换;可以考虑基于 hutool 的 ScriptUtil 做
  17 +
17 /** 18 /**
18 * 执行场景 19 * 执行场景
19 * 20 *
20 * @param message 消息,允许空 21 * @param message 消息,允许空
21 * 1. 空的情况:定时触发 22 * 1. 空的情况:定时触发
22 * 2. 非空的情况:设备触发 23 * 2. 非空的情况:设备触发
23 - * @param config 配置 24 + * @param config 配置
24 */ 25 */
25 - void execute(@Nullable IotDeviceMessage message, IotRuleSceneDO.ActionConfig config) throws Exception; 26 + void execute(@Nullable IotDeviceMessage message, IotRuleSceneActionConfig config) throws Exception;
26 27
27 /** 28 /**
28 * 获得类型 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.dal.dataobject.rule.IotRuleSceneDO; 3 +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config.IotRuleSceneActionConfig;
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, IotRuleSceneDO.ActionConfig config) { 19 + public void execute(@Nullable IotDeviceMessage message, IotRuleSceneActionConfig 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;
5 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; 6 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, IotRuleSceneDO.ActionConfig config) throws Exception { 32 + public void execute(IotDeviceMessage message, IotRuleSceneActionConfig 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,8 +2,9 @@ package cn.iocoder.yudao.module.iot.service.rule.action; @@ -2,8 +2,9 @@ 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;
5 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; 7 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
6 -import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO;  
7 import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum; 8 import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum;
8 import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; 9 import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage;
9 import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; 10 import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
@@ -27,8 +28,8 @@ public class IotRuleSceneDeviceControlAction implements IotRuleSceneAction { @@ -27,8 +28,8 @@ public class IotRuleSceneDeviceControlAction implements IotRuleSceneAction {
27 private IotDeviceService deviceService; 28 private IotDeviceService deviceService;
28 29
29 @Override 30 @Override
30 - public void execute(IotDeviceMessage message, IotRuleSceneDO.ActionConfig config) {  
31 - IotRuleSceneDO.ActionDeviceControl control = config.getDeviceControl(); 31 + public void execute(IotDeviceMessage message, IotRuleSceneActionConfig config) {
  32 + IotRuleSceneActionDeviceControl control = config.getDeviceControl();
32 Assert.notNull(control, "设备控制配置不能为空"); 33 Assert.notNull(control, "设备控制配置不能为空");
33 // 遍历每个设备,下发消息 34 // 遍历每个设备,下发消息
34 control.getDeviceNames().forEach(deviceName -> { 35 control.getDeviceNames().forEach(deviceName -> {
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; @@ -4,6 +4,7 @@ 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;
7 import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; 8 import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO;
8 import jakarta.validation.Valid; 9 import jakarta.validation.Valid;
9 10
@@ -90,4 +91,12 @@ public interface IotThingModelService { @@ -90,4 +91,12 @@ public interface IotThingModelService {
90 */ 91 */
91 Long getThingModelCount(LocalDateTime createTime); 92 Long getThingModelCount(LocalDateTime createTime);
92 93
  94 + /**
  95 + * 通过产品 ID 获取产品物模型 TSL
  96 + *
  97 + * @param productId 产品 ID
  98 + * @return 产品物模型 TSL
  99 + */
  100 + IotThingModelTSLRespVO getThingModelTslByProductId(Long productId);
  101 +
93 } 102 }
94 \ No newline at end of file 103 \ 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;
4 import cn.hutool.core.util.ObjectUtil; 5 import cn.hutool.core.util.ObjectUtil;
5 import cn.hutool.core.util.StrUtil; 6 import cn.hutool.core.util.StrUtil;
6 import cn.hutool.extra.spring.SpringUtil; 7 import cn.hutool.extra.spring.SpringUtil;
@@ -13,6 +14,7 @@ import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelS @@ -13,6 +14,7 @@ import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.ThingModelS
13 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelListReqVO; 14 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelListReqVO;
14 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelPageReqVO; 15 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelPageReqVO;
15 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelSaveReqVO; 16 import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelSaveReqVO;
  17 +import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.vo.IotThingModelTSLRespVO;
16 import cn.iocoder.yudao.module.iot.convert.thingmodel.IotThingModelConvert; 18 import cn.iocoder.yudao.module.iot.convert.thingmodel.IotThingModelConvert;
17 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; 19 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
18 import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; 20 import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO;
@@ -149,6 +151,30 @@ public class IotThingModelServiceImpl implements IotThingModelService { @@ -149,6 +151,30 @@ public class IotThingModelServiceImpl implements IotThingModelService {
149 return thingModelMapper.selectList(reqVO); 151 return thingModelMapper.selectList(reqVO);
150 } 152 }
151 153
  154 + @Override
  155 + public IotThingModelTSLRespVO getThingModelTslByProductId(Long productId) {
  156 + IotThingModelTSLRespVO tslRespVO = new IotThingModelTSLRespVO();
  157 + // 1. 获得产品所有物模型定义
  158 + List<IotThingModelDO> thingModelList = thingModelMapper.selectListByProductId(productId);
  159 + if (CollUtil.isEmpty(thingModelList)) {
  160 + return tslRespVO;
  161 + }
  162 +
  163 + // 2.1 设置公共部分参数
  164 + IotThingModelDO thingModel = thingModelList.get(0);
  165 + tslRespVO.setProductId(thingModel.getProductId()).setProductKey(thingModel.getProductKey());
  166 + // 2.2 处理属性列表
  167 + tslRespVO.setProperties(convertList(filterList(thingModelList, item ->
  168 + ObjUtil.equal(IotThingModelTypeEnum.PROPERTY.getType(), item.getType())), IotThingModelDO::getProperty));
  169 + // 2.3 处理服务列表
  170 + tslRespVO.setServices(convertList(filterList(thingModelList, item ->
  171 + ObjUtil.equal(IotThingModelTypeEnum.SERVICE.getType(), item.getType())), IotThingModelDO::getService));
  172 + // 2.4 处理事件列表
  173 + tslRespVO.setEvents(convertList(filterList(thingModelList, item ->
  174 + ObjUtil.equal(IotThingModelTypeEnum.EVENT.getType(), item.getType())), IotThingModelDO::getEvent));
  175 + return tslRespVO;
  176 + }
  177 +
152 /** 178 /**
153 * 校验功能是否存在 179 * 校验功能是否存在
154 * 180 *
yudao-server/pom.xml
@@ -109,11 +109,11 @@ @@ -109,11 +109,11 @@
109 <!-- </dependency>--> 109 <!-- </dependency>-->
110 110
111 <!-- IoT 物联网相关模块。默认注释,保证编译速度 --> 111 <!-- IoT 物联网相关模块。默认注释,保证编译速度 -->
112 -<!-- <dependency>-->  
113 -<!-- <groupId>cn.iocoder.boot</groupId>-->  
114 -<!-- <artifactId>yudao-module-iot-biz</artifactId>-->  
115 -<!-- <version>${revision}</version>-->  
116 -<!-- </dependency>--> 112 + <dependency>
  113 + <groupId>cn.iocoder.boot</groupId>
  114 + <artifactId>yudao-module-iot-biz</artifactId>
  115 + <version>${revision}</version>
  116 + </dependency>
117 117
118 <!-- spring boot 配置所需依赖 --> 118 <!-- spring boot 配置所需依赖 -->
119 <dependency> 119 <dependency>
yudao-server/src/main/resources/application-local.yaml
@@ -76,11 +76,12 @@ spring: @@ -76,11 +76,12 @@ spring:
76 validation-query: SELECT SERVER_STATUS() # TDengine 数据源的有效性检查 SQL 76 validation-query: SELECT SERVER_STATUS() # TDengine 数据源的有效性检查 SQL
77 77
78 # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 78 # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
79 - redis:  
80 - host: 127.0.0.1 # 地址  
81 - port: 6379 # 端口  
82 - database: 0 # 数据库索引  
83 -# password: dev # 密码,建议生产环境开启 79 + data:
  80 + redis:
  81 + host: 127.0.0.1 # 地址
  82 + port: 6379 # 端口
  83 + database: 0 # 数据库索引
  84 +# password: dev # 密码,建议生产环境开启
84 85
85 --- #################### 定时任务相关配置 #################### 86 --- #################### 定时任务相关配置 ####################
86 87