d972f67bad
Infrastructure-free normalization engine in Core dispatching on MeterMode: - Cumulative/Generation counters: register deltas, first-reading baseline (Haus 411, Auto 3755), meter swaps (water …861→2 reconciles to 12 via boundary registers OR an explicit amount override), counter resets, anomaly-guarded decreases. - RuntimeCounter: Δhours × rate (fixed/empirical). - ConsumableBalance: tank level-Δ + deliveries → consumption, cm→litre calibration; delivery-only rows before the first dipstick emit nothing. - DirectDelta, and Virtual meters via a small safe arithmetic evaluator (Netz Einsparung = Haus − Netz, Eigenverbrauch = Erzeugung − Einsparung) — data-driven, not hardcoded. - DatabaseSeeder: default energy types, cost categories, base settings (idempotent). 24 Core unit tests + 4 integration tests green. Claude-Session: https://claude.ai/code/session_01WujdMtMJPbxDpDnMeK22rr
48 lines
1.6 KiB
C#
48 lines
1.6 KiB
C#
using MeterVault.Core.Domain;
|
|
|
|
namespace MeterVault.Core.Normalization;
|
|
|
|
/// <summary>
|
|
/// The immutable, infrastructure-free view of a meter that the normalization engine needs.
|
|
/// Infrastructure projects a <see cref="Meter"/> (+ optional <see cref="Tank"/>) into this.
|
|
/// </summary>
|
|
public sealed record MeterConfig
|
|
{
|
|
public required int MeterId { get; init; }
|
|
|
|
public required MeterMode Mode { get; init; }
|
|
|
|
public required string Unit { get; init; }
|
|
|
|
/// <summary>Register baseline for a newly installed meter (SDD §7.1). Default 0.</summary>
|
|
public double InitialBaseline { get; init; }
|
|
|
|
/// <summary>Tank/runtime configuration for consumable_balance and runtime_counter meters.</summary>
|
|
public TankConfig? Tank { get; init; }
|
|
|
|
/// <summary>Expression + referenced meters for virtual meters.</summary>
|
|
public VirtualSpec? Virtual { get; init; }
|
|
}
|
|
|
|
/// <summary>Consumable/runtime parameters (SDD §5.3 <c>tank</c>).</summary>
|
|
public sealed record TankConfig
|
|
{
|
|
public double Capacity { get; init; }
|
|
|
|
public TankRateMode RateMode { get; init; } = TankRateMode.Empirical;
|
|
|
|
/// <summary>Litres per runtime-hour when <see cref="RateMode"/> is Fixed.</summary>
|
|
public double? FixedRate { get; init; }
|
|
|
|
/// <summary>Physical-level (cm) → volume curve. Present when dipstick readings are recorded.</summary>
|
|
public CalibrationCurve? Calibration { get; init; }
|
|
}
|
|
|
|
/// <summary>A virtual meter's expression over other meters' series (SDD §7.4).</summary>
|
|
public sealed record VirtualSpec
|
|
{
|
|
public required string Expression { get; init; }
|
|
|
|
public IReadOnlyList<int> ReferencedMeterIds { get; init; } = [];
|
|
}
|