Skip to content

rec_metering

Promotes normalized 15-minute meter readings from the silver layer into gold tables consumed by all other REC pipelines.

Upstream dependency

Reads from a single silver table produced by a metering ingestion pipeline (not included in this repository). The expected schema is declared in dbt/models/gold/sources.yml.

Schema resolution: the source schema is read from the CELINE_SILVER_SCHEMA env var (default: ds_dev_silver). Set this in .env to match your deployment.

Providing the table: the upstream pipeline must materialise meters_data_normalized into the configured schema before this pipeline runs. This is typically a private pipeline that normalises smart-meter readings from the local metering infrastructure. For local development, create the table manually with DDL matching the columns below and load sample data.

meters_data_normalized must expose the following columns:

Column Type Description
device_id text Device identifier (matches sensor_id in the REC registry)
ts timestamptz 15-minute interval start, aligned to a quarter-hour boundary
consumption_kwh numeric Grid import over the interval (kWh per 15-min bucket)
production_kwh numeric Grid export over the interval (kWh per 15-min bucket)
self_consumed_kwh numeric Behind-the-meter self-use (kWh per bucket), unclipped — negative on a minority of rows upstream

These are energy quantities per bucket, not instantaneous power. There is no kW→kWh conversion anywhere in this pipeline or downstream of it.

dbt models

meters_data_15m

Deduplicates and aggregates normalized 15-min readings per (device_id, ts). Groups by slot to collapse any duplicate readings from the source. Incremental merge on md5(device_id || ts).

Outputs (ds_dev_gold.meters_data_15m):

Column Description
_id md5(device_id \|\| ts)
device_id
ts 15-min slot start
consumption_kwh Summed across source rows for the slot
production_kwh Summed across source rows for the slot
self_consumed_kwh Summed across source rows for the slot

meters_data_1h

Hourly rollup of meters_data_15m via date_trunc('hour', ts). Incremental merge on md5(device_id || date_trunc('hour', ts)).

Outputs (ds_dev_gold.meters_data_1h):

Column Description
_id md5(device_id \|\| ts_hour)
device_id
ts Hour start
consumption_kwh Sum of 15-min readings in the hour
production_kwh Sum of 15-min readings in the hour

meters_data_15m_missing_intervals

Quality model. Generates the complete expected 15-min grid per device over the last 7 days, then left-joins against actuals to surface gaps. Incremental merge on md5(device_id || expected_ts).

Outputs (ds_dev_gold.meters_data_15m_missing_intervals):

Column Description
event_id md5(device_id \|\| ts)
device_id
ts Missing interval timestamp
hour Hour of day (Europe/Rome)
created_at Detection timestamp

Flow (flows/pipeline.py)

rec-metering-flow runs two tasks in sequence: Transform Gold Layer (dbt run --select gold) followed by Run dbt Tests. Serves with cron */10 * * * * (every 10 minutes) in dev mode.