我正在尝试使用规则配置对象设计规则系统,其中规则本身可以在外部配置。具体来说,我想在DRL规则定义的外部配置特定类型规则的规则启动之间的最短时间。
到目前为止,我的方法是将规则配置作为事实ValueRuleSpec插入:
rule "Any value detected"
when
$r : ValueRuleSpec(mode == ValueRuleSpecMode.ANY(), $devices: devices)
$e : SensorEvent(deviceId memberOf $devices) from entry-point FMSensorEvents
not Activation(ruleSpec == $r, cause == $e)
then
insert(new Activation($r, $e));
end
$ r ValueRuleSpec对象具有属性 triggerEvery ,其中包含激活之间的最小秒数。我知道这可以通过在$ e之前使用以下内容测试是否缺少特定范围内的Activation对象来静态完成:
not Activation(this before[60s, 0s] $e)
如何使用$ r.triggerEvery属性作为秒数,在可配置的时间窗口中执行此操作?
答案 0 :(得分:0)
根据laune的建议回答我自己的问题。
before关键字的行为为described in the manual:
$eventA : EventA( this before[ 3m30s, 4m ] $eventB )
当且仅当时间距离时,先前的模式将匹配 在$ eventA完成的时间和$ eventB的时间之间 开始时间在(3分钟到30秒)和(4分钟)之间。在 换句话说:
3m30s <= $eventB.startTimestamp - $eventA.endTimeStamp <= 4m
查看source code for the before evaluator我们可以看到相同的内容。
@Override
protected boolean evaluate(long rightTS, long leftTS) {
long dist = leftTS - rightTS;
return this.getOperator().isNegated() ^ (dist >= this.initRange && dist <= this.finalRange);
}
基于此,我相应地修改了我的代码,现在它似乎正常工作:
rule "Any value detected"
when
$r : ValueRuleSpec(mode == ValueRuleSpecMode.ANY(), $devices: devices)
$e : SensorEvent(deviceId memberOf $devices) from entry-point FMSensorEvents
not Activation(ruleSpec == $r, cause == $e)
// no activation within past triggerEvery seconds for same device
not Activation(
ruleSpec == $r,
deviceId == $e.deviceId,
start.time > ($e.start.time - ($r.triggerEvery * 1000))
)
then
insert(new Activation($r, $e));
end