# Operation and production

> Derive production volumes from meter readings, total them by period, read the operating regime and the well's current status, and collect operation warnings with @welldot/utils.

The operational blocks record how a well is used: meters (`meters`), their readings and estimated volumes (`production`), the declared pumping regime (`operating_regime`) and the well's status changes in `history_logs`. Volumes and the current state are derived from these records, following the spec's normative rules.

## Production volumes

A meter (hidrômetro) is a totalizer: the file stores its register readings, and volumes are the differences between consecutive readings ([production](/format/spec/v2/object-schemas#production-since-v23)). `@welldot/utils` implements the [volume derivation](/format/spec/v2/object-schemas#volume-derivation-normative):

- readings of each meter are ordered by instant, then `sequence`;
- each pair of consecutive readings gives `r₂ − r₁`;
- a decrease means the register rolled over at `max_reading`, or, without `max_reading`, an unknown volume, never a negative one;
- an interval never spans two meters, so the gap between a meter's removal and the next one's installation is unmetered;
- an `estimated_volume` entry counts only for the part of its period that no meter interval covers ([precedence](/format/spec/v2/object-schemas#precedence)).

```ts
import { getProductionByPeriod, getProductionTotal } from '@welldot/utils';

getProductionTotal(well);
// { metered: 1238406, estimated: 0, total: 1238406, unknown_intervals: 0 }

getProductionByPeriod(well, 'year').at(-1);
// { period: '2026', metered: 52067.3, estimated: 0, total: 52067.3, unknown_intervals: 0 }
```

`getProductionByPeriod(well, 'day' | 'month' | 'year')` buckets by local date (`YYYY-MM-DD`, `YYYY-MM`, `YYYY`) and prorates each interval by time across period boundaries, so the buckets add up to the total. Volumes are in m³.

Lower-level helpers:

| Function                          | Returns                                                                                  |
| --------------------------------- | ---------------------------------------------------------------------------------------- |
| `getMeterIntervals(well)`         | Each interval between consecutive readings of a meter, with `volume: null` when unknown. |
| `getCurrentMeters(well)`          | Meters without `removed_at`, newest first.                                               |
| `getEffectiveProduction(well)`    | Production entries not retracted by `corrects`.                                          |
| `getRetractedProductionIds(well)` | The retracted ids.                                                                       |

## Operating regime

`operating_regime` entries declare a flow rate, daily hours and days per week, each in force from `effective_from` ([operating regime](/format/spec/v2/object-schemas#operating_regime-since-v23)).

```ts
import { getCurrentRegime, normalizeDailyOperatingTime } from '@welldot/utils';

getCurrentRegime(well); // the entry in force now
getCurrentRegime(well, new Date('2015-06-01T00:00:00-03:00')); // the entry in force then (a Date)

normalizeDailyOperatingTime(26); // 24: values above 24 h count as 24 in derivations
```

The stored value is never rewritten; the spec makes values above 24 a warning and normalizes them only for calculation.

## Well status

The status is a closed vocabulary (`active`, `maintenance`, `inactive`, `decommissioned`, `abandoned`) written by `status_change` entries in `history_logs` ([status change](/format/spec/v2/object-schemas#status_change)). Without one, the status is unknown.

```ts
import {
  getCurrentWellStatus,
  getCurrentWellStatusEntry,
} from '@welldot/utils';

getCurrentWellStatus(well); // 'active', or undefined when no status_change exists
getCurrentWellStatusEntry(well)?.datetime; // when it changed
```

Label it with `WELL_STATUSES` from `@welldot/core`.

## Pumps

`pump_installations` is an installation block: each entry is one installation, from `installed_at` to `removed_at` ([pump installations](/format/spec/v2/object-schemas#pump_installations-since-v23)).

| Function                                 | Returns                                                                                                             |
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `getCurrentPump(well)`                   | The installation without `removed_at` (the latest if several).                                                      |
| `getPumpInstalledAt(well, instant)`      | The installation in place at an instant.                                                                            |
| `getPumpServiceTime(well, serial, now?)` | Total minutes in service of the installations that share a serial number.                                           |
| `calculateSubmergence(well)`             | Intake depth below the latest dynamic level.                                                                        |
| `getPumpInstallationWarnings(well)`      | Intake below the bottom of the well or inside a screen, several open installations, removal not after installation. |

## Warnings

```ts
import { getOperationWarnings } from '@welldot/utils';

getOperationWarnings(well); // [{ code, ids }, …]
```

Covers meters, production, operating regime, structured history entries and analyses that cite retracted events, plus the 2.4 checks for logger series (an analysis citing a `logger_series`, readings deeper than the sensor). Each is a warning in the spec, never a reason to reject the file ([meter validation](/format/spec/v2/object-schemas#validation-warnings-never-rejection-2), [production validation](/format/spec/v2/object-schemas#validation-warnings-never-rejection-3)).
