|
|
@@ -20,6 +20,8 @@ import com.usky.rule.vo.Condition;
|
|
|
import com.usky.rule.vo.Expression;
|
|
|
import com.usky.rule.vo.RuleEngineDetail;
|
|
|
import com.usky.rule.vo.action.RuleEngineAction;
|
|
|
+import com.usky.rule.util.CronUtil;
|
|
|
+import com.usky.rule.vo.constraint.CronConstraint;
|
|
|
import com.usky.rule.vo.constraint.DeviceConstraint;
|
|
|
import com.usky.rule.vo.log.BaseLog;
|
|
|
import com.usky.rule.vo.log.DeviceTriggerLog;
|
|
|
@@ -40,7 +42,7 @@ import java.time.LocalDateTime;
|
|
|
import java.util.*;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
-import com.usky.rule.vo.log.BaseLog;
|
|
|
+import com.usky.rule.vo.log.CronTriggerLog;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
@@ -102,12 +104,16 @@ public class TriggerDeviceUtil {
|
|
|
if (triggerAction) {
|
|
|
log.info("triggerAction is true");
|
|
|
this.setTriggerLog(now, ruleEngineDetailLog, deviceId, null, TriggerValueTypeEnum.ACQ.getValue(), TriggerTypeEnum.DEVICE, meetTriggerConditionList, valueMap);
|
|
|
+ List<CronConstraint> cronConstraints = this.ruleEngineService.getCronConstraints(ruleEngineDetail.getConstraints());
|
|
|
List<DeviceConstraint> deviceConstraints = this.ruleEngineService.getDeviceConstraints(ruleEngineDetail.getConstraints());
|
|
|
- boolean constraintAction = this.meetConstraintAction(deviceConstraints, ruleEngineDetailLog);
|
|
|
- if (constraintAction) {
|
|
|
- log.info("constraintAction is true");
|
|
|
+ boolean cronOk = this.meetCronConstraintAction(cronConstraints, ruleEngineDetailLog, currDataTime);
|
|
|
+ boolean deviceOk = this.meetConstraintAction(deviceConstraints, ruleEngineDetailLog);
|
|
|
+ if (cronOk && deviceOk) {
|
|
|
+ log.info("ruleEngineId={} constraints satisfied, executing actions", ruleEngineId);
|
|
|
this.ruleEngineUtil.performMultipleDevicesControl(ruleEngineId, true, TriggerTypeEnum.DEVICE.getType(), ruleEngine.getProjectId(), ruleEngine.getSpaceId(), actions, ruleEngineDetailLog);
|
|
|
this.clearMeetConditionCache(ruleEngineId, deviceId, meetMinuteExpressionMap);
|
|
|
+ } else if (!cronOk) {
|
|
|
+ log.debug("ruleEngineId={} skipped: cron constraint not satisfied at {}", ruleEngineId, currDataTime);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -287,6 +293,41 @@ public class TriggerDeviceUtil {
|
|
|
};
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 时间类约束(cron):在设备上报触发路径下与触发条件 AND。
|
|
|
+ * 使用消息时间戳 {@code effectiveTime}(缺省为当前时间)做 {@link CronExpression#isSatisfiedBy(Date)} 判断。
|
|
|
+ */
|
|
|
+ public boolean meetCronConstraintAction(List<CronConstraint> cronConstraints, RuleEngineDetailLog ruleEngineDetailLog, LocalDateTime effectiveTime) {
|
|
|
+ if (cronConstraints == null || cronConstraints.isEmpty()) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ LocalDateTime t = effectiveTime != null ? effectiveTime : LocalDateTime.now();
|
|
|
+ Date at = DateTimeUtil.localDateTimeToDate(t);
|
|
|
+ for (CronConstraint cc : cronConstraints) {
|
|
|
+ if (cc == null || StringUtils.isBlank(cc.getCron())) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!CronUtil.isCronSatisfiedBy(cc.getCron().trim(), at)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ List<BaseLog> baseLogs = ruleEngineDetailLog.getConstraints();
|
|
|
+ if (baseLogs == null) {
|
|
|
+ baseLogs = new ArrayList();
|
|
|
+ ruleEngineDetailLog.setConstraints(baseLogs);
|
|
|
+ }
|
|
|
+ for (CronConstraint cc : cronConstraints) {
|
|
|
+ CronTriggerLog cronConstraintLog = new CronTriggerLog();
|
|
|
+ cronConstraintLog.setCronExp(cc.getCron());
|
|
|
+ cronConstraintLog.setTime(DateTimeUtil.format(t));
|
|
|
+ BaseLog cronBaseLog = new BaseLog();
|
|
|
+ cronBaseLog.setDetail(cronConstraintLog);
|
|
|
+ cronBaseLog.setType(ConstraintTypeEnum.CRON.getType());
|
|
|
+ baseLogs.add(cronBaseLog);
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
public boolean meetConstraintAction(List<DeviceConstraint> deviceConstraints, RuleEngineDetailLog ruleEngineDetailLog) {
|
|
|
List<DeviceTriggerLog> deviceTriggerLogs = new ArrayList();
|
|
|
boolean constraintAction = true;
|
|
|
@@ -358,14 +399,17 @@ public class TriggerDeviceUtil {
|
|
|
}
|
|
|
|
|
|
if (constraintAction && !deviceTriggerLogs.isEmpty()) {
|
|
|
- List<BaseLog> baseLogs = new ArrayList();
|
|
|
+ List<BaseLog> existing = ruleEngineDetailLog.getConstraints();
|
|
|
+ final List<BaseLog> baseLogs = existing != null ? existing : new ArrayList();
|
|
|
+ if (existing == null) {
|
|
|
+ ruleEngineDetailLog.setConstraints(baseLogs);
|
|
|
+ }
|
|
|
deviceTriggerLogs.forEach((deviceConstraintLog) -> {
|
|
|
BaseLog baseLog = new BaseLog();
|
|
|
baseLog.setType(ConstraintTypeEnum.DEVICE.getType());
|
|
|
baseLog.setDetail(deviceConstraintLog);
|
|
|
baseLogs.add(baseLog);
|
|
|
});
|
|
|
- ruleEngineDetailLog.setConstraints(baseLogs);
|
|
|
}
|
|
|
|
|
|
return constraintAction;
|