> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mangrovesystems.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Common Data Rules for Reactors, Meters and Batch Calculations

> Frequently used data rule examples, with the condition and settings for each, ready to adapt to your project.

Most Mangrove projects start with the same handful of data rules, whatever the site produces: a limit that only applies while equipment is running, a value that cannot be negative, a sensor that has flatlined, a value that dropped out. This page collects the six teams set up first, each with its condition, its settings on the **Then** step, and the adjustment that stops it raising false alerts on data that is fine. Start from the one closest to your equipment, replace the data point names (the slugs inside `{{ }}`) and the thresholds with your own, and click **Validate** before you save to see what the rule would have flagged over the last 90 days.

Data rules are introduced in [Data Rules Fundamentals](/data-rules/fundamentals). The operators and windows these conditions use are in [Rule Expressions](/data-rules/rule-expressions), and the rule builder itself in [Create a Data Rule](/data-rules/create-a-rule).

| Rule                                                                                                                                              | Catches                                                                                             | Action             |
| ------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | ------------------ |
| [Reactor temperature below its floor while running](#reactor-temperature-below-its-floor-while-the-reactor-is-running)                            | A process temperature that dropped during production, without false alerts on warm-up and cool-down | Alert              |
| [A value outside what the measurement can physically be](#a-value-outside-what-the-measurement-can-physically-be)                                 | A negative mass or volume, or a percentage above 100                                                | Alert              |
| [A gas flow meter stuck on one value](#a-gas-flow-meter-stuck-on-one-value)                                                                       | A meter or sensor that keeps reporting the same number after it stopped measuring                   | Alert              |
| [Zero a gas product meter while the plant inlet flow is below threshold](#zero-a-gas-product-meter-while-the-plant-inlet-flow-is-below-threshold) | A product meter reporting flow while the inlet shows the plant is not running                       | Substitute         |
| [Fill a dropped analyzer value from its own history](#fill-a-dropped-analyzer-value-from-its-own-history)                                         | A gas analyzer that intermittently records an empty value, or zero                                  | Substitute         |
| [A batch calculation result outside its physical bounds](#a-batch-calculation-result-outside-its-physical-bounds)                                 | A batch output that went negative, or a residual that no longer adds up                             | Alert on the batch |

A rule reads data points captured together on one event, the same row on the Events table, so the two data points a condition names have to arrive together. **Substitute** appears as an action only when substitutions are enabled on your account, and each substitute recipe also works as an alert.

## Reactor temperature below its floor while the reactor is running

A pyrolysis reactor spends part of every cycle heating up and cooling down, so a rule that tests the temperature alone raises a false alert on every start and stop. Adding the reactor's status to the condition limits the rule to the time production is actually running.

```
{{data-point.reactor_status}} = 'running' AND {{data-point.reactor_temperature}} < 500
```

| Setting                    | Value                                                   |
| -------------------------- | ------------------------------------------------------- |
| Runs on                    | Data Points                                             |
| Action                     | Alert                                                   |
| When this rule fires, flag | **Specific data points**, with the temperature selected |

Replace `500` with the floor your process runs at, in the unit the temperature is captured in, and write the status value exactly as it appears in your data: the comparison is exact, so `'Running'` does not match `'running'`. A controller that reports status as a number takes `= 1` in place of `= 'running'`.

Flag the temperature only. With **Automatic** the status is flagged as well, and whoever [triages the alert](/data-rules/manage-alerts) is sent to a value that did nothing wrong. The same shape suits any limit that only matters under load: a flare temperature, a kiln pressure, an engine's exhaust temperature.

## A value outside what the measurement can physically be

A meter counter that rolled over, a unit conversion applied twice, or a spreadsheet cell left blank all arrive as a value the measurement can never take. A biochar mass at or below zero is the plain case.

```
{{data-point.biochar_mass}} <= 0
```

| Setting                    | Value         |
| -------------------------- | ------------- |
| Runs on                    | Data Points   |
| Action                     | Alert         |
| When this rule fires, flag | **Automatic** |

Match the bound to the measurement. A flow meter reads zero overnight while the equipment is idle, so a rule on a meter tests `< 0` and leaves zero alone. A percentage, such as feedstock moisture or methane content, takes `not between 0 and 100`, and a lab result takes `not between` with the range your lab can actually report.

## A gas flow meter stuck on one value

A flow meter or sensor that has frozen keeps reporting on schedule, so nothing about any single value looks wrong. The rule tests that the lowest and highest values over the last hour are the same, with a count beside it saying how many identical values it takes to call the meter stuck.

```
MIN({{data-point.rng_flow}} WITHIN TRAILING 1.hour) = MAX({{data-point.rng_flow}} WITHIN TRAILING 1.hour)
  AND COUNT({{data-point.rng_flow}} WITHIN TRAILING 1.hour) >= 3
  AND {{data-point.rng_flow}} != 0
```

| Setting            | Value                                                        |
| ------------------ | ------------------------------------------------------------ |
| Runs on            | Data Points                                                  |
| Action             | Alert                                                        |
| Flag the whole run | On. The switch appears once the condition contains a window. |

Size the window and the count against the meter's interval. A meter reporting every 15 minutes puts four values in an hour, so `COUNT >= 3` is met as soon as the hour is flat. A meter reporting once a minute wants a shorter window or a higher count, so a few quiet minutes do not trip it. The last clause leaves out a flatline of zeros, which is what idle equipment produces; drop it on a stream that never legitimately reads zero.

[Catching a stuck sensor](/data-rules/rule-expressions#catching-a-stuck-sensor) explains the condition and what **Flag the whole run** does, and [Repair a stuck sensor](/api-reference/cookbooks/substitute-values#repair-a-stuck-sensor) writes the same rule as a substitution over the API.

## Zero a gas product meter while the plant inlet flow is below threshold

On a biogas or renewable natural gas (RNG) upgrading plant, the product meter can report a small flow while the inlet meter shows the plant is not running. The rule reads the inlet as the gate and the product meter as the value to correct.

```
{{data-point.inlet_flow}} < 25 AND {{data-point.rng_product_flow}} != 0
```

| Setting                          | Value                   |
| -------------------------------- | ----------------------- |
| Runs on                          | Data Points             |
| Action                           | Substitute              |
| When this rule fires, substitute | The product flow        |
| Substitution methods             | **Constant**, value `0` |
| Hold for approval                | On                      |

Replace `25` with the inlet flow below which the plant is not producing, in the unit the meter is captured in. Keep **Hold for approval** on while you confirm the threshold: each match becomes a proposal to check against the plant log before anything is written, and you can switch it off once the rule has been right a few times. See [Approve corrections](/data-rules/approve-corrections).

The `!= 0` clause stops the rule matching the zero it wrote, and leaves a product meter that already reads zero alone. To flag instead of correct, keep the condition and pick **Alert**.

## Fill a dropped analyzer value from its own history

A gas analyzer that loses its connection records an empty value, or zero, for a stretch of data points while the rest of the event is fine. The rule replaces each one with the last value the analyzer measured, and with the day's average when there is no earlier value to carry forward.

```
{{data-point.methane_content}} IS MISSING OR {{data-point.methane_content}} = 0
```

| Setting                          | Value                                                         |
| -------------------------------- | ------------------------------------------------------------- |
| Runs on                          | Data Points                                                   |
| Action                           | Substitute                                                    |
| When this rule fires, substitute | The methane content                                           |
| Substitution methods             | **Forward fill**, then **Trailing average** over the last day |
| Hold for approval                | On                                                            |

Keep **Hold for approval** on until the replacements have matched the analyzer's own log a few times. Forward fill takes the most recent earlier value that passes this rule, so a run of dropouts fills from the last real measurement, and when neither method finds a value the data point is left as it is and an alert is raised.

The fill methods only draw on values carrying the same tracking ID as the one being corrected, so a rule that alerts where you expected a correction is the cue to check the tracking IDs on the events it reads. See [Create a Data Rule](/data-rules/create-a-rule#if-the-action-is-substitute).

## A batch calculation result outside its physical bounds

A model output can go wrong while every input passes its own checks. A net removal figure at or below zero, or a volume worked out by subtracting the other sources from a total that comes out negative, means an input is overstated somewhere upstream.

```
{{node.net_removals}} <= 0
```

| Setting | Value                                      |
| ------- | ------------------------------------------ |
| Runs on | Batch Calculation, with the model selected |
| Action  | Alert                                      |

Pick the model on the When step, then type `{{` in the condition to choose the output, the model's node, from the list. A volume worked out by subtraction takes the same rule with `< 0`.

The alert lands on the batch, so pair this rule with a Data Points rule on the inputs that can overstate, such as the [physical-bounds check](#a-value-outside-what-the-measurement-can-physically-be) above, and an alert on the data point then points at the cause.
