Logistics
A refrigerated truck carries vaccines, which must stay between 2 and 8 °C; its temperature and door sensors report every minute. Regulations limit the total time above 8 °C over the trip to 45 minutes, across all excursions, and an excursion soon after the door was open is probably caused by it.
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.time.Duration;
import java.util.Map;
Channel door = Channel.named("door");
Channel temp = Channel.named("temp");
Rule excursion = Rule.named("Excursion")
.when(temp.above(8)).forDuration(Duration.ofMinutes(15))
.endWhen(temp.above(8).not());
Rule doorOpen = Rule.named("DoorOpen").when(door.above(0.5));
Rule excursionAfterDoor = Rule.named("ExcursionAfterDoor")
.when(after(doorOpen).within(Duration.ofMinutes(30)).and(temp.above(8)));
Rule cumulativeLimit = Rule.named("CumulativeLimit")
.when(totalDuration(excursion).above(Duration.ofMinutes(45).toMillis()));
Detector detector = Detector.builder()
.rules(excursion, doorOpen, excursionAfterDoor, cumulativeLimit)
.build();
for (int m = 0; m < 480; m++) { // every minute
double celsius = m >= 62 && m < 90 ? 10 : m >= 300 && m < 330 ? 9 : 5;
detector.push(m * 60_000L, Map.of(temp, celsius, door, m >= 60 && m < 65 ? 1.0 : 0.0));
}
detector.close();
The Rules
- Excursion: above 8 °C for 15 minutes, over as soon as it is back at 8 °C or below.
- DoorOpen: the door sensor reads 1.
- ExcursionAfterDoor: above 8 °C within 30 minutes after the door closed, to attribute the cause.
- CumulativeLimit: the total time of the Excursions above 45 minutes.
At the defaults, the door is open from minute 60 to 65, and the temperature is above 8 °C from minute 62 to 90 and from 300 to 330. The first Excursion runs from 62 to 90, Confirmed at 77. ExcursionAfterDoor starts at 65, the moment the door closed, and runs to 90; the second Excursion, from 300, is too long after the door. The first Excursion adds 28 minutes; the second, Confirmed at 315, brings the total to 46 at 318, where CumulativeLimit starts. It holds until the data ends, so its end is Truncated.
Things to try
- Raise Total time limit to 60 minutes: the two Excursions add up to 58 minutes above 8 °C, and there is no
CumulativeLimit.
Reference
The example is ColdChainExample, a test with its expected Events, listed in the README's Examples.
Methods used: Channel.named, Rule.named, Rule.when, Expression.above, Rule.forDuration, Rule.endWhen, Condition.not, Conditions.after, After.within, Condition.and, Conditions.totalDuration, Detector.builder, Detector.Builder.rules, Detector.Builder.build, Detector.push, Detector.close.
The concepts at work, each on a page of its own: After another Event, Time spent in Events, End Conditions and hysteresis.