【代码优化】IoT: 规则场景 config 抽离

This commit is contained in:
puhui999 2025-03-18 16:51:08 +08:00
parent 6d6547be39
commit f118d66006
13 changed files with 298 additions and 246 deletions

View File

@ -1,9 +1,12 @@
package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene; 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 io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List;
@Schema(description = "管理后台 - IoT 规则场景(场景联动) Response VO") @Schema(description = "管理后台 - IoT 规则场景(场景联动) Response VO")
@Data @Data
@ -22,10 +25,10 @@ public class IotRuleSceneRespVO {
private Integer status; private Integer status;
@Schema(description = "触发器数组", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "触发器数组", requiredMode = Schema.RequiredMode.REQUIRED)
private String triggers; private List<IotRuleSceneTriggerConfig> triggers;
@Schema(description = "执行器数组", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "执行器数组", requiredMode = Schema.RequiredMode.REQUIRED)
private String actions; private List<IotRuleSceneActionConfig> actions;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime; private LocalDateTime createTime;

View File

@ -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.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.validation.InEnum; 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 io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import lombok.Data; import lombok.Data;
import java.util.List;
@Schema(description = "管理后台 - IoT 规则场景(场景联动)新增/修改 Request VO") @Schema(description = "管理后台 - IoT 规则场景(场景联动)新增/修改 Request VO")
@Data @Data
public class IotRuleSceneSaveReqVO { public class IotRuleSceneSaveReqVO {
@ -28,10 +32,10 @@ public class IotRuleSceneSaveReqVO {
@Schema(description = "触发器数组", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "触发器数组", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "触发器数组不能为空") @NotEmpty(message = "触发器数组不能为空")
private String triggers; private List<IotRuleSceneTriggerConfig> triggers;
@Schema(description = "执行器数组", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "执行器数组", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "执行器数组不能为空") @NotEmpty(message = "执行器数组不能为空")
private String actions; private List<IotRuleSceneActionConfig> actions;
} }

View File

@ -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;
}

View File

@ -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<String> 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<String, Object> data;
}

View File

@ -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<IotRuleSceneTriggerConditionParameter> parameters;
}

View File

@ -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;
}

View File

@ -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<String> deviceNames;
/**
* 触发条件数组
*
* 必填 {@link #type} {@link IotRuleSceneTriggerTypeEnum#DEVICE}
* 条件与条件之间的关系
*/
private List<IotRuleSceneTriggerCondition> conditions;
/**
* CRON 表达式
*
* 必填 {@link #type} {@link IotRuleSceneTriggerTypeEnum#TIMER}
*/
private String cronExpression;
}

View File

@ -1,23 +1,19 @@
package cn.iocoder.yudao.module.iot.dal.dataobject.rule; package cn.iocoder.yudao.module.iot.dal.dataobject.rule;
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; 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.controller.admin.rule.vo.scene.config.IotRuleSceneActionConfig;
import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.config.IotRuleSceneTriggerConfig;
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 com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; 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.List;
import java.util.Map;
/** /**
* IoT 规则场景场景联动 DO * IoT 规则场景场景联动 DO
@ -56,188 +52,12 @@ public class IotRuleSceneDO extends TenantBaseDO {
* 触发器数组 * 触发器数组
*/ */
@TableField(typeHandler = JacksonTypeHandler.class) @TableField(typeHandler = JacksonTypeHandler.class)
private List<TriggerConfig> triggers; private List<IotRuleSceneTriggerConfig> triggers;
/** /**
* 执行器数组 * 执行器数组
*/ */
@TableField(typeHandler = JacksonTypeHandler.class) @TableField(typeHandler = JacksonTypeHandler.class)
private List<ActionConfig> actions; private List<IotRuleSceneActionConfig> actions;
/**
* 触发器配置
*/
@Data
public static class TriggerConfig {
/**
* 触发类型
*
* 枚举 {@link IotRuleSceneTriggerTypeEnum}
*/
private Integer type;
/**
* 产品标识
*
* 关联 {@link IotProductDO#getProductKey()}
*/
private String productKey;
/**
* 设备名称数组
*
* 关联 {@link IotDeviceDO#getDeviceName()}
*/
private List<String> deviceNames;
/**
* 触发条件数组
*
* 必填 {@link #type} {@link IotRuleSceneTriggerTypeEnum#DEVICE}
* 条件与条件之间的关系
*/
private List<TriggerCondition> 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<TriggerConditionParameter> 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<String> 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<String, Object> data;
}
} }

View File

@ -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.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.IotRuleScenePageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleSceneSaveReqVO; 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.dataobject.rule.IotRuleSceneDO;
import cn.iocoder.yudao.module.iot.dal.mysql.rule.IotRuleSceneMapper; import cn.iocoder.yudao.module.iot.dal.mysql.rule.IotRuleSceneMapper;
import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum; import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum;
@ -117,82 +118,82 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService {
if (true) { if (true) {
IotRuleSceneDO ruleScene01 = new IotRuleSceneDO(); IotRuleSceneDO ruleScene01 = new IotRuleSceneDO();
ruleScene01.setTriggers(CollUtil.newArrayList()); ruleScene01.setTriggers(CollUtil.newArrayList());
IotRuleSceneDO.TriggerConfig trigger01 = new IotRuleSceneDO.TriggerConfig(); IotRuleSceneTriggerConfig trigger01 = new IotRuleSceneTriggerConfig();
trigger01.setType(IotRuleSceneTriggerTypeEnum.DEVICE.getType()); trigger01.setType(IotRuleSceneTriggerTypeEnum.DEVICE.getType());
trigger01.setConditions(CollUtil.newArrayList()); trigger01.setConditions(CollUtil.newArrayList());
// 属性 // 属性
IotRuleSceneDO.TriggerCondition condition01 = new IotRuleSceneDO.TriggerCondition(); IotRuleSceneTriggerCondition condition01 = new IotRuleSceneTriggerCondition();
condition01.setType(IotDeviceMessageTypeEnum.PROPERTY.getType()); condition01.setType(IotDeviceMessageTypeEnum.PROPERTY.getType());
condition01.setIdentifier(IotDeviceMessageIdentifierEnum.PROPERTY_REPORT.getIdentifier()); condition01.setIdentifier(IotDeviceMessageIdentifierEnum.PROPERTY_REPORT.getIdentifier());
condition01.setParameters(CollUtil.newArrayList()); condition01.setParameters(CollUtil.newArrayList());
// IotRuleSceneDO.TriggerConditionParameter parameter010 = new IotRuleSceneDO.TriggerConditionParameter(); // IotRuleSceneTriggerConditionParameter parameter010 = new IotRuleSceneTriggerConditionParameter();
// parameter010.setIdentifier("width"); // parameter010.setIdentifier("width");
// parameter010.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.getOperator()); // parameter010.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.getOperator());
// parameter010.setValue("abc"); // parameter010.setValue("abc");
// condition01.getParameters().add(parameter010); // condition01.getParameters().add(parameter010);
IotRuleSceneDO.TriggerConditionParameter parameter011 = new IotRuleSceneDO.TriggerConditionParameter(); IotRuleSceneTriggerConditionParameter parameter011 = new IotRuleSceneTriggerConditionParameter();
parameter011.setIdentifier("width"); parameter011.setIdentifier("width");
parameter011.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.getOperator()); parameter011.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.getOperator());
parameter011.setValue("1"); parameter011.setValue("1");
condition01.getParameters().add(parameter011); condition01.getParameters().add(parameter011);
IotRuleSceneDO.TriggerConditionParameter parameter012 = new IotRuleSceneDO.TriggerConditionParameter(); IotRuleSceneTriggerConditionParameter parameter012 = new IotRuleSceneTriggerConditionParameter();
parameter012.setIdentifier("width"); parameter012.setIdentifier("width");
parameter012.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_EQUALS.getOperator()); parameter012.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_EQUALS.getOperator());
parameter012.setValue("2"); parameter012.setValue("2");
condition01.getParameters().add(parameter012); condition01.getParameters().add(parameter012);
IotRuleSceneDO.TriggerConditionParameter parameter013 = new IotRuleSceneDO.TriggerConditionParameter(); IotRuleSceneTriggerConditionParameter parameter013 = new IotRuleSceneTriggerConditionParameter();
parameter013.setIdentifier("width"); parameter013.setIdentifier("width");
parameter013.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.GREATER_THAN.getOperator()); parameter013.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.GREATER_THAN.getOperator());
parameter013.setValue("0"); parameter013.setValue("0");
condition01.getParameters().add(parameter013); condition01.getParameters().add(parameter013);
IotRuleSceneDO.TriggerConditionParameter parameter014 = new IotRuleSceneDO.TriggerConditionParameter(); IotRuleSceneTriggerConditionParameter parameter014 = new IotRuleSceneTriggerConditionParameter();
parameter014.setIdentifier("width"); parameter014.setIdentifier("width");
parameter014.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.GREATER_THAN_OR_EQUALS.getOperator()); parameter014.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.GREATER_THAN_OR_EQUALS.getOperator());
parameter014.setValue("0"); parameter014.setValue("0");
condition01.getParameters().add(parameter014); condition01.getParameters().add(parameter014);
IotRuleSceneDO.TriggerConditionParameter parameter015 = new IotRuleSceneDO.TriggerConditionParameter(); IotRuleSceneTriggerConditionParameter parameter015 = new IotRuleSceneTriggerConditionParameter();
parameter015.setIdentifier("width"); parameter015.setIdentifier("width");
parameter015.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.LESS_THAN.getOperator()); parameter015.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.LESS_THAN.getOperator());
parameter015.setValue("2"); parameter015.setValue("2");
condition01.getParameters().add(parameter015); condition01.getParameters().add(parameter015);
IotRuleSceneDO.TriggerConditionParameter parameter016 = new IotRuleSceneDO.TriggerConditionParameter(); IotRuleSceneTriggerConditionParameter parameter016 = new IotRuleSceneTriggerConditionParameter();
parameter016.setIdentifier("width"); parameter016.setIdentifier("width");
parameter016.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.LESS_THAN_OR_EQUALS.getOperator()); parameter016.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.LESS_THAN_OR_EQUALS.getOperator());
parameter016.setValue("2"); parameter016.setValue("2");
condition01.getParameters().add(parameter016); condition01.getParameters().add(parameter016);
IotRuleSceneDO.TriggerConditionParameter parameter017 = new IotRuleSceneDO.TriggerConditionParameter(); IotRuleSceneTriggerConditionParameter parameter017 = new IotRuleSceneTriggerConditionParameter();
parameter017.setIdentifier("width"); parameter017.setIdentifier("width");
parameter017.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.IN.getOperator()); parameter017.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.IN.getOperator());
parameter017.setValue("1,2,3"); parameter017.setValue("1,2,3");
condition01.getParameters().add(parameter017); condition01.getParameters().add(parameter017);
IotRuleSceneDO.TriggerConditionParameter parameter018 = new IotRuleSceneDO.TriggerConditionParameter(); IotRuleSceneTriggerConditionParameter parameter018 = new IotRuleSceneTriggerConditionParameter();
parameter018.setIdentifier("width"); parameter018.setIdentifier("width");
parameter018.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_IN.getOperator()); parameter018.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_IN.getOperator());
parameter018.setValue("0,2,3"); parameter018.setValue("0,2,3");
condition01.getParameters().add(parameter018); condition01.getParameters().add(parameter018);
IotRuleSceneDO.TriggerConditionParameter parameter019 = new IotRuleSceneDO.TriggerConditionParameter(); IotRuleSceneTriggerConditionParameter parameter019 = new IotRuleSceneTriggerConditionParameter();
parameter019.setIdentifier("width"); parameter019.setIdentifier("width");
parameter019.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.BETWEEN.getOperator()); parameter019.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.BETWEEN.getOperator());
parameter019.setValue("1,3"); parameter019.setValue("1,3");
condition01.getParameters().add(parameter019); condition01.getParameters().add(parameter019);
IotRuleSceneDO.TriggerConditionParameter parameter020 = new IotRuleSceneDO.TriggerConditionParameter(); IotRuleSceneTriggerConditionParameter parameter020 = new IotRuleSceneTriggerConditionParameter();
parameter020.setIdentifier("width"); parameter020.setIdentifier("width");
parameter020.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_BETWEEN.getOperator()); parameter020.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_BETWEEN.getOperator());
parameter020.setValue("2,3"); parameter020.setValue("2,3");
condition01.getParameters().add(parameter020); condition01.getParameters().add(parameter020);
trigger01.getConditions().add(condition01); trigger01.getConditions().add(condition01);
// 状态 // 状态
IotRuleSceneDO.TriggerCondition condition02 = new IotRuleSceneDO.TriggerCondition(); IotRuleSceneTriggerCondition condition02 = new IotRuleSceneTriggerCondition();
condition02.setType(IotDeviceMessageTypeEnum.STATE.getType()); condition02.setType(IotDeviceMessageTypeEnum.STATE.getType());
condition02.setIdentifier(IotDeviceMessageIdentifierEnum.STATE_ONLINE.getIdentifier()); condition02.setIdentifier(IotDeviceMessageIdentifierEnum.STATE_ONLINE.getIdentifier());
condition02.setParameters(CollUtil.newArrayList()); condition02.setParameters(CollUtil.newArrayList());
trigger01.getConditions().add(condition02); trigger01.getConditions().add(condition02);
// 事件 // 事件
IotRuleSceneDO.TriggerCondition condition03 = new IotRuleSceneDO.TriggerCondition(); IotRuleSceneTriggerCondition condition03 = new IotRuleSceneTriggerCondition();
condition03.setType(IotDeviceMessageTypeEnum.EVENT.getType()); condition03.setType(IotDeviceMessageTypeEnum.EVENT.getType());
condition03.setIdentifier("xxx"); condition03.setIdentifier("xxx");
condition03.setParameters(CollUtil.newArrayList()); condition03.setParameters(CollUtil.newArrayList());
IotRuleSceneDO.TriggerConditionParameter parameter030 = new IotRuleSceneDO.TriggerConditionParameter(); IotRuleSceneTriggerConditionParameter parameter030 = new IotRuleSceneTriggerConditionParameter();
parameter030.setIdentifier("width"); parameter030.setIdentifier("width");
parameter030.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.getOperator()); parameter030.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.getOperator());
parameter030.setValue("1"); parameter030.setValue("1");
@ -201,21 +202,21 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService {
// 动作 // 动作
ruleScene01.setActions(CollUtil.newArrayList()); ruleScene01.setActions(CollUtil.newArrayList());
// 设备控制 // 设备控制
IotRuleSceneDO.ActionConfig action01 = new IotRuleSceneDO.ActionConfig(); IotRuleSceneActionConfig action01 = new IotRuleSceneActionConfig();
action01.setType(IotRuleSceneActionTypeEnum.DEVICE_CONTROL.getType()); action01.setType(IotRuleSceneActionTypeEnum.DEVICE_CONTROL.getType());
IotRuleSceneDO.ActionDeviceControl actionDeviceControl01 = new IotRuleSceneDO.ActionDeviceControl(); IotRuleSceneActionDeviceControl iotRuleSceneActionDeviceControl01 = new IotRuleSceneActionDeviceControl();
actionDeviceControl01.setProductKey("4aymZgOTOOCrDKRT"); iotRuleSceneActionDeviceControl01.setProductKey("4aymZgOTOOCrDKRT");
actionDeviceControl01.setDeviceNames(ListUtil.of("small")); iotRuleSceneActionDeviceControl01.setDeviceNames(ListUtil.of("small"));
actionDeviceControl01.setType(IotDeviceMessageTypeEnum.PROPERTY.getType()); iotRuleSceneActionDeviceControl01.setType(IotDeviceMessageTypeEnum.PROPERTY.getType());
actionDeviceControl01.setIdentifier(IotDeviceMessageIdentifierEnum.PROPERTY_SET.getIdentifier()); iotRuleSceneActionDeviceControl01.setIdentifier(IotDeviceMessageIdentifierEnum.PROPERTY_SET.getIdentifier());
actionDeviceControl01.setData(MapUtil.<String, Object>builder() iotRuleSceneActionDeviceControl01.setData(MapUtil.<String, Object>builder()
.put("power", 1) .put("power", 1)
.put("color", "red") .put("color", "red")
.build()); .build());
action01.setDeviceControl(actionDeviceControl01); action01.setDeviceControl(iotRuleSceneActionDeviceControl01);
// ruleScene01.getActions().add(action01); // TODO 芋艿先不测试了 // ruleScene01.getActions().add(action01); // TODO 芋艿先不测试了
// 数据桥接http // 数据桥接http
IotRuleSceneDO.ActionConfig action02 = new IotRuleSceneDO.ActionConfig(); IotRuleSceneActionConfig action02 = new IotRuleSceneActionConfig();
action02.setType(IotRuleSceneActionTypeEnum.DATA_BRIDGE.getType()); action02.setType(IotRuleSceneActionTypeEnum.DATA_BRIDGE.getType());
action02.setDataBridgeId(1L); action02.setDataBridgeId(1L);
ruleScene01.getActions().add(action02); ruleScene01.getActions().add(action02);
@ -225,7 +226,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService {
List<IotRuleSceneDO> list = ruleSceneMapper.selectList(); List<IotRuleSceneDO> list = ruleSceneMapper.selectList();
// TODO @芋艿需要考虑开启状态 // TODO @芋艿需要考虑开启状态
return filterList(list, ruleScene -> { return filterList(list, ruleScene -> {
for (IotRuleSceneDO.TriggerConfig trigger : ruleScene.getTriggers()) { for (IotRuleSceneTriggerConfig trigger : ruleScene.getTriggers()) {
if (ObjUtil.notEqual(trigger.getProductKey(), productKey)) { if (ObjUtil.notEqual(trigger.getProductKey(), productKey)) {
continue; continue;
} }
@ -260,22 +261,22 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService {
IotRuleSceneDO scene = new IotRuleSceneDO().setStatus(CommonStatusEnum.ENABLE.getStatus()); IotRuleSceneDO scene = new IotRuleSceneDO().setStatus(CommonStatusEnum.ENABLE.getStatus());
if (true) { if (true) {
scene.setTenantId(1L); scene.setTenantId(1L);
IotRuleSceneDO.TriggerConfig triggerConfig = new IotRuleSceneDO.TriggerConfig(); IotRuleSceneTriggerConfig iotRuleSceneTriggerConfig = new IotRuleSceneTriggerConfig();
triggerConfig.setType(IotRuleSceneTriggerTypeEnum.TIMER.getType()); iotRuleSceneTriggerConfig.setType(IotRuleSceneTriggerTypeEnum.TIMER.getType());
scene.setTriggers(ListUtil.toList(triggerConfig)); scene.setTriggers(ListUtil.toList(iotRuleSceneTriggerConfig));
// 动作 // 动作
IotRuleSceneDO.ActionConfig action01 = new IotRuleSceneDO.ActionConfig(); IotRuleSceneActionConfig action01 = new IotRuleSceneActionConfig();
action01.setType(IotRuleSceneActionTypeEnum.DEVICE_CONTROL.getType()); action01.setType(IotRuleSceneActionTypeEnum.DEVICE_CONTROL.getType());
IotRuleSceneDO.ActionDeviceControl actionDeviceControl01 = new IotRuleSceneDO.ActionDeviceControl(); IotRuleSceneActionDeviceControl iotRuleSceneActionDeviceControl01 = new IotRuleSceneActionDeviceControl();
actionDeviceControl01.setProductKey("4aymZgOTOOCrDKRT"); iotRuleSceneActionDeviceControl01.setProductKey("4aymZgOTOOCrDKRT");
actionDeviceControl01.setDeviceNames(ListUtil.of("small")); iotRuleSceneActionDeviceControl01.setDeviceNames(ListUtil.of("small"));
actionDeviceControl01.setType(IotDeviceMessageTypeEnum.PROPERTY.getType()); iotRuleSceneActionDeviceControl01.setType(IotDeviceMessageTypeEnum.PROPERTY.getType());
actionDeviceControl01.setIdentifier(IotDeviceMessageIdentifierEnum.PROPERTY_SET.getIdentifier()); iotRuleSceneActionDeviceControl01.setIdentifier(IotDeviceMessageIdentifierEnum.PROPERTY_SET.getIdentifier());
actionDeviceControl01.setData(MapUtil.<String, Object>builder() iotRuleSceneActionDeviceControl01.setData(MapUtil.<String, Object>builder()
.put("power", 1) .put("power", 1)
.put("color", "red") .put("color", "red")
.build()); .build());
action01.setDeviceControl(actionDeviceControl01); action01.setDeviceControl(iotRuleSceneActionDeviceControl01);
scene.setActions(ListUtil.toList(action01)); scene.setActions(ListUtil.toList(action01));
} }
if (scene == null) { if (scene == null) {
@ -287,7 +288,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService {
return; return;
} }
// 1.2 判断是否有定时触发器避免脏数据 // 1.2 判断是否有定时触发器避免脏数据
IotRuleSceneDO.TriggerConfig config = CollUtil.findOne(scene.getTriggers(), IotRuleSceneTriggerConfig config = CollUtil.findOne(scene.getTriggers(),
trigger -> ObjUtil.equals(trigger.getType(), IotRuleSceneTriggerTypeEnum.TIMER.getType())); trigger -> ObjUtil.equals(trigger.getType(), IotRuleSceneTriggerTypeEnum.TIMER.getType()));
if (config == null) { if (config == null) {
log.error("[executeRuleSceneByTimer][规则场景({}) 不存在定时触发器]", scene); log.error("[executeRuleSceneByTimer][规则场景({}) 不存在定时触发器]", scene);
@ -316,7 +317,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService {
// 2. 匹配 trigger 触发器的条件 // 2. 匹配 trigger 触发器的条件
return filterList(ruleScenes, ruleScene -> { return filterList(ruleScenes, ruleScene -> {
for (IotRuleSceneDO.TriggerConfig trigger : ruleScene.getTriggers()) { for (IotRuleSceneTriggerConfig trigger : ruleScene.getTriggers()) {
// 2.1 非设备触发不匹配 // 2.1 非设备触发不匹配
if (ObjUtil.notEqual(trigger.getType(), IotRuleSceneTriggerTypeEnum.DEVICE.getType())) { if (ObjUtil.notEqual(trigger.getType(), IotRuleSceneTriggerTypeEnum.DEVICE.getType())) {
return false; return false;
@ -327,13 +328,13 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService {
return false; return false;
} }
// 2.3 多个条件只需要满足一个即可 // 2.3 多个条件只需要满足一个即可
IotRuleSceneDO.TriggerCondition matchedCondition = CollUtil.findOne(trigger.getConditions(), condition -> { IotRuleSceneTriggerCondition matchedCondition = CollUtil.findOne(trigger.getConditions(), condition -> {
if (ObjUtil.notEqual(message.getType(), condition.getType()) if (ObjUtil.notEqual(message.getType(), condition.getType())
|| ObjUtil.notEqual(message.getIdentifier(), condition.getIdentifier())) { || ObjUtil.notEqual(message.getIdentifier(), condition.getIdentifier())) {
return false; return false;
} }
// 多个条件参数必须全部满足所以下面的逻辑就是找到一个不满足的条件参数 // 多个条件参数必须全部满足所以下面的逻辑就是找到一个不满足的条件参数
IotRuleSceneDO.TriggerConditionParameter notMatchedParameter = CollUtil.findOne(condition.getParameters(), IotRuleSceneTriggerConditionParameter notMatchedParameter = CollUtil.findOne(condition.getParameters(),
parameter -> !isTriggerConditionParameterMatched(message, parameter, ruleScene, trigger)); parameter -> !isTriggerConditionParameterMatched(message, parameter, ruleScene, trigger));
return notMatchedParameter == null; return notMatchedParameter == null;
}); });
@ -348,6 +349,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService {
} }
// TODO @芋艿可优化可以考虑增加下单测边界太多了 // TODO @芋艿可优化可以考虑增加下单测边界太多了
/** /**
* 判断触发器的条件参数是否匹配 * 判断触发器的条件参数是否匹配
* *
@ -358,8 +360,8 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService {
* @return 是否匹配 * @return 是否匹配
*/ */
@SuppressWarnings({"unchecked", "DataFlowIssue"}) @SuppressWarnings({"unchecked", "DataFlowIssue"})
private boolean isTriggerConditionParameterMatched(IotDeviceMessage message, IotRuleSceneDO.TriggerConditionParameter parameter, private boolean isTriggerConditionParameterMatched(IotDeviceMessage message, IotRuleSceneTriggerConditionParameter parameter,
IotRuleSceneDO ruleScene, IotRuleSceneDO.TriggerConfig trigger) { IotRuleSceneDO ruleScene, IotRuleSceneTriggerConfig trigger) {
// 1.1 校验操作符是否合法 // 1.1 校验操作符是否合法
IotRuleSceneTriggerConditionParameterOperatorEnum operator = IotRuleSceneTriggerConditionParameterOperatorEnum operator =
IotRuleSceneTriggerConditionParameterOperatorEnum.operatorOf(parameter.getOperator()); IotRuleSceneTriggerConditionParameterOperatorEnum.operatorOf(parameter.getOperator());
@ -459,7 +461,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService {
schedulerManager.addOrUpdateJob(IotRuleSceneJob.class, schedulerManager.addOrUpdateJob(IotRuleSceneJob.class,
IotRuleSceneJob.buildJobName(id), IotRuleSceneJob.buildJobName(id),
"0/10 * * * * ?", "0/10 * * * * ?",
jobDataMap); jobDataMap);
} }
if (false) { if (false) {
Long id = 1L; Long id = 1L;

View File

@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.iot.service.rule.action; 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.enums.rule.IotRuleSceneActionTypeEnum;
import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage;
@ -14,15 +14,16 @@ import javax.annotation.Nullable;
public interface IotRuleSceneAction { public interface IotRuleSceneAction {
// TODO @芋艿groovy 或者 javascript 实现数据的转换可以考虑基于 hutool ScriptUtil // TODO @芋艿groovy 或者 javascript 实现数据的转换可以考虑基于 hutool ScriptUtil
/** /**
* 执行场景 * 执行场景
* *
* @param message 消息允许空 * @param message 消息允许空
* 1. 空的情况定时触发 * 1. 空的情况定时触发
* 2. 非空的情况设备触发 * 2. 非空的情况设备触发
* @param config 配置 * @param config 配置
*/ */
void execute(@Nullable IotDeviceMessage message, IotRuleSceneDO.ActionConfig config) throws Exception; void execute(@Nullable IotDeviceMessage message, IotRuleSceneActionConfig config) throws Exception;
/** /**
* 获得类型 * 获得类型

View File

@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.iot.service.rule.action; 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.enums.rule.IotRuleSceneActionTypeEnum;
import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -16,7 +16,7 @@ import javax.annotation.Nullable;
public class IotRuleSceneAlertAction implements IotRuleSceneAction { public class IotRuleSceneAlertAction implements IotRuleSceneAction {
@Override @Override
public void execute(@Nullable IotDeviceMessage message, IotRuleSceneDO.ActionConfig config) { public void execute(@Nullable IotDeviceMessage message, IotRuleSceneActionConfig config) {
// TODO @芋艿待实现 // TODO @芋艿待实现
} }

View File

@ -2,8 +2,8 @@ package cn.iocoder.yudao.module.iot.service.rule.action;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 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.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.enums.rule.IotRuleSceneActionTypeEnum;
import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage;
import cn.iocoder.yudao.module.iot.service.rule.IotDataBridgeService; import cn.iocoder.yudao.module.iot.service.rule.IotDataBridgeService;
@ -29,7 +29,7 @@ public class IotRuleSceneDataBridgeAction implements IotRuleSceneAction {
private List<IotDataBridgeExecute<?>> dataBridgeExecutes; private List<IotDataBridgeExecute<?>> dataBridgeExecutes;
@Override @Override
public void execute(IotDeviceMessage message, IotRuleSceneDO.ActionConfig config) throws Exception { public void execute(IotDeviceMessage message, IotRuleSceneActionConfig config) throws Exception {
// 1.1 如果消息为空直接返回 // 1.1 如果消息为空直接返回
if (message == null) { if (message == null) {
return; return;

View File

@ -2,8 +2,9 @@ package cn.iocoder.yudao.module.iot.service.rule.action;
import cn.hutool.core.lang.Assert; 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.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.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.enums.rule.IotRuleSceneActionTypeEnum;
import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage;
import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
@ -27,8 +28,8 @@ public class IotRuleSceneDeviceControlAction implements IotRuleSceneAction {
private IotDeviceService deviceService; private IotDeviceService deviceService;
@Override @Override
public void execute(IotDeviceMessage message, IotRuleSceneDO.ActionConfig config) { public void execute(IotDeviceMessage message, IotRuleSceneActionConfig config) {
IotRuleSceneDO.ActionDeviceControl control = config.getDeviceControl(); IotRuleSceneActionDeviceControl control = config.getDeviceControl();
Assert.notNull(control, "设备控制配置不能为空"); Assert.notNull(control, "设备控制配置不能为空");
// 遍历每个设备下发消息 // 遍历每个设备下发消息
control.getDeviceNames().forEach(deviceName -> { control.getDeviceNames().forEach(deviceName -> {