public void TestPlausibilityReportGenerationSomeCustomer() { foreach (string boFile in Directory.GetFiles("Energiemenge/plausibility", "somecustomer*.json")) { JObject json; using (StreamReader r = new StreamReader(boFile)) { string jsonString = r.ReadToEnd(); json = JsonConvert.DeserializeObject <JObject>(jsonString); } foreach (var key in new HashSet <string> { "reference", "other", "expectedResult" }) { if (!json.ContainsKey(key)) { throw new ArgumentException($"Test file {boFile} has no key '{key}'."); } } Energiemenge emReference = JsonConvert.DeserializeObject <Energiemenge>(json["reference"].ToString()); Energiemenge emOther = JsonConvert.DeserializeObject <Energiemenge>(json["other"].ToString()); PlausibilityReport prActual = emReference.GetPlausibilityReport(emOther); PlausibilityReport prExpected = JsonConvert.DeserializeObject <PlausibilityReport>(json["expectedResult"].ToString()); Assert.AreEqual(prExpected, prActual); } }
/// <summary> /// Returns a <see cref="PlausibilityReport"/> that compares <paramref name="emReference"/> with <paramref name="emOther"/>. /// within the interval defined in <paramref name="timeframe"/>. /// </summary> /// <param name="emReference">reference Energiemenge (reference = used for normalisation)</param> /// <param name="emOther">other Energiemenge</param> /// <param name="timeframe">time frame to be analysed. If null, the overlap of <paramref name="emReference"/> and <paramref name="emOther"/> is used.</param> /// <param name="ignoreLocation">By default (false) an ArgumentException is thrown if the <see cref="BO4E.BO.Energiemenge.LokationsId"/> do not match. Setting this flag suppresses the error.</param> /// <returns>a <see cref="PlausibilityReport"/></returns> public static PlausibilityReport GetPlausibilityReport(this BO4E.BO.Energiemenge emReference, BO4E.BO.Energiemenge emOther, ITimeRange timeframe = null, bool ignoreLocation = false) { using (MiniProfiler.Current.Step(nameof(GetPlausibilityReport))) { TimeRange trReference = emReference.GetTimeRange(); TimeRange trOther = emOther.GetTimeRange(); if (timeframe == null) { ITimeRange overlap = trReference.GetIntersection(trOther); if (!ignoreLocation) { if (!(emReference.LokationsId == emOther.LokationsId && emReference.LokationsTyp == emOther.LokationsTyp)) { throw new ArgumentException($"locations do not match! '{emReference.LokationsId}' ({emReference.LokationsTyp}) != '{emOther.LokationsId}' ({emOther.LokationsTyp})"); } } timeframe = overlap; } Tuple <decimal, Mengeneinheit> consumptionReference; Tuple <decimal, Mengeneinheit> consumptionOtherRaw; using (MiniProfiler.Current.Step("Get Consumptions for overlap:")) { consumptionReference = emReference.GetConsumption(timeframe); consumptionOtherRaw = emOther.GetConsumption(timeframe); } Tuple <decimal, Mengeneinheit> consumptionOther; if (consumptionReference.Item2 != consumptionOtherRaw.Item2) { // unit mismatch if (consumptionReference.Item2.IsConvertibleTo(consumptionOtherRaw.Item2)) { consumptionOther = new Tuple <decimal, Mengeneinheit>(consumptionOtherRaw.Item1 * consumptionOtherRaw.Item2.GetConversionFactor(consumptionReference.Item2), consumptionReference.Item2); } else { throw new ArgumentException($"The unit {consumptionOtherRaw.Item2} is not comparable to {consumptionReference.Item2}!"); } } else { consumptionOther = consumptionOtherRaw; } decimal absoluteDeviation = consumptionOther.Item1 - consumptionReference.Item1; decimal?relativeDeviation; try { relativeDeviation = absoluteDeviation / consumptionReference.Item1; } catch (DivideByZeroException) { relativeDeviation = null; } Verbrauch vReference = emReference.Energieverbrauch.FirstOrDefault(); // copies obiskennzahl, wertermittlungsverfahren... vReference.Wert = consumptionReference.Item1; vReference.Einheit = consumptionReference.Item2; vReference.Startdatum = timeframe.Start; vReference.Enddatum = timeframe.End; Verbrauch vOther = emOther.Energieverbrauch.FirstOrDefault(); // copies obiskennzahl, wertermittlungsverfahren... vOther.Wert = consumptionOther.Item1; vOther.Einheit = consumptionOther.Item2; vOther.Startdatum = timeframe.Start; vOther.Enddatum = timeframe.End; var pr = new PlausibilityReport() { LokationsId = emReference.LokationsId, ReferenceTimeFrame = new BO4E.COM.Zeitraum() { Startdatum = timeframe.Start, Enddatum = timeframe.End }, VerbrauchReference = vReference, VerbrauchOther = vOther, AbsoluteDeviation = Math.Abs(absoluteDeviation), AbsoluteDeviationEinheit = consumptionReference.Item2 }; if (relativeDeviation.HasValue) { pr.RelativeDeviation = Math.Round(relativeDeviation.Value, 4); } else { pr.RelativeDeviation = null; } return(pr); } }