reactor:【IoT 物联网】增加 IotRuleScene2DO 新的定义,对标阿里云 IoT 的「事件响应」

This commit is contained in:
YunaiV
2025-06-23 08:52:57 +08:00
parent a17d4bb281
commit 1ad4e08cb8
12 changed files with 399 additions and 45 deletions

View File

@@ -9,6 +9,7 @@ import java.util.Arrays;
/**
* IoT 设备消息类型枚举
*/
@Deprecated
@Getter
@RequiredArgsConstructor
public enum IotDeviceMessageTypeEnum implements ArrayValuable<String> {

View File

@@ -15,8 +15,33 @@ import java.util.Arrays;
@Getter
public enum IotRuleSceneActionTypeEnum implements ArrayValuable<Integer> {
DEVICE_CONTROL(1), // 设备执行
// TODO @芋艿:后续“对应”部分,要 @下,等包结构梳理完;
/**
* 设备属性设置
*
* 对应 IotDeviceMessageMethodEnum.DEVICE_PROPERTY_SET
*/
DEVICE_PROPERTY_SET(1),
/**
* 设备服务调用
*
* 对应 IotDeviceMessageMethodEnum.DEVICE_SERVICE_INVOKE
*/
DEVICE_SERVICE_INVOKE(2),
/**
* 告警触发
*/
ALERT_TRIGGER(100),
/**
* 告警恢复
*/
ALERT_RECOVER(101),
@Deprecated
ALERT(2), // 告警执行
@Deprecated
DATA_BRIDGE(3); // 桥接执行
private final Integer type;

View File

@@ -8,13 +8,13 @@ import lombok.RequiredArgsConstructor;
import java.util.Arrays;
/**
* IoT 场景触发条件参数的操作符枚举
* IoT 场景触发条件的操作符枚举
*
* @author 芋道源码
*/
@RequiredArgsConstructor
@Getter
public enum IotRuleSceneTriggerConditionParameterOperatorEnum implements ArrayValuable<String> {
public enum IotRuleSceneConditionOperatorEnum implements ArrayValuable<String> {
EQUALS("=", "#source == #value"),
NOT_EQUALS("!=", "!(#source == #value)"),
@@ -32,12 +32,28 @@ public enum IotRuleSceneTriggerConditionParameterOperatorEnum implements ArrayVa
NOT_BETWEEN("not between", "(#source < #values.get(0)) || (#source > #values.get(1))"),
LIKE("like", "#source.contains(#value)"), // 字符串匹配
NOT_NULL("not null", "#source != null && #source.length() > 0"); // 非空
NOT_NULL("not null", "#source != null && #source.length() > 0"), // 非空
// ========== 特殊不放在字典里 ==========
// TODO @puhui999@芋艿需要测试下
DATE_TIME_GREATER_THAN("date_time_>", "#source > #value"), // 在时间之后时间戳
DATE_TIME_LESS_THAN("date_time_<", "#source < #value"), // 在时间之前时间戳
DATE_TIME_BETWEEN("date_time_between", // 在时间之间时间戳
"(#source >= #values.get(0)) && (#source <= #values.get(1))"),
// TODO @puhui999@芋艿需要测试下
TIME_GREATER_THAN("time_>", "#source.isAfter(#value)"), // 在当日时间之后HH:mm:ss
TIME_LESS_THAN("time_<", "#source.isBefore(#value)"), // 在当日时间之前HH:mm:ss
TIME_BETWEEN("time_between", // 在当日时间之间HH:mm:ss
"(#source >= #values.get(0)) && (#source <= #values.get(1))"),
;
private final String operator;
private final String springExpression;
public static final String[] ARRAYS = Arrays.stream(values()).map(IotRuleSceneTriggerConditionParameterOperatorEnum::getOperator).toArray(String[]::new);
public static final String[] ARRAYS = Arrays.stream(values()).map(IotRuleSceneConditionOperatorEnum::getOperator).toArray(String[]::new);
/**
* Spring 表达式 - 原始值
@@ -52,7 +68,7 @@ public enum IotRuleSceneTriggerConditionParameterOperatorEnum implements ArrayVa
*/
public static final String SPRING_EXPRESSION_VALUE_LIST = "values";
public static IotRuleSceneTriggerConditionParameterOperatorEnum operatorOf(String operator) {
public static IotRuleSceneConditionOperatorEnum operatorOf(String operator) {
return ArrayUtil.firstMatch(item -> item.getOperator().equals(operator), values());
}

View File

@@ -0,0 +1,35 @@
package cn.iocoder.yudao.module.iot.enums.rule;
import cn.iocoder.yudao.framework.common.core.ArrayValuable;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import java.util.Arrays;
/**
* IoT 条件类型枚举
*
* @author 芋道源码
*/
@RequiredArgsConstructor
@Getter
public enum IotRuleSceneConditionTypeEnum implements ArrayValuable<Integer> {
DEVICE_STATE(1, "设备状态"),
DEVICE_PROPERTY(2, "设备属性"),
CURRENT_TIME(100, "当前时间"),
;
private final Integer type;
private final String name;
public static final Integer[] ARRAYS = Arrays.stream(values()).map(IotRuleSceneConditionTypeEnum::getType).toArray(Integer[]::new);
@Override
public Integer[] array() {
return ARRAYS;
}
}

View File

@@ -9,14 +9,47 @@ import java.util.Arrays;
/**
* IoT 场景流转的触发类型枚举
*
* 为什么不直接使用 IotDeviceMessageMethodEnum 呢?
* 原因是,物模型属性上报,存在批量上报的情况,不只对应一个 method
*
* @author 芋道源码
*/
@RequiredArgsConstructor
@Getter
public enum IotRuleSceneTriggerTypeEnum implements ArrayValuable<Integer> {
DEVICE(1), // 设备触发
TIMER(2); // 定时触发
@Deprecated
DEVICE(1), // 设备触发 // TODO @puhui999@芋艿:这个可以作废
// TODO @芋艿:后续“对应”部分,要 @下,等包结构梳理完;
/**
* 设备上下线变更
*
* 对应 IotDeviceMessageMethodEnum.STATE_UPDATE
*/
DEVICE_STATE_UPDATE(1),
/**
* 物模型属性上报
*
* 对应 IotDeviceMessageMethodEnum.DEVICE_PROPERTY_POST
*/
DEVICE_PROPERTY_POST(2),
/**
* 设备事件上报
*
* 对应 IotDeviceMessageMethodEnum.DEVICE_EVENT_POST
*/
DEVICE_EVENT_POST(3),
/**
* 设备服务调用
*
* 对应 IotDeviceMessageMethodEnum.DEVICE_SERVICE_INVOKE
*/
DEVICE_SERVICE_INVOKE(4),
TIMER(100) // 定时触发
;
private final Integer type;

View File

@@ -23,7 +23,7 @@ import java.util.List;
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class IotAlertConfig extends BaseDO {
public class IotAlertConfigDO extends BaseDO {
/**
* 配置编号

View File

@@ -34,13 +34,13 @@ public class IotAlertRecordDO extends BaseDO {
/**
* 告警名称
*
* 冗余 {@link IotAlertConfig#getName()}
* 冗余 {@link IotAlertConfigDO#getName()}
*/
private Long configId;
/**
* 告警名称
*
* 冗余 {@link IotAlertConfig#getName()}
* 冗余 {@link IotAlertConfigDO#getName()}
*/
private String name;

View File

@@ -0,0 +1,241 @@
package cn.iocoder.yudao.module.iot.dal.dataobject.rule;
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO;
import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum;
import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneConditionOperatorEnum;
import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneConditionTypeEnum;
import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneTriggerTypeEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
// TODO @puhui999还是在 IotRuleSceneDO 里搞,这里主要可以看到变化字段哈。
/**
* IoT 场景联动 DO
*
* @author 芋道源码
*/
@TableName(value = "iot_rule_scene2", autoResultMap = true)
@KeySequence("iot_rule_scene_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class IotRuleScene2DO extends TenantBaseDO {
/**
* 设备编号 - 全部设备
*/
public static final Long DEVICE_ID_ALL = 0L;
/**
* 场景编号
*/
@TableId
private Long id;
/**
* 场景名称
*/
private String name;
/**
* 场景描述
*/
private String description;
/**
* 场景状态
*
* 枚举 {@link cn.iocoder.yudao.framework.common.enums.CommonStatusEnum}
*/
private Integer status;
/**
* 场景定义配置
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<Trigger> triggers;
/**
* 场景动作配置
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<Action> actions;
/**
* 场景定义配置
*/
@Data
public static class Trigger {
// ========== 事件部分 ==========
/**
* 场景事件类型
*
* 枚举 {@link IotRuleSceneTriggerTypeEnum}
* 1. {@link IotRuleSceneTriggerTypeEnum#DEVICE_STATE_UPDATE} 时operator 非空,并且 value 为在线状态
* 2. {@link IotRuleSceneTriggerTypeEnum#DEVICE_PROPERTY_POST}
* {@link IotRuleSceneTriggerTypeEnum#DEVICE_EVENT_POST} 时identifier、operator 非空,并且 value 为属性值
* 3. {@link IotRuleSceneTriggerTypeEnum#DEVICE_EVENT_POST}
* {@link IotRuleSceneTriggerTypeEnum#DEVICE_SERVICE_INVOKE} 时identifier 非空,但是 operator、value 为空
* 4. {@link IotRuleSceneTriggerTypeEnum#TIMER} 时conditions 非空,并且设备无关(无需 productId、deviceId 字段)
*/
private Integer type;
/**
* 产品编号
*
* 关联 {@link IotProductDO#getId()}
*/
private Long productId;
/**
* 设备编号
*
* 关联 {@link IotDeviceDO#getId()}
* 特殊:如果为 0则是全部
*/
private Long deviceId;
/**
* 物模型标识符
*
* 对应:{@link IotThingModelDO#getIdentifier()}
*/
private String identifier;
/**
* 操作符
*
* 枚举 {@link IotRuleSceneConditionOperatorEnum}
*/
private String operator;
/**
* 参数(属性值、在线状态)
*
* 如果有多个值,则使用 "," 分隔,类似 "1,2,3"。
* 例如说,{@link IotRuleSceneConditionOperatorEnum#IN}、{@link IotRuleSceneConditionOperatorEnum#BETWEEN}
*/
private String value;
/**
* CRON 表达式
*/
private String cronExpression;
// ========== 条件部分 ==========
/**
* 触发条件分组(状态条件分组)的数组
*
* 第一层 List分组与分组之间是“或”的关系
* 第二层 List条件与条件之间是“且”的关系
*/
private List<List<TriggerCondition>> conditionGroups;
}
/**
* 触发条件(状态条件)
*/
@Data
public static class TriggerCondition {
/**
* 触发条件类型
*
* 枚举 {@link IotRuleSceneConditionTypeEnum}
* 1. {@link IotRuleSceneConditionTypeEnum#DEVICE_STATE} 时operator 非空,并且 value 为在线状态
* 2. {@link IotRuleSceneConditionTypeEnum#DEVICE_PROPERTY} 时identifier、operator 非空,并且 value 为属性值
* 3. {@link IotRuleSceneConditionTypeEnum#CURRENT_TIME} 时operator 非空(使用 DATE_TIME_ 和 TIME_ 部分),并且 value 非空
*/
private Integer type;
/**
* 产品编号
*
* 关联 {@link IotProductDO#getId()}
*/
private Long productId;
/**
* 设备编号
*
* 关联 {@link IotDeviceDO#getId()}
*/
private Long deviceId;
/**
* 标识符(属性)
*
* 关联 {@link IotThingModelDO#getIdentifier()}
*/
private String identifier;
/**
* 操作符
*
* 枚举 {@link IotRuleSceneConditionOperatorEnum}
*/
private String operator;
/**
* 参数
*
* 如果有多个值,则使用 "," 分隔,类似 "1,2,3"。
* 例如说,{@link IotRuleSceneConditionOperatorEnum#IN}、{@link IotRuleSceneConditionOperatorEnum#BETWEEN}
*/
private String param;
}
/**
* 场景动作配置
*/
@Data
public static class Action {
/**
* 执行类型
*
* 枚举 {@link IotRuleSceneActionTypeEnum}
* 1. {@link IotRuleSceneActionTypeEnum#DEVICE_PROPERTY_SET} 时params 非空
* {@link IotRuleSceneActionTypeEnum#DEVICE_SERVICE_INVOKE} 时params 非空
* 2. {@link IotRuleSceneActionTypeEnum#ALERT_TRIGGER} 时alertConfigId 为空,因为是 {@link IotAlertConfigDO} 里面关联它
* 3. {@link IotRuleSceneActionTypeEnum#ALERT_RECOVER} 时alertConfigId 非空
*/
private Integer type;
/**
* 产品编号
*
* 关联 {@link IotProductDO#getId()}
*/
private Long productId;
/**
* 设备编号
*
* 关联 {@link IotDeviceDO#getId()}
*/
private Long deviceId;
/**
* 请求参数
*
* 一般来说,对应 {@link IotDeviceMessage#getParams()} 请求参数
*/
private Object params;
/**
* 告警配置编号
*
* 关联 {@link IotAlertConfigDO#getId()}
*/
private Long alertConfigId;
}
}

View File

@@ -7,7 +7,7 @@ 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.IotRuleSceneConditionOperatorEnum;
import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneTriggerTypeEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
@@ -163,7 +163,7 @@ public class IotRuleSceneDO extends TenantBaseDO {
/**
* 操作符
*
* 枚举 {@link IotRuleSceneTriggerConditionParameterOperatorEnum}
* 枚举 {@link IotRuleSceneConditionOperatorEnum}
*/
private String operator;
@@ -171,7 +171,7 @@ public class IotRuleSceneDO extends TenantBaseDO {
* 比较值
*
* 如果有多个值,则使用 "," 分隔,类似 "1,2,3"。
* 例如说,{@link IotRuleSceneTriggerConditionParameterOperatorEnum#IN}、{@link IotRuleSceneTriggerConditionParameterOperatorEnum#BETWEEN}
* 例如说,{@link IotRuleSceneConditionOperatorEnum#IN}、{@link IotRuleSceneConditionOperatorEnum#BETWEEN}
*/
private String value;
@@ -193,7 +193,7 @@ public class IotRuleSceneDO extends TenantBaseDO {
/**
* 设备控制
*
* 必填:当 {@link #type} 为 {@link IotRuleSceneActionTypeEnum#DEVICE_CONTROL} 时
* 必填:当 {@link #type} 为 {@link IotRuleSceneActionTypeEnum#DEVICE_PROPERTY_SET} 时
*/
private ActionDeviceControl deviceControl;

View File

@@ -23,7 +23,7 @@ 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.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.IotRuleSceneConditionOperatorEnum;
import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneTriggerTypeEnum;
import cn.iocoder.yudao.module.iot.framework.job.core.IotSchedulerManager;
import cn.iocoder.yudao.module.iot.job.rule.IotRuleSceneJob;
@@ -127,57 +127,57 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService {
condition01.setParameters(CollUtil.newArrayList());
// IotRuleSceneDO.TriggerConditionParameter parameter010 = new IotRuleSceneDO.TriggerConditionParameter();
// parameter010.setIdentifier("width");
// parameter010.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.getOperator());
// parameter010.setOperator(IotRuleSceneConditionOperatorEnum.EQUALS.getOperator());
// parameter010.setValue("abc");
// condition01.getParameters().add(parameter010);
IotRuleSceneDO.TriggerConditionParameter parameter011 = new IotRuleSceneDO.TriggerConditionParameter();
parameter011.setIdentifier("width");
parameter011.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.getOperator());
parameter011.setOperator(IotRuleSceneConditionOperatorEnum.EQUALS.getOperator());
parameter011.setValue("1");
condition01.getParameters().add(parameter011);
IotRuleSceneDO.TriggerConditionParameter parameter012 = new IotRuleSceneDO.TriggerConditionParameter();
parameter012.setIdentifier("width");
parameter012.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_EQUALS.getOperator());
parameter012.setOperator(IotRuleSceneConditionOperatorEnum.NOT_EQUALS.getOperator());
parameter012.setValue("2");
condition01.getParameters().add(parameter012);
IotRuleSceneDO.TriggerConditionParameter parameter013 = new IotRuleSceneDO.TriggerConditionParameter();
parameter013.setIdentifier("width");
parameter013.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.GREATER_THAN.getOperator());
parameter013.setOperator(IotRuleSceneConditionOperatorEnum.GREATER_THAN.getOperator());
parameter013.setValue("0");
condition01.getParameters().add(parameter013);
IotRuleSceneDO.TriggerConditionParameter parameter014 = new IotRuleSceneDO.TriggerConditionParameter();
parameter014.setIdentifier("width");
parameter014.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.GREATER_THAN_OR_EQUALS.getOperator());
parameter014.setOperator(IotRuleSceneConditionOperatorEnum.GREATER_THAN_OR_EQUALS.getOperator());
parameter014.setValue("0");
condition01.getParameters().add(parameter014);
IotRuleSceneDO.TriggerConditionParameter parameter015 = new IotRuleSceneDO.TriggerConditionParameter();
parameter015.setIdentifier("width");
parameter015.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.LESS_THAN.getOperator());
parameter015.setOperator(IotRuleSceneConditionOperatorEnum.LESS_THAN.getOperator());
parameter015.setValue("2");
condition01.getParameters().add(parameter015);
IotRuleSceneDO.TriggerConditionParameter parameter016 = new IotRuleSceneDO.TriggerConditionParameter();
parameter016.setIdentifier("width");
parameter016.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.LESS_THAN_OR_EQUALS.getOperator());
parameter016.setOperator(IotRuleSceneConditionOperatorEnum.LESS_THAN_OR_EQUALS.getOperator());
parameter016.setValue("2");
condition01.getParameters().add(parameter016);
IotRuleSceneDO.TriggerConditionParameter parameter017 = new IotRuleSceneDO.TriggerConditionParameter();
parameter017.setIdentifier("width");
parameter017.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.IN.getOperator());
parameter017.setOperator(IotRuleSceneConditionOperatorEnum.IN.getOperator());
parameter017.setValue("1,2,3");
condition01.getParameters().add(parameter017);
IotRuleSceneDO.TriggerConditionParameter parameter018 = new IotRuleSceneDO.TriggerConditionParameter();
parameter018.setIdentifier("width");
parameter018.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_IN.getOperator());
parameter018.setOperator(IotRuleSceneConditionOperatorEnum.NOT_IN.getOperator());
parameter018.setValue("0,2,3");
condition01.getParameters().add(parameter018);
IotRuleSceneDO.TriggerConditionParameter parameter019 = new IotRuleSceneDO.TriggerConditionParameter();
parameter019.setIdentifier("width");
parameter019.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.BETWEEN.getOperator());
parameter019.setOperator(IotRuleSceneConditionOperatorEnum.BETWEEN.getOperator());
parameter019.setValue("1,3");
condition01.getParameters().add(parameter019);
IotRuleSceneDO.TriggerConditionParameter parameter020 = new IotRuleSceneDO.TriggerConditionParameter();
parameter020.setIdentifier("width");
parameter020.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_BETWEEN.getOperator());
parameter020.setOperator(IotRuleSceneConditionOperatorEnum.NOT_BETWEEN.getOperator());
parameter020.setValue("2,3");
condition01.getParameters().add(parameter020);
trigger01.getConditions().add(condition01);
@@ -194,7 +194,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService {
condition03.setParameters(CollUtil.newArrayList());
IotRuleSceneDO.TriggerConditionParameter parameter030 = new IotRuleSceneDO.TriggerConditionParameter();
parameter030.setIdentifier("width");
parameter030.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.getOperator());
parameter030.setOperator(IotRuleSceneConditionOperatorEnum.EQUALS.getOperator());
parameter030.setValue("1");
trigger01.getConditions().add(condition03);
ruleScene01.getTriggers().add(trigger01);
@@ -202,7 +202,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService {
ruleScene01.setActions(CollUtil.newArrayList());
// 设备控制
IotRuleSceneDO.ActionConfig action01 = new IotRuleSceneDO.ActionConfig();
action01.setType(IotRuleSceneActionTypeEnum.DEVICE_CONTROL.getType());
action01.setType(IotRuleSceneActionTypeEnum.DEVICE_PROPERTY_SET.getType());
IotRuleSceneDO.ActionDeviceControl actionDeviceControl01 = new IotRuleSceneDO.ActionDeviceControl();
actionDeviceControl01.setProductKey("4aymZgOTOOCrDKRT");
actionDeviceControl01.setDeviceNames(ListUtil.of("small"));
@@ -266,7 +266,7 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService {
scene.setTriggers(ListUtil.toList(triggerConfig));
// 动作
IotRuleSceneDO.ActionConfig action01 = new IotRuleSceneDO.ActionConfig();
action01.setType(IotRuleSceneActionTypeEnum.DEVICE_CONTROL.getType());
action01.setType(IotRuleSceneActionTypeEnum.DEVICE_PROPERTY_SET.getType());
IotRuleSceneDO.ActionDeviceControl iotRuleSceneActionDeviceControl01 = new IotRuleSceneDO.ActionDeviceControl();
iotRuleSceneActionDeviceControl01.setProductKey("4aymZgOTOOCrDKRT");
iotRuleSceneActionDeviceControl01.setDeviceNames(ListUtil.of("small"));
@@ -366,8 +366,8 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService {
private boolean isTriggerConditionParameterMatched(IotDeviceMessage message, IotRuleSceneDO.TriggerConditionParameter parameter,
IotRuleSceneDO ruleScene, IotRuleSceneDO.TriggerConfig trigger) {
// 1.1 校验操作符是否合法
IotRuleSceneTriggerConditionParameterOperatorEnum operator =
IotRuleSceneTriggerConditionParameterOperatorEnum.operatorOf(parameter.getOperator());
IotRuleSceneConditionOperatorEnum operator =
IotRuleSceneConditionOperatorEnum.operatorOf(parameter.getOperator());
if (operator == null) {
log.error("[isTriggerConditionParameterMatched][规则场景编号({}) 的触发器({}) 存在错误的操作符({})]",
ruleScene.getId(), trigger, parameter.getOperator());
@@ -382,24 +382,24 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService {
// 2.1 构建 Spring 表达式的变量
Map<String, Object> springExpressionVariables = new HashMap<>();
try {
springExpressionVariables.put(IotRuleSceneTriggerConditionParameterOperatorEnum.SPRING_EXPRESSION_SOURCE, messageValue);
springExpressionVariables.put(IotRuleSceneTriggerConditionParameterOperatorEnum.SPRING_EXPRESSION_VALUE, parameter.getValue());
springExpressionVariables.put(IotRuleSceneConditionOperatorEnum.SPRING_EXPRESSION_SOURCE, messageValue);
springExpressionVariables.put(IotRuleSceneConditionOperatorEnum.SPRING_EXPRESSION_VALUE, parameter.getValue());
List<String> parameterValues = StrUtil.splitTrim(parameter.getValue(), CharPool.COMMA);
springExpressionVariables.put(IotRuleSceneTriggerConditionParameterOperatorEnum.SPRING_EXPRESSION_VALUE_LIST, parameterValues);
springExpressionVariables.put(IotRuleSceneConditionOperatorEnum.SPRING_EXPRESSION_VALUE_LIST, parameterValues);
// 特殊:解决数字的比较。因为 Spring 是基于它的 compareTo 方法,对数字的比较存在问题!
if (ObjectUtils.equalsAny(operator, IotRuleSceneTriggerConditionParameterOperatorEnum.BETWEEN,
IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_BETWEEN,
IotRuleSceneTriggerConditionParameterOperatorEnum.GREATER_THAN,
IotRuleSceneTriggerConditionParameterOperatorEnum.GREATER_THAN_OR_EQUALS,
IotRuleSceneTriggerConditionParameterOperatorEnum.LESS_THAN,
IotRuleSceneTriggerConditionParameterOperatorEnum.LESS_THAN_OR_EQUALS)
if (ObjectUtils.equalsAny(operator, IotRuleSceneConditionOperatorEnum.BETWEEN,
IotRuleSceneConditionOperatorEnum.NOT_BETWEEN,
IotRuleSceneConditionOperatorEnum.GREATER_THAN,
IotRuleSceneConditionOperatorEnum.GREATER_THAN_OR_EQUALS,
IotRuleSceneConditionOperatorEnum.LESS_THAN,
IotRuleSceneConditionOperatorEnum.LESS_THAN_OR_EQUALS)
&& NumberUtil.isNumber(messageValue)
&& NumberUtils.isAllNumber(parameterValues)) {
springExpressionVariables.put(IotRuleSceneTriggerConditionParameterOperatorEnum.SPRING_EXPRESSION_SOURCE,
springExpressionVariables.put(IotRuleSceneConditionOperatorEnum.SPRING_EXPRESSION_SOURCE,
NumberUtil.parseDouble(messageValue));
springExpressionVariables.put(IotRuleSceneTriggerConditionParameterOperatorEnum.SPRING_EXPRESSION_VALUE,
springExpressionVariables.put(IotRuleSceneConditionOperatorEnum.SPRING_EXPRESSION_VALUE,
NumberUtil.parseDouble(parameter.getValue()));
springExpressionVariables.put(IotRuleSceneTriggerConditionParameterOperatorEnum.SPRING_EXPRESSION_VALUE_LIST,
springExpressionVariables.put(IotRuleSceneConditionOperatorEnum.SPRING_EXPRESSION_VALUE_LIST,
convertList(parameterValues, NumberUtil::parseDouble));
}
// 2.2 计算 Spring 表达式

View File

@@ -49,7 +49,7 @@ public class IotRuleSceneDeviceControlAction implements IotRuleSceneAction {
@Override
public IotRuleSceneActionTypeEnum getType() {
return IotRuleSceneActionTypeEnum.DEVICE_CONTROL;
return IotRuleSceneActionTypeEnum.DEVICE_PROPERTY_SET;
}
}

View File

@@ -19,9 +19,12 @@ public enum IotDeviceMessageMethodEnum implements ArrayValuable<String> {
// ========== 设备状态 ==========
// TODO @芋艿要合并下thing.state.update
STATE_ONLINE("thing.state.online", "设备上线", true),
STATE_OFFLINE("thing.state.offline", "设备下线", true),
STATE_UPDATE("thing.state.update", "设备状态更新", true),
// ========== 设备属性 ==========
// 可参考https://help.aliyun.com/zh/iot/user-guide/device-properties-events-and-services