Esempio n. 1
0
        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);
            }
        }