# Time spent in Events

`totalDuration(a)` is the summed duration in milliseconds of all Events of Rule `a`: the Ended ones in full, plus a running one up to now. It grows continuously while an Event of `a` runs, so a limit is detected the moment it is crossed:

```java
Rule excursion = Rule.named("Excursion").when(temp.above(8));
Rule cumulativeLimit = Rule.named("CumulativeLimit")
    .when(totalDuration(excursion).above(Duration.ofMinutes(45).toMillis()));
```

## A cumulative limit

A cold chain logs its temperature once a minute. It is above 8 °C from minute 20 to 40, from 80 to 95 and from 150 to 175: 20, 15 and 25 minutes, an hour in all. A single excursion is tolerable, but not more than the limit in total.

Parameters (in the page address as ?limit=…):

- Limit (`limit`): 0 to 70 min in steps of 5, default 45

The site cannot run the default parameters: (JavaScript) TypeError: Cannot read properties of undefined (reading 'length')

Java source at the default parameters:

```java
import static io.github.romanhaendler.rbed.Conditions.*;

import io.github.romanhaendler.rbed.*;
import java.time.Duration;
import java.util.Map;

Channel temp = Channel.named("temp");

Rule excursion = Rule.named("Excursion").when(temp.above(8));
Rule cumulativeLimit = Rule.named("CumulativeLimit")
    .when(totalDuration(excursion).above(Duration.ofMinutes(45).toMillis()));
Detector detector = Detector.builder()
    .rules(excursion, cumulativeLimit)
    .build();

for (int m = 0; m <= 240; m++) {   // one Sample a minute
  boolean warm = m >= 20 && m < 40 || m >= 80 && m < 95 || m >= 150 && m < 175;
  detector.push(m * 60_000L, Map.of(temp, warm ? 10.0 : 5.0));
}
detector.close();
```

`totalDuration(excursion)` rises while an `Excursion` runs and stays level between them: 20 minutes after the first, 35 after the second. At the default limit of 45 minutes, the sum reaches 45 at minute 160, in the middle of the third excursion, and exceeds it at minute 161, where `CumulativeLimit` starts. It never Ends, since the sum never decreases: it runs to the end of the data, and `close()` gives it a Truncated end.

### Things to try

- Raise the limit to 60 minutes: the sum reaches it at minute 175 but never exceeds it, so there is no `CumulativeLimit`.
- Lower it to 30 minutes: the sum exceeds it during the second excursion, and `CumulativeLimit` starts at minute 91.

## Reference

- [totalDuration: time spent in Events](https://github.com/romanhaendler/rbed#totalduration-time-spent-in-events) in the README, the canonical text
- [Conditions](https://romanhaendler.github.io/rbed/api/io.github.romanhaendler.rbed/io/github/romanhaendler/rbed/Conditions.html) in the Javadoc

Methods used: [`Channel.named`](https://romanhaendler.github.io/rbed/api/io.github.romanhaendler.rbed/io/github/romanhaendler/rbed/Channel.html#named%28java.lang.String%29), [`Rule.named`](https://romanhaendler.github.io/rbed/api/io.github.romanhaendler.rbed/io/github/romanhaendler/rbed/Rule.html#named%28java.lang.String%29), [`Rule.when`](https://romanhaendler.github.io/rbed/api/io.github.romanhaendler.rbed/io/github/romanhaendler/rbed/Rule.html#when%28io.github.romanhaendler.rbed.Condition%29), [`Expression.above`](https://romanhaendler.github.io/rbed/api/io.github.romanhaendler.rbed/io/github/romanhaendler/rbed/Expression.html#above%28double%29), [`Conditions.totalDuration`](https://romanhaendler.github.io/rbed/api/io.github.romanhaendler.rbed/io/github/romanhaendler/rbed/Conditions.html#totalDuration%28io.github.romanhaendler.rbed.Rule%29), [`Detector.builder`](https://romanhaendler.github.io/rbed/api/io.github.romanhaendler.rbed/io/github/romanhaendler/rbed/Detector.html#builder%28%29), [`Detector.Builder.rules`](https://romanhaendler.github.io/rbed/api/io.github.romanhaendler.rbed/io/github/romanhaendler/rbed/Detector.Builder.html#rules%28io.github.romanhaendler.rbed.Rule...%29), [`Detector.Builder.build`](https://romanhaendler.github.io/rbed/api/io.github.romanhaendler.rbed/io/github/romanhaendler/rbed/Detector.Builder.html#build%28%29), [`Detector.push`](https://romanhaendler.github.io/rbed/api/io.github.romanhaendler.rbed/io/github/romanhaendler/rbed/Detector.html#push%28long,java.util.Map%29), [`Detector.close`](https://romanhaendler.github.io/rbed/api/io.github.romanhaendler.rbed/io/github/romanhaendler/rbed/Detector.html#close%28%29).
