Guides

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). @welldot/utils implements the volume derivation:

  • 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).
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:

FunctionReturns
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).

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). Without one, the status is unknown.

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).

FunctionReturns
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

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, production validation).