Skip to main content
Jira progress: loading…

ENGY-FUEL

Fuel Consolidation

1. Identity

Loading identity…

Depends on module:

Purpose
Consolidates fuel consumption from procurement, fleet, and stationary combustion systems into canonical fuel-energy series suitable for ESRS-aligned energy reporting and downstream aggregation.

This engine exists because fuels often arrive as:

  • liters/tonnes/m³ from procurement,
  • mixed units and calorific assumptions,
  • split across mobile vs stationary uses,
  • with data quality variability requiring strict normalization + metadata.

Typical usage

  • Total fuels energy consumption (MWh)
  • Fuels by fuel-type (MWh)
  • Stationary vs mobile fuels splits (MWh)
  • Input to MEID_CALC_ENERGY_AGGR (as the authoritative fuels stream)

2. Contract References (ZAR)

2.1 Input Schema

ZAR Address: schema.compute.energy.fuels.inputs.v1_0_0

Required conceptual fields (v1 minimal):

  • records: list of fuel records
  • alignment: BY_YEAR | BY_INDEX (default BY_YEAR)

Each fuel record conceptually includes:

  • period (typically year)
  • fuel_type: canonical fuel identifier (e.g., diesel, gasoline, natural_gas, fuel_oil, coal, lpg)
  • value
  • unit (e.g., L, m3, kg, tonne, GJ, MWh)
  • optional:
    • use_context: STATIONARY | MOBILE | UNKNOWN
    • source_type: PROCUREMENT | FLEET | METER | ESTIMATE
    • invoice_id / purchase_id / tank_id
    • site_id / fleet_id
    • lcv_hv_flag: LCV | HHV (if relevant)
    • calorific_value_override (MJ/unit)
    • density_override (kg/L) (for volume→mass conversions)

Optional structured fields (preferred when available):

  • fuels_total: scalar or time-series (already energy-normalized)
  • fuels_by_type: map fuel_type → series (already energy-normalized)

If structured fields are provided, records may be omitted.


2.2 Options Schema

ZAR Address: schema.compute.energy.fuels.options.v1_0_0

Common options:

  • unit_output: default MWh
  • fuel_normalization: STRICT | LENIENT (default STRICT)
  • unknown_fuel_policy: ERROR | DROP | FLAG (default ERROR)
  • conversion_policy: DEFAULT_FACTORS | REQUIRE_FACTORS (default DEFAULT_FACTORS)
  • default_factor_ref: reference to default conversion factors dataset (NCV/LHV)
  • duplicate_policy: ALLOW | DEDUPE_BY_ID | ERROR (default DEDUPE_BY_ID)
  • negative_values_policy: ERROR | ALLOW_WITH_FLAG
  • missing_policy: ERROR | SKIP
  • rounding: optional digits

2.3 Output Schema

ZAR Address: schema.compute.energy.fuels.output.v1_0_0

Outputs include:

  • Efuels(t)E_{\mathrm{fuels}}(t): total fuels energy
  • Efuels,by_type(f,t)E_{\mathrm{fuels,by\_type}}(f,t): fuels by type
  • Efuels,stationary(t)E_{\mathrm{fuels,stationary}}(t)
  • Efuels,mobile(t)E_{\mathrm{fuels,mobile}}(t)
  • metadata (factor sources, overrides used, unknown fuel handling, dedupe actions)

3. Accepted Input Shapes

A. Procurement records (volumetric units)

{
"records": [
{ "source_type": "PROCUREMENT", "purchase_id": "P-001", "period": 2025, "fuel_type": "diesel", "value": 50000, "unit": "L", "use_context": "MOBILE" },
{ "source_type": "PROCUREMENT", "purchase_id": "P-002", "period": 2025, "fuel_type": "natural_gas", "value": 20000, "unit": "m3", "use_context": "STATIONARY" }
],
"alignment": "BY_YEAR"
}

B. Direct energy units (already in GJ / MWh)

{
"records": [
{ "source_type": "METER", "period": 2025, "fuel_type": "natural_gas", "value": 30000, "unit": "GJ", "use_context": "STATIONARY" }
]
}

C. Structured series (already consolidated upstream)

{
"fuels_by_type": {
"diesel": [[2025, 5200], [2026, 5100]],
"natural_gas": [[2025, 8000], [2026, 7600]]
},
"unit_output": "MWh",
"alignment": "BY_YEAR"
}

All supported shapes MUST be normalized internally to:

Map<period, Map<fuel_type, energy_MWh>> + optional Map<period, context_splits>

4. Fuel Normalization Rules (Normative)

4.1. Canonical fuel identifiers (v1)

At minimum, v1 MUST recognize:

  • diesel
  • gasoline
  • natural_gas
  • fuel_oil
  • coal
  • lpg
  • jet_fuel (optional but common)

If fuel_normalization = STRICT:

  • unknown fuels MUST error (default)

If LENIENT:

  • unknown fuels may be dropped or flagged per unknown_fuel_policy

4.2. Conversion factors governance

If conversion_policy = DEFAULT_FACTORS:

  • use conversion factors from default_factor_ref (dataset) unless overridden per record

If REQUIRE_FACTORS:

  • each record MUST provide an override factor (calorific/density) or computation fails

Metadata MUST record:

  • factor dataset reference/version used
  • overrides used (count + which fuel types)

5. Unit Conversion Semantics (Normative)

5.1. Convert to energy in MJ

For a fuel record rr with value V(r)V(r) in a physical unit:

  • If unit is already energy (e.g., GJ, MWh): convert directly.
  • If unit is mass or volume: convert using:
  • density (if volume→mass needed)
  • calorific value (MJ per unit)

Generic conversion:

EMJ(r)=V(r)CV(r)E_{\mathrm{MJ}}(r) = V(r) \cdot CV(r)

Where CV(r)CV(r) is the calorific value in MJ per input unit.

If volume requires density:

  • convert volume to mass first:

m(r)=V(r)ρ(r)m(r) = V(r) \cdot \rho(r)

Then: EMJ(r)=m(r)CVMJ/kg(r)E_{\mathrm{MJ}}(r) = m(r) \cdot CV_{\mathrm{MJ/kg}}(r)

5.2. Convert MJ to output unit (MWh)

Using 1 MWh=3600 MJ1\ \mathrm{MWh} = 3600\ \mathrm{MJ}:

EMWh(r)=EMJ(r)3600E_{\mathrm{MWh}}(r) = \frac{E_{\mathrm{MJ}}(r)}{3600}


6. Aggregation Semantics (Normative)

Let FF be the set of fuel types and tt periods.

6.1. Fuels by type

For each fuel type ff and period tt:

Efuels,bytype(f,t)=r:fuel(r)=fperiod(r)=tEMWh(r)E_{\mathrm{fuels,by_type}}(f,t) = \sum_{r: fuel(r)=f \land period(r)=t} E_{\mathrm{MWh}}(r)

6.2. Fuels total

Efuels(t)=fFEfuels,bytype(f,t)E_{\mathrm{fuels}}(t) = \sum_{f \in F} E_{\mathrm{fuels,by_type}}(f,t)

6.3. Stationary vs mobile splits (if use_context provided)

Let UstationaryU_{\mathrm{stationary}} be records where use_context=STATIONARY, and similarly for mobile.

Efuels,stationary(t)=rUstationary(t)EMWh(r)E_{\mathrm{fuels,stationary}}(t) = \sum_{r \in U_{\mathrm{stationary}}(t)} E_{\mathrm{MWh}}(r)

Efuels,mobile(t)=rUmobile(t)EMWh(r)E_{\mathrm{fuels,mobile}}(t) = \sum_{r \in U_{\mathrm{mobile}}(t)} E_{\mathrm{MWh}}(r)

If context is missing:

  • record under UNKNOWN bucket and flag in metadata (v1)

7. Validation & Error Model

Invariants

  • Values must be finite
  • Units must be convertible
  • Conversion factors must be resolvable under policy
  • Duplicate records handled per duplicate_policy
  • Negative values default to error

Error codes (suggested)

  • ENERGY_FUEL_MISSING_INPUT
  • ENERGY_FUEL_INVALID_FUEL_TYPE
  • ENERGY_FUEL_FACTOR_NOT_FOUND
  • ENERGY_FUEL_UNIT_CONVERSION_FAILED
  • ENERGY_FUEL_DUPLICATE_RECORD_ERROR
  • ENERGY_FUEL_NON_FINITE_VALUE
  • ENERGY_FUEL_ALIGNMENT_MISMATCH

Errors MUST include:

  • engine cmi_short_code
  • record identifier and period
  • fuel_type and unit context

8. Dependencies

MEID_CALC_ENERGY_FUEL depends on:

  • schema resolver (ZAR)
  • unit conversion utilities
  • fuel conversion factors dataset (default_factor_ref)
  • optional density/calorific reference tables

Declared via ZAR dependencies.


9. Federation & Audit Requirements

To reproduce fuel consolidation externally, the export MUST include:

  • engine identity (cmi or zar_code)
  • engine build proof (execution_ref + build_hash)
  • input/options/output schemas used
  • raw fuel records or structured series used
  • conversion factor dataset reference/version
  • any density/calorific overrides applied
  • conversion_policy, unknown_fuel_policy, duplicate_policy

Provenance chain MUST show:

… → MEID_CALC_ENERGY_FUEL → …

with cmi_short_code recorded in USO tail arrays.


10. Performance Notes

  • Complexity: O(nrecords)O(n_{records})
  • Memory: O(T×F)O(|T| \times |F|)
  • Highly parallelizable by site/fleet

11. Methods Served (v1)

  • Energy.fuels.abs
  • Energy.fuels.by_type.abs
  • Energy.fuels.stationary.abs
  • Energy.fuels.mobile.abs



GitHub RepoRequest for Change (RFC)