The latest Event
latest(a) gives access to the most recent Confirmed Event of Rule a, whether still running or Ended:
.min(x),.max(x),.mean(x): its Aggregates of Channelx, so far if it is running. Ruleaaggregatesxfor this automatically..duration(): its duration in milliseconds, up to now if it is running.
Each is an Expression, undefined while there has been no Event of a. This relates the present to an earlier Event.
A partial set-down
A crane lifts a load of 800 kg from 10 s to 40 s and sets it down to 300 kg in between, from 25 s to 30 s. Then it lifts 600 kg from 60 s to 90 s and sets it down to 350 kg from 75 s to 80 s. LoadLifted has an End Condition, so a set-down does not End it. PartialSetDown holds while the weight is below a fraction of the latest lift's maximum.
The live chart and its controls need JavaScript. The tables show the Events at the default parameters.
The site cannot run the default parameters: (JavaScript) TypeError: Cannot read properties of undefined (reading 'length')
import static io.github.romanhaendler.rbed.Conditions.*;
import io.github.romanhaendler.rbed.*;
import java.util.Map;
Channel weight = Channel.named("weight");
Rule loadLifted = Rule.named("LoadLifted").when(weight.above(500)).endWhen(weight.below(50));
Rule partialSetDown = Rule.named("PartialSetDown")
.when(during(loadLifted).and(weight.below(latest(loadLifted).max(weight).times(0.5))));
Detector detector = Detector.builder()
.rules(loadLifted, partialSetDown)
.build();
for (int s = 0; s <= 110; s++) { // one Sample a second
double kg = s >= 25 && s < 30 ? 300
: s >= 10 && s < 40 ? 800
: s >= 75 && s < 80 ? 350
: s >= 60 && s < 90 ? 600
: 0;
detector.push(s * 1_000L, Map.of(weight, kg));
}
detector.close();
At the default fraction of 0.5:
- Before 10 s there has been no lift, and
latest(loadLifted).max(weight)is undefined. - During the first lift
latestreads that lift, whose maximum is 800 kg. The set-down to 300 kg is below 400 kg, andPartialSetDownruns from 25 s to 30 s. - Between the lifts
lateststill reads the first one, which has Ended, butduring(loadLifted)does not hold. - From 60 s
latestreads the second lift. Its maximum is 600 kg, so its set-down to 350 kg is not below 300 kg, although it would be below half of the first lift's 800 kg.
Things to try
- Raise the fraction to 0.6: the second set-down counts too. 350 kg is below 360 kg, and
PartialSetDownruns from 75 s to 80 s. - Lower it to 0.3: neither set-down is below 240 kg or 180 kg, and there is no
PartialSetDown.
A cycle taking too long
.duration() of a running Event grows with time, so a Rule can detect a long Event while it is still running:
Rule cycle = Rule.named("Cycle").when(spindle.above(0.5));
Rule slowCycle = Rule.named("SlowCycle")
.when(during(cycle).and(latest(cycle).duration().above(Duration.ofMinutes(2).toMillis())));
The Cranes example uses PartialSetDown with lifting, overload and classifying a load.
Reference
- latest: values of the most recent Event and Aggregates in the README, the canonical text
- LatestEvent in the Javadoc
Methods used: Channel.named, Rule.named, Rule.when, Expression.above, Rule.endWhen, Expression.below (double, Expression), Conditions.during, Condition.and, Conditions.latest, LatestEvent.max, Expression.times, Detector.builder, Detector.Builder.rules, Detector.Builder.build, Detector.push, Detector.close, LatestEvent.duration.