using MeterVault.Core.Domain; using MeterVault.Core.Normalization; using static MeterVault.Core.Tests.TestData; namespace MeterVault.Core.Tests; /// /// The electricity derived columns are data-driven virtual expressions, not hardcoded formulas /// (SDD §2.2, §7.4): Netz Einsparung = Haus − Netz, Anlage Eigenverbrauch = Erzeugung − Einsparung. /// public sealed class VirtualMeterTests { private readonly INormalizationEngine _engine = NormalizationEngine.CreateDefault(); private static Consumption Cons(int meterId, DateTimeOffset time, double amount) => new() { MeterId = meterId, Time = time, Amount = amount, Kind = ConsumptionKind.Consumption, Quality = ReadingQuality.Imported, }; [Fact] public void Netz_einsparung_is_haus_minus_netz() { var oct = Month(2022, 10); var nov = Month(2022, 11); var ctx = new NormalizationContext { Meter = new MeterConfig { MeterId = 100, Mode = MeterMode.Virtual, Unit = "kWh", Virtual = new VirtualSpec { Expression = "m1 - m2", ReferencedMeterIds = [1, 2] }, }, ReferencedSeries = new Dictionary> { [1] = [Cons(1, oct, 411), Cons(1, nov, 742)], // Haus Verbrauch [2] = [Cons(2, oct, 416), Cons(2, nov, 832)], // Netz Verbrauch }, }; var result = _engine.Normalize(ctx); Assert.Equal([-5d, -90d], result.Select(c => c.Amount)); } [Fact] public void Eigenverbrauch_is_erzeugung_minus_einsparung() { var oct = Month(2022, 10); var ctx = new NormalizationContext { Meter = new MeterConfig { MeterId = 101, Mode = MeterMode.Virtual, Unit = "kWh", Virtual = new VirtualSpec { Expression = "m50 - m100", ReferencedMeterIds = [50, 100] }, }, ReferencedSeries = new Dictionary> { [50] = [Cons(50, oct, 76)], // Solar Erzeugung [100] = [Cons(100, oct, -5)], // Netz Einsparung (from the previous test) }, }; var result = _engine.Normalize(ctx); // 76 − (−5) = 81 (Anlage Eigenverbrauch Okt 2022). Assert.Equal([81d], result.Select(c => c.Amount)); } }