pub struct Quantities {Show 18 fields
pub electricity: Option<MeterInput>,
pub sect14a_modul3: Option<Sect14aModul3Verbrauch>,
pub gas: Option<GasMeterInput>,
pub heat: Option<WaermeMeterInput>,
pub wasser: Option<WasserMeterInput>,
pub solar: Option<SolarMeterInput>,
pub ggv_solar: Option<GgvSolarInput>,
pub eeg: Option<EegMeterInput>,
pub einspeisung: Option<EegMeterInput>,
pub hems: Option<HemsMeterInput>,
pub emobility: Option<EmobilityMeterInput>,
pub service: Option<ServiceMeterInput>,
pub dynamic_intervals: Vec<DynamicInterval>,
pub dynamic_epex_prices: HashMap<OffsetDateTime, Decimal>,
pub eeg_gutschrift_eur: Option<Decimal>,
pub prosumer: Option<ProsumerMeterInput>,
pub sect41a_annual_comparison: Option<Sect41aAnnualComparison>,
pub energy_share: Option<EnergyShareMeterInput>,
}Expand description
All metered quantities for one billing period.
Replaces the scattered positional parameters of the old calculate_* functions.
Set only the fields relevant for the current billing run — defaults are None/
empty for unused products.
§Multi-product billing
To bill a customer with electricity + solar + HEMS on one invoice:
let quantities = Quantities {
electricity: Some(MeterInput { arbeitsmenge_kwh: dec!(500), ..Default::default() }),
solar: Some(SolarMeterInput { eigenverbrauch_kwh: dec!(120) }),
hems: Some(HemsMeterInput { months: Some(dec!(1)), ..Default::default() }),
..Default::default()
};Fields§
§electricity: Option<MeterInput>Electricity consumption (STROM, WAERMEPUMPE, WALLBOX).
sect14a_modul3: Option<Sect14aModul3Verbrauch>§14a Modul 3 — the controllable device’s energy per Tarifstufe.
The Netzbetreiber’s time windows, not the supplier’s HT/NT: the two
gratings are set by different parties and rarely coincide, which is why
this is not derived from MeterInput’s Zweitarif split.
gas: Option<GasMeterInput>Natural gas consumption (GAS).
heat: Option<WaermeMeterInput>District heat / Fernwärme (WAERME).
wasser: Option<WasserMeterInput>Drinking water / wastewater (WASSER).
solar: Option<SolarMeterInput>Solar self-consumption / Mieterstrom / GGV (SOLAR) — simple single-rate path.
ggv_solar: Option<GgvSolarInput>§42b EnWG (Solarpaket I) — GGV community solar hybrid billing.
Use instead of (or in addition to) solar when the plant’s generation must be
proportionally allocated among tenants. The SolarProvider will then generate
two positions per tenant:
- PV portion:
min(consumption, allocated_pv)at the community solar rate - Grid portion:
max(0, consumption − allocated_pv)at the regular electricity rate
Computed via GgvNutzungsplan::allocate(plant_generation_kwh) in billingd.
eeg: Option<EegMeterInput>EEG feed-in meter data (simplified path — rates from TariffInput).
einspeisung: Option<EegMeterInput>Non-EEG Direktvermarktung feed-in (EINSPEISUNG).
hems: Option<HemsMeterInput>HEMS subscription and event data.
emobility: Option<EmobilityMeterInput>E-mobility CPO/EMSP data.
service: Option<ServiceMeterInput>Energiedienstleistung service data.
dynamic_intervals: Vec<DynamicInterval>§41a dynamic tariff intervals (15-min Lastgang from edmd).
dynamic_epex_prices: HashMap<OffsetDateTime, Decimal>EPEX Spot price map for §41a billing: quarter-hour MTU start (UTC) → ct/kWh.
Keyed on the 15-minute market time unit start instant
(crate::provider::mtu_start) — DST-safe and aligned with the EPEX
SPOT 15-min day-ahead products (live since 2025-10-01).
Set by the service layer (billingd) after fetching from productd.
DynamicElectricityProvider reads this map as a fallback when its internal
SpotPriceSource has no data for an interval. This is the standard production path:
build_engine() creates the provider with an empty source, and prices flow in here
at bill() time.
eeg_gutschrift_eur: Option<Decimal>EEG Gutschrift credit passed through to electricity billing (e.g. from einsd).
prosumer: Option<ProsumerMeterInput>Prosumer meter data (PV self-consumption + grid draw).
When set, ElectricityProvider uses the prosumer billing path:
- Grid consumption is billed at full tariff (commodity + NNE + Stromsteuer)
- Self-consumption is Stromsteuer-exempt (§ 9 Abs. 1 Nr. 3 StromStG)
- NNE does NOT apply to self-consumed energy
sect41a_annual_comparison: Option<Sect41aAnnualComparison>§41a Abs. 6 EnWG — annual savings comparison for dynamic tariff customers.
When set, DynamicElectricityProvider renders a mandatory informational
position on the annual invoice comparing actual dynamic costs against a
reference fixed tariff (§41a Abs. 6 EnWG).
§42c EnWG Energy Sharing — allocated community energy for this customer.
When set, EnergyShareProvider generates a credit position for the
customer’s share of locally produced community electricity.
§Data source
Populated by billingd after querying the sharing community’s allocation
data from edmd (virtual meter with GgvConstantAllocation or
GgvProportionalAllocation rule — same infrastructure as §42b EnWG GGV).
Implementations§
Source§impl Quantities
impl Quantities
Sourcepub fn empty_energy_sources(&self) -> Vec<&'static str>
pub fn empty_energy_sources(&self) -> Vec<&'static str>
The metered sources that were supplied and carry no quantity at all.
A supply invoice for a period longer than a day whose every energy
source reads zero charges the standing charges and nothing for the
commodity, and reads exactly like an ordinary invoice — the quantity
twin of the KEIN_ARBEITSPREIS family, which refuses a product that
prices nothing.
Only sources with an energy or volume dimension are considered. HEMS and Energiedienstleistung are billed per month and per event, so “zero kWh” says nothing about them.
Names the sources rather than answering yes/no, so the finding can say which reading is missing. Empty when at least one source carries a quantity, or when none of these sources was supplied at all.
Trait Implementations§
Source§impl Clone for Quantities
impl Clone for Quantities
Source§fn clone(&self) -> Quantities
fn clone(&self) -> Quantities
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more