public void TestSapTimeZoneUserProperties() { Verbrauch v1 = JsonConvert.DeserializeObject <Verbrauch>("{\"startdatum\":\"2019-03-30T02:45:00\",\"enddatum\":\"2019-03-30T03:15:00\",\"wertermittlungsverfahren\":1,\"obiskennzahl\":\"1-0:1.29.0\",\"wert\":0.0,\"einheit\":1,\"zw\":\"000000000030000301\",\"Status\":\"IU015\",\"sap_timezone\":\"CET\"}"); Assert.AreEqual(DateTimeKind.Utc, v1.Startdatum.Kind); Assert.AreEqual(DateTimeKind.Utc, v1.Enddatum.Kind); Assert.AreEqual(2.75, v1.Startdatum.TimeOfDay.TotalHours); Assert.AreEqual(3.25, v1.Enddatum.TimeOfDay.TotalHours); Verbrauch v2 = JsonConvert.DeserializeObject <Verbrauch>("{\"startdatum\":\"2019-03-30T02:45:00\",\"enddatum\":\"2019-03-30T03:15:00\",\"wertermittlungsverfahren\":1,\"obiskennzahl\":\"1-0:1.29.0\",\"wert\":0.0,\"einheit\":1,\"zw\":\"000000000030000301\",\"Status\":\"IU015\",\"sap_timezone\":\"UTC\"}"); Assert.AreEqual(DateTimeKind.Utc, v2.Startdatum.Kind); Assert.AreEqual(DateTimeKind.Utc, v2.Enddatum.Kind); Assert.AreEqual(2.75, v2.Startdatum.TimeOfDay.TotalHours); Assert.AreEqual(3.25, v2.Enddatum.TimeOfDay.TotalHours); Verbrauch v3 = JsonConvert.DeserializeObject <Verbrauch>("{\"startdatum\":\"2019-10-27T02:30:00\",\"enddatum\":\"2019-10-27T02:45:00\",\"wertermittlungsverfahren\":1,\"obiskennzahl\":\"1-0:1.29.0\",\"wert\":0.0,\"einheit\":1,\"zw\":\"000000000030000301\",\"Status\":\"IU015\",\"sap_timezone\":\"CEST\"}"); Assert.AreEqual(DateTimeKind.Utc, v3.Startdatum.Kind); Assert.AreEqual(DateTimeKind.Utc, v3.Enddatum.Kind); Assert.AreEqual(2.5, v3.Startdatum.TimeOfDay.TotalHours); Assert.AreEqual(2.75, v3.Enddatum.TimeOfDay.TotalHours); Verbrauch v4 = JsonConvert.DeserializeObject <Verbrauch>("{\"startdatum\":\"2019-10-27T02:45:00\",\"enddatum\":\"2019-10-27T03:15:00\",\"wertermittlungsverfahren\":1,\"obiskennzahl\":\"1-0:1.29.0\",\"wert\":0.0,\"einheit\":1,\"zw\":\"000000000030000301\",\"Status\":\"IU015\",\"sap_timezone\":\"CEST\"}"); Assert.AreEqual(DateTimeKind.Utc, v4.Startdatum.Kind); Assert.AreEqual(DateTimeKind.Utc, v4.Enddatum.Kind); Assert.AreEqual(2.75, v4.Startdatum.TimeOfDay.TotalHours); Assert.AreEqual(3.25, v4.Enddatum.TimeOfDay.TotalHours); }
protected void OnDeserialized(StreamingContext context) { if (Energieverbrauch == null) { Energieverbrauch = new List <Verbrauch>(); } else if (Energieverbrauch.Count > 0) { Energieverbrauch = Energieverbrauch .Select(v => Verbrauch.FixSapCdsBug(v)) .Where(v => !(v.Startdatum == DateTime.MinValue || v.Enddatum == DateTime.MinValue)) .Where(v => !(v.UserProperties != null && v.UserProperties.ContainsKey("invalid") && (bool)v.UserProperties["invalid"] == true)) .ToList(); if (UserProperties != null && UserProperties.TryGetValue(Verbrauch._SAP_PROFDECIMALS_KEY, out JToken profDecimalsRaw)) { var profDecimals = profDecimalsRaw.Value <int>(); if (profDecimals > 0) { for (int i = 0; i < profDecimals; i++) { // or should I import math.pow() for this purpose? foreach (Verbrauch v in Energieverbrauch.Where(v => v.UserProperties == null || !v.UserProperties.ContainsKey(Verbrauch._SAP_PROFDECIMALS_KEY))) { v.Wert /= 10.0M; } } } UserProperties.Remove(Verbrauch._SAP_PROFDECIMALS_KEY); } } }
internal void LöscheVerbrauch(Verbrauch verbrauch) { verbrauch.Abrechnung.Verbrauche.Remove(verbrauch); verbrauch.Abrechnung = null; Kontext.SaveChanges(); VerbrauchGelöscht?.Invoke(verbrauch); }
public void TestMergeAdjacentExtensive() { Verbrauch v1 = new Verbrauch() { Obiskennzahl = "123", Wertermittlungsverfahren = Wertermittlungsverfahren.MESSUNG, Einheit = Mengeneinheit.KWH, Wert = 5, Startdatum = new DateTimeOffset(2017, 12, 31, 23, 0, 0, TimeSpan.Zero).UtcDateTime, Enddatum = new DateTimeOffset(2018, 1, 31, 23, 0, 0, TimeSpan.Zero).UtcDateTime }; Verbrauch v2 = new Verbrauch() { Obiskennzahl = "123", Wertermittlungsverfahren = Wertermittlungsverfahren.MESSUNG, Einheit = Mengeneinheit.KWH, Wert = 3, Startdatum = new DateTimeOffset(2018, 1, 31, 23, 0, 0, TimeSpan.Zero).UtcDateTime, Enddatum = new DateTimeOffset(2018, 2, 28, 23, 0, 0, TimeSpan.Zero).UtcDateTime }; HashSet <Verbrauch> result = v1.Merge(v2); Assert.AreEqual(1, result.Count); Assert.AreEqual(v1.Startdatum, result.First().Startdatum); Assert.AreEqual(v2.Enddatum, result.First().Enddatum); Assert.AreEqual(8, result.First().Wert); Assert.IsTrue(result.SetEquals(v2.Merge(v1))); }
public void TestMergeNoOverlap() { Verbrauch v1 = new Verbrauch() { Obiskennzahl = "123", Wertermittlungsverfahren = Wertermittlungsverfahren.MESSUNG, Einheit = Mengeneinheit.KWH, Wert = 5, Startdatum = new DateTimeOffset(2017, 12, 31, 23, 0, 0, TimeSpan.Zero).UtcDateTime, Enddatum = new DateTimeOffset(2018, 1, 31, 23, 0, 0, TimeSpan.Zero).UtcDateTime }; Verbrauch v2 = new Verbrauch() { Obiskennzahl = "123", Wertermittlungsverfahren = Wertermittlungsverfahren.MESSUNG, Einheit = Mengeneinheit.KWH, Wert = 3, Startdatum = new DateTimeOffset(2018, 2, 28, 23, 0, 0, TimeSpan.Zero).UtcDateTime, Enddatum = new DateTimeOffset(2018, 3, 31, 23, 0, 0, TimeSpan.Zero).UtcDateTime }; HashSet <Verbrauch> result = v1.Merge(v2); Assert.AreEqual(2, result.Count); Assert.IsTrue(result.SetEquals(new HashSet <Verbrauch> { v1, v2 })); }
/// <summary> /// <see cref="IsEvenlySpaced(BO.Energiemenge, TimeRange, Wertermittlungsverfahren, string, Mengeneinheit, bool)"/> /// </summary> /// <param name="em">Energiemenge</param> /// <param name="allowGaps"></param> /// <returns></returns> public static bool IsEvenlySpaced(this BO4E.BO.Energiemenge em, bool allowGaps = false) { if (!em.IsPure()) { // Find all combinations of Wertermittlungsverfahren, obis and Mengeneinheit. // The Energiemenge is evenly spaced if each of the combinations is evenly spaced itself. using (MiniProfiler.Current.Step("Check all Werte/Einheit/OBIS combinations")) { ISet <Tuple <Wertermittlungsverfahren, string, Mengeneinheit> > combinations = GetWevObisMeCombinations(em); foreach (Tuple <Wertermittlungsverfahren, string, Mengeneinheit> combo in combinations) { if (!em.IsEvenlySpaced(em.GetTimeRange(), combo.Item1, combo.Item2, combo.Item3, allowGaps)) { return(false); } } } return(true); } else { Verbrauch v = em.Energieverbrauch.FirstOrDefault(); return(em.IsEvenlySpaced(em.GetTimeRange(), v.Wertermittlungsverfahren, v.Obiskennzahl, v.Einheit, allowGaps)); } }
public void TestMergeRedundantExtensiveLeftJustifiedOverlap() { Verbrauch v1 = new Verbrauch() { Obiskennzahl = "123", Wertermittlungsverfahren = Wertermittlungsverfahren.MESSUNG, Einheit = Mengeneinheit.KWH, Wert = 5, Startdatum = new DateTimeOffset(2017, 12, 31, 23, 0, 0, TimeSpan.Zero).UtcDateTime, Enddatum = new DateTimeOffset(2018, 2, 28, 23, 0, 0, TimeSpan.Zero).UtcDateTime }; Verbrauch v2 = new Verbrauch() { Obiskennzahl = "123", Wertermittlungsverfahren = Wertermittlungsverfahren.MESSUNG, Einheit = Mengeneinheit.KWH, Wert = 3, Startdatum = new DateTimeOffset(2017, 12, 31, 23, 0, 0, TimeSpan.Zero).UtcDateTime, Enddatum = new DateTimeOffset(2018, 1, 31, 23, 0, 0, TimeSpan.Zero).UtcDateTime }; var rawResult = v1.MergeRedundant(v2, true); List <Verbrauch> result = new List <Verbrauch>(rawResult); result.Sort(new VerbrauchDateTimeComparer()); Assert.AreEqual(1, result.Count); Assert.AreEqual(2, result.First().Wert); Assert.AreEqual(new DateTimeOffset(2017, 12, 31, 23, 0, 0, TimeSpan.Zero), result.First().Startdatum); //Assert.AreEqual(new DateTimeOffset(2018, 1, 31, 23, 0, 0, TimeSpan.Zero), result.First().enddatum); //Assert.AreEqual(5, result.Last().wert); //Assert.AreEqual(new DateTimeOffset(2018, 1, 31, 23, 0, 0, TimeSpan.Zero), result.Last().startdatum); Assert.AreEqual(new DateTimeOffset(2018, 2, 28, 23, 0, 0, TimeSpan.Zero), result.Last().Enddatum); }
public void TestMergeRedundantExtensiveSameTime() { Verbrauch v1 = new Verbrauch() { Obiskennzahl = "123", Wertermittlungsverfahren = Wertermittlungsverfahren.MESSUNG, Einheit = Mengeneinheit.KWH, Wert = 5, Startdatum = new DateTimeOffset(2017, 12, 31, 23, 0, 0, TimeSpan.Zero).UtcDateTime, Enddatum = new DateTimeOffset(2018, 1, 31, 23, 0, 0, TimeSpan.Zero).UtcDateTime }; Verbrauch v2 = new Verbrauch() { Obiskennzahl = "123", Wertermittlungsverfahren = Wertermittlungsverfahren.MESSUNG, Einheit = Mengeneinheit.KWH, Wert = 5, Startdatum = new DateTimeOffset(2017, 12, 31, 23, 0, 0, TimeSpan.Zero).UtcDateTime, Enddatum = new DateTimeOffset(2018, 1, 31, 23, 0, 0, TimeSpan.Zero).UtcDateTime }; var rawResult = v1.MergeRedundant(v2, true); List <Verbrauch> result = new List <Verbrauch>(rawResult); Assert.AreEqual(1, result.Count); Assert.AreEqual(5, result.First().Wert); }
public void TestMergeOverlappingIntensive() { Verbrauch v1 = new Verbrauch() { Obiskennzahl = "123", Wertermittlungsverfahren = Wertermittlungsverfahren.MESSUNG, Einheit = Mengeneinheit.KW, Wert = 5, Startdatum = new DateTimeOffset(2017, 12, 31, 23, 0, 0, TimeSpan.Zero).UtcDateTime, Enddatum = new DateTimeOffset(2018, 1, 31, 23, 0, 0, TimeSpan.Zero).UtcDateTime }; Verbrauch v2 = new Verbrauch() { Obiskennzahl = "123", Wertermittlungsverfahren = Wertermittlungsverfahren.MESSUNG, Einheit = Mengeneinheit.KW, Wert = 3, Startdatum = new DateTimeOffset(2018, 1, 15, 23, 0, 0, TimeSpan.Zero).UtcDateTime, Enddatum = new DateTimeOffset(2018, 2, 28, 23, 0, 0, TimeSpan.Zero).UtcDateTime }; var rawResult = v1.Merge(v2); List <Verbrauch> result = new List <Verbrauch>(rawResult); Assert.AreEqual(3, result.Count); result.Sort(new VerbrauchDateTimeComparer()); Assert.AreEqual(v1.Startdatum, result.First().Startdatum); Assert.AreEqual(5, result.First().Wert); Assert.AreEqual(v2.Startdatum, result[1].Startdatum); Assert.AreEqual(v1.Enddatum, result[1].Enddatum); Assert.AreEqual(8, result[1].Wert); Assert.AreEqual(v2.Enddatum, result.Last().Enddatum); Assert.AreEqual(3, result.Last().Wert); Assert.IsTrue(rawResult.SetEquals(v2.Merge(v1))); }
public void TestEqualsCOM() { Verbrauch v1 = new Verbrauch(); Verbrauch v2 = new Verbrauch(); Assert.ThrowsException <JsonSerializationException>(() => v1.Equals(v2), "You must not compare invalid/incomplete COMs"); Assert.AreEqual(v1.GetHashCode(), v2.GetHashCode()); v1 = new Verbrauch() { Einheit = Mengeneinheit.KWH, Obiskennzahl = "1-1:1.8.0", Startdatum = new DateTime(2019, 1, 1, 0, 0, 0, DateTimeKind.Utc), Enddatum = new DateTime(2020, 1, 1, 0, 0, 0, DateTimeKind.Utc) }; v2 = new Verbrauch() { Einheit = Mengeneinheit.KWH, Obiskennzahl = "1-1:1.8.0", Startdatum = new DateTime(2019, 1, 1, 0, 0, 0, DateTimeKind.Utc), Enddatum = new DateTime(2020, 1, 1, 0, 0, 0, DateTimeKind.Utc) }; Assert.AreEqual(v1, v2); Assert.IsTrue(v1.Equals(v2)); Assert.AreEqual(v1.GetHashCode(), v2.GetHashCode()); Assert.IsFalse(v1 == v2); v2.Obiskennzahl = "1-1:1.8.1"; Assert.AreNotEqual(v1, v2); Assert.AreNotEqual <int>(v1.GetHashCode(), v2.GetHashCode()); Assert.AreNotEqual(new Preis(), new Menge()); }
internal void NeuerVerbrauch(Abrechnung abrechnung, Verbrauch verbrauch) { abrechnung.Verbrauche.Add(verbrauch); verbrauch.Abrechnung = abrechnung; Kontext.SaveChanges(); VerbrauchHinzugefügt?.Invoke(verbrauch); }
/// <summary> /// convert to another unit if possible /// </summary> /// <param name="v">Verbrauch</param> /// <param name="mengeneinheit">Mengeneinheit</param> /// <throws>ArgumentException if units are not convertible</throws> public static void ConvertToUnit(this Verbrauch v, Mengeneinheit mengeneinheit) { PhysikalischerWert oldWert = new PhysikalischerWert(v.Wert, v.Einheit); PhysikalischerWert newWert = oldWert.ConvertToUnit(mengeneinheit); v.Wert = newWert.Wert; v.Einheit = newWert.Einheit; }
/// <summary> /// <see cref="GetMissingTimeRanges(BO.Energiemenge, TimeRange, Wertermittlungsverfahren, string, Mengeneinheit)"/> /// </summary> /// <param name="em">Energiemenge</param> /// <param name="reference">reference time frame</param> /// <returns></returns> public static List <TimeRange> GetMissingTimeRanges(this BO4E.BO.Energiemenge em, TimeRange reference) { if (!em.IsPure()) { throw new ArgumentException("The Energiemenge you provided is not pure. Consider using the overloaded method."); } Verbrauch v = em.Energieverbrauch.FirstOrDefault(); return(GetMissingTimeRanges(em, reference, v.Wertermittlungsverfahren, v.Obiskennzahl, v.Einheit)); }
public void TestMergeRedundantRightJustifiedOverlap() { Verbrauch v1 = JsonConvert.DeserializeObject <Verbrauch>("{\"startdatum\":\"2018-12-25T16:22:00Z\",\"enddatum\":\"2019-12-25T08:20:00Z\",\"wertermittlungsverfahren\":0,\"obiskennzahl\":\"1-1:1.8.0\",\"wert\":1539,\"einheit\":2,\"zaehlernummer\":\"10000548\"}"); Verbrauch v2 = JsonConvert.DeserializeObject <Verbrauch>("{\"startdatum\":\"2018-09-01T00:00:00Z\",\"enddatum\":\"2018-12-25T16:22:00Z\",\"wertermittlungsverfahren\":0,\"obiskennzahl\":\"1-1:1.8.0\",\"wert\":911,\"einheit\":2,\"zaehlernummer\":\"10000548\"}"); var rawResult = v1.MergeRedundant(v2, true); List <Verbrauch> result = new List <Verbrauch>(rawResult); result.Sort(new VerbrauchDateTimeComparer()); Assert.AreEqual(1, result.Count); Assert.AreEqual(2450.0M, result.First().Wert); Assert.AreEqual(new DateTimeOffset(2018, 9, 1, 0, 0, 0, TimeSpan.Zero), result.First().Startdatum); Assert.AreEqual(new DateTimeOffset(2019, 12, 25, 08, 20, 0, TimeSpan.Zero), result.First().Enddatum); }
public void TestMergeAdjacentIntensive() { Verbrauch v1 = new Verbrauch() { Obiskennzahl = "123", Wertermittlungsverfahren = Wertermittlungsverfahren.MESSUNG, Einheit = Mengeneinheit.KW, Wert = 5, Startdatum = new DateTimeOffset(2017, 12, 31, 23, 0, 0, TimeSpan.Zero).UtcDateTime, Enddatum = new DateTimeOffset(2018, 1, 31, 23, 0, 0, TimeSpan.Zero).UtcDateTime }; Verbrauch v2 = new Verbrauch() { Obiskennzahl = "123", Wertermittlungsverfahren = Wertermittlungsverfahren.MESSUNG, Einheit = Mengeneinheit.KW, Wert = 3, Startdatum = new DateTimeOffset(2018, 1, 31, 23, 0, 0, TimeSpan.Zero).UtcDateTime, Enddatum = new DateTimeOffset(2018, 2, 28, 23, 0, 0, TimeSpan.Zero).UtcDateTime }; HashSet <Verbrauch> result12 = v1.Merge(v2); Assert.AreEqual(2, result12.Count); Assert.IsTrue(result12.SetEquals(v2.Merge(v1))); Verbrauch v3 = new Verbrauch() { Obiskennzahl = "123", Wertermittlungsverfahren = Wertermittlungsverfahren.MESSUNG, Einheit = Mengeneinheit.KW, Wert = 5, Startdatum = new DateTimeOffset(2017, 12, 31, 23, 0, 0, TimeSpan.Zero).UtcDateTime, Enddatum = new DateTimeOffset(2018, 1, 31, 23, 0, 0, TimeSpan.Zero).UtcDateTime }; Verbrauch v4 = new Verbrauch() { Obiskennzahl = "123", Wertermittlungsverfahren = Wertermittlungsverfahren.MESSUNG, Einheit = Mengeneinheit.KW, Wert = 5, Startdatum = new DateTimeOffset(2018, 1, 31, 23, 0, 0, TimeSpan.Zero).UtcDateTime, Enddatum = new DateTimeOffset(2018, 2, 28, 23, 0, 0, TimeSpan.Zero).UtcDateTime }; HashSet <Verbrauch> result34 = v3.Merge(v4); //Assert.AreEqual(1, result34.Count); Assert.IsTrue(result34.SetEquals(v4.Merge(v3))); }
/// <summary> /// Get percentage of time range covered by pure Energiemenge. /// </summary> /// <param name="em">pure Energiemenge</param> /// <param name="reference">time frame reference</param> /// <returns>value between 0 (only coverage for 1 point in time) and 1.0 (100% coverage)</returns> public static decimal GetCoverage(this BO4E.BO.Energiemenge em, ITimeRange reference) { using (MiniProfiler.Current.Step(nameof(GetCoverage))) { if (!IsPure(em)) { throw new ArgumentException("The Energiemenge is not pure. Cannot determine parameters."); } if (em.Energieverbrauch.Count == 0) { return(0.0M); } Verbrauch v = em.Energieverbrauch.First <Verbrauch>(); return(em.GetCoverage(reference, v.Wertermittlungsverfahren, v.Obiskennzahl, v.Einheit)); } }
/// <summary> /// Get Average (<see cref="GetAverage(BO.Energiemenge, TimeRange, Wertermittlungsverfahren, string, Mengeneinheit)"/>) /// for a pure Energiemenge with automatically found parameters. /// </summary> /// <seealso cref="IsPure(BO4E.BO.Energiemenge)"/> /// <param name="em">Energiemenge</param> /// <returns>Tuple of average value and unit of measurement</returns> public static Tuple <decimal?, Mengeneinheit> GetAverage(this BO4E.BO.Energiemenge em) { if (!IsPure(em)) { throw new ArgumentException("Energiemenge is not pure."); } else if (em.Energieverbrauch.Count == 0) { return(Tuple.Create <decimal?, Mengeneinheit>(null, Mengeneinheit.KW)); } else { Verbrauch v = em.Energieverbrauch.First <Verbrauch>(); return(Tuple.Create <decimal?, Mengeneinheit>(em.GetAverage(v.Wertermittlungsverfahren, v.Obiskennzahl, v.Einheit), v.Einheit)); } }
int IComparer <CompletenessReport.BasicVerbrauch> .Compare(CompletenessReport.BasicVerbrauch x, CompletenessReport.BasicVerbrauch y) { Verbrauch vx = new Verbrauch { Startdatum = x.Startdatum, Enddatum = x.Enddatum, }; Verbrauch vy = new Verbrauch { Startdatum = y.Startdatum, Enddatum = y.Enddatum, }; IComparer <Verbrauch> cv = new VerbrauchDateTimeComparer(); return(cv.Compare(vx, vy)); }
public void TestVerbrauch() { Verbrauch v1 = new Verbrauch(); Assert.IsFalse(v1.IsValid()); Verbrauch v2 = new Verbrauch { Startdatum = new DateTime(), Enddatum = new DateTime(), Einheit = BO4E.ENUM.Mengeneinheit.ANZAHL, Wert = (decimal)123.456, Obiskennzahl = "asd" }; Assert.IsTrue(v2.IsValid()); }
public void TestUnitConversion() { Verbrauch v1 = new Verbrauch() { Obiskennzahl = "123", Wertermittlungsverfahren = Wertermittlungsverfahren.MESSUNG, Einheit = Mengeneinheit.MW, Wert = 17, Startdatum = new DateTimeOffset(2017, 12, 31, 23, 0, 0, TimeSpan.Zero).UtcDateTime, Enddatum = new DateTimeOffset(2018, 3, 31, 23, 0, 0, TimeSpan.Zero).UtcDateTime }; v1.ConvertToUnit(Mengeneinheit.KW); Assert.AreEqual(Mengeneinheit.KW, v1.Einheit); Assert.AreEqual(17000.0M, v1.Wert); Assert.ThrowsException <InvalidOperationException>(() => v1.ConvertToUnit(Mengeneinheit.KWH)); }
public void ShowCaseTest() { var verbrauchA = new Verbrauch() { Startdatum = new DateTime(2020, 3, 1, 0, 0, 0, DateTimeKind.Utc), Enddatum = new DateTime(2020, 3, 8, 0, 0, 0, DateTimeKind.Utc), Wert = 0.456M, Einheit = Mengeneinheit.MW, Wertermittlungsverfahren = Wertermittlungsverfahren.MESSUNG }; verbrauchA.ConvertToUnit(Mengeneinheit.KW); Debug.WriteLine($"{nameof(verbrauchA)} contains {verbrauchA.Wert}{verbrauchA.Einheit}"); // v contains 456,000KW try { verbrauchA.ConvertToUnit(Mengeneinheit.TAG); } catch (InvalidOperationException ioe) { Debug.WriteLine(ioe.Message); // KW and TAG are not convertible into each other because they don't share the same dimension. } var verbrauchB = new Verbrauch() { Startdatum = new DateTime(2020, 3, 7, 0, 0, 0, DateTimeKind.Utc), Enddatum = new DateTime(2020, 3, 14, 0, 0, 0, DateTimeKind.Utc), Wert = 0.1M, Einheit = Mengeneinheit.KW, Wertermittlungsverfahren = Wertermittlungsverfahren.MESSUNG }; foreach (Verbrauch v in verbrauchA.Merge(verbrauchB)) { Debug.WriteLine($"{v.Startdatum.ToString("yyyy-MM-dd")} to {v.Enddatum.ToString("yyyy-MM-dd")}: {v.Wert}{v.Einheit}"); } // 2020-03-01 to 2020-03-07: 456,000KW // 2020-03-07 to 2020-03-08: 456,100KW // 2020-03-08 to 2020-03-14: 0,1KW }
public void TestSommerzeitumstellung() { // endzeitpunkt wird im sap aus startzeitpunkt + 1 std zusammengesetzt. bei umstellung auf sommerzeit entsteht als artefakt ein shift Verbrauch v1 = JsonConvert.DeserializeObject <Verbrauch>("{\"zw\":\"000000000020720475\",\"startdatum\":\"201903310100\",\"enddatum\":\"201903310300\",\"wert\":263,\"status\":\"IU021\",\"obiskennzahl\":\"7-10:99.33.17\",\"wertermittlungsverfahren\":\"MESSUNG\",\"einheit\":\"KWH\",\"sap_timezone\":\"CET\"}", new LenientDateTimeConverter()); Assert.AreEqual(new DateTimeOffset(2019, 3, 31, 2, 0, 0, TimeSpan.Zero), v1.Enddatum); // negativ test: nur in der sommerzeit soll das nicht passieren Verbrauch v2 = JsonConvert.DeserializeObject <Verbrauch>("{\"zw\":\"000000000020720475\",\"startdatum\":\"201905310100\",\"enddatum\":\"201905310300\",\"wert\":263,\"status\":\"IU021\",\"obiskennzahl\":\"7-10:99.33.17\",\"wertermittlungsverfahren\":\"MESSUNG\",\"einheit\":\"KWH\",\"sap_timezone\":\"CET\"}", new LenientDateTimeConverter()); Assert.AreEqual(new DateTimeOffset(2019, 5, 31, 3, 0, 0, TimeSpan.Zero), v2.Enddatum); // negativ test: nur in der winterzeit soll das nicht passieren Verbrauch v3 = JsonConvert.DeserializeObject <Verbrauch>("{\"zw\":\"000000000020720475\",\"startdatum\":\"201901310100\",\"enddatum\":\"201901310300\",\"wert\":263,\"status\":\"IU021\",\"obiskennzahl\":\"7-10:99.33.17\",\"wertermittlungsverfahren\":\"MESSUNG\",\"einheit\":\"KWH\",\"sap_timezone\":\"CET\"}", new LenientDateTimeConverter()); Assert.AreEqual(new DateTimeOffset(2019, 1, 31, 3, 0, 0, TimeSpan.Zero), v3.Enddatum); }
/// <summary> /// Get consumption in given time reference frame. Trying to automatically determine parameters and forward to <see cref="BO4E.BO.Energiemenge.GetConsumption(BO.Energiemenge, TimeRange, Wertermittlungsverfahren, string, Mengeneinheit)"/>. /// </summary> /// <param name="em">Energiemenge</param> /// <param name="reference">time reference frame</param> /// <returns>Tuple of consumption value and automatically determined unit of measurement</returns> public static Tuple <decimal, Mengeneinheit> GetConsumption(this BO4E.BO.Energiemenge em, ITimeRange reference) { using (MiniProfiler.Current.Step(nameof(GetConsumption))) { if (!IsPure(em)) { throw new ArgumentException("The Energiemenge is not pure."); } if (em.Energieverbrauch.Count == 0) { return(Tuple.Create <decimal, Mengeneinheit>(0.0M, Mengeneinheit.ANZAHL)); } ISet <Mengeneinheit> einheiten = new HashSet <Mengeneinheit>(em.Energieverbrauch.Select(x => x.Einheit)); if (einheiten.Count > 1) { // z.B. kWh und Wh oder Monat und Jahr... Die liefern IsPure==true. throw new NotImplementedException("Converting different units of same type is not supported yet."); } Verbrauch v = em.Energieverbrauch.First <Verbrauch>(); decimal consumption = em.GetConsumption(reference, v.Wertermittlungsverfahren, v.Obiskennzahl, v.Einheit); return(Tuple.Create <decimal, Mengeneinheit>(consumption, v.Einheit)); } }
public static bool Contains(this Verbrauch v1, Verbrauch v2) { return(v1.OverlapsWith(v2) && v1.Startdatum <= v2.Startdatum && v1.Enddatum >= v2.Enddatum); }
public static ITimeRange GetIntersection(this Verbrauch v1, Verbrauch v2) { return(v1.GetIntersection(new TimeRange(v2.Startdatum, v2.Enddatum))); }
public static ITimeRange GetIntersection(this Verbrauch v1, ITimeRange tr2) { return(new TimeRange(v1.Startdatum, v1.Enddatum).GetIntersection(tr2)); }
public static bool OverlapsWith(this Verbrauch v1, ITimeRange tr2) { return(new TimeRange(v1.Startdatum, v1.Enddatum).OverlapsWith(tr2)); }
/// <summary> /// Test if the time ranges [startdatum, enddatum) overlap. /// </summary> /// <param name="v1"></param> /// <param name="v2"></param> /// <returns>true iff [<paramref name="v1"/>.startdatum, <paramref name="v1"/>.enddatum) and [<paramref name="v2"/>.startdatum, <paramref name="v2"/>.enddatum) overlap</returns> public static bool OverlapsWith(this Verbrauch v1, Verbrauch v2) { return(v1.OverlapsWith(new TimeRange(v2.Startdatum, v2.Enddatum, true))); }
public static HashSet <Verbrauch> Merge(this Verbrauch v1, Verbrauch v2, bool redundant, Boolean biased) { HashSet <Verbrauch> result = new HashSet <Verbrauch>(); if (v1.Obiskennzahl == v2.Obiskennzahl && v1.Wertermittlungsverfahren == v2.Wertermittlungsverfahren && v1.Einheit == v2.Einheit) { if (v1.OverlapsWith(v2)) { // don't wanna deal with time running backwards. //Debug.Assert(v1.enddatum >= v1.startdatum); //Debug.Assert(v2.enddatum >= v2.startdatum); TimeRange tr1 = new TimeRange(v1.Startdatum, v1.Enddatum); TimeRange tr2 = new TimeRange(v2.Startdatum, v2.Enddatum); ITimeRange overlap = v1.GetIntersection(v2); if (v1.Einheit.IsExtensive()) { Verbrauch vmerge = new Verbrauch() { Obiskennzahl = v1.Obiskennzahl, Einheit = v1.Einheit, Wertermittlungsverfahren = v1.Wertermittlungsverfahren }; if (redundant) { decimal exclusiveV1Wert = (decimal)(tr1.Duration.TotalSeconds - overlap.Duration.TotalSeconds) * v1.Wert / ((decimal)tr1.Duration.TotalSeconds); decimal exclusiveV2Wert = (decimal)(tr2.Duration.TotalSeconds - overlap.Duration.TotalSeconds) * v2.Wert / ((decimal)tr2.Duration.TotalSeconds); decimal overlapV1Wert = ((decimal)overlap.Duration.TotalSeconds * v1.Wert) / (decimal)(tr1.Duration.TotalSeconds); decimal overlapV2Wert = ((decimal)overlap.Duration.TotalSeconds * v2.Wert) / (decimal)(tr2.Duration.TotalSeconds); if (biased == true) { // biased ==> assume that v2 is contained in v1 vmerge.Startdatum = v1.Startdatum; vmerge.Enddatum = v1.Enddatum; if (exclusiveV1Wert == 0.0M && exclusiveV2Wert == 0.0M && overlapV1Wert == overlapV2Wert) { vmerge.Wert = overlapV1Wert; } else { vmerge.Wert = v1.Wert - overlapV2Wert; // overlapV1Wert; } } else if (biased == false) { vmerge.Startdatum = v1.Startdatum; vmerge.Enddatum = v2.Startdatum; vmerge.Wert = v1.Wert - overlapV2Wert; } else // biased null { vmerge.Startdatum = v1.Startdatum < v2.Startdatum ? v1.Startdatum : v2.Startdatum; vmerge.Enddatum = v1.Enddatum > v2.Enddatum ? v1.Enddatum : v2.Enddatum; if (overlapV1Wert != overlapV2Wert) { throw new ArgumentException("The inequality is unsolvable."); } vmerge.Wert = exclusiveV1Wert + overlapV1Wert + exclusiveV2Wert; } } else { vmerge.Startdatum = v1.Startdatum < v2.Startdatum ? v1.Startdatum : v2.Startdatum; vmerge.Enddatum = v1.Enddatum > v2.Enddatum ? v1.Enddatum : v2.Enddatum; vmerge.Wert = v1.Wert + v2.Wert; } result.Add(vmerge); } else { Verbrauch vmerge1 = new Verbrauch() { Obiskennzahl = v1.Obiskennzahl, Einheit = v1.Einheit, Wertermittlungsverfahren = v1.Wertermittlungsverfahren, Startdatum = v1.Startdatum < v2.Startdatum ? v1.Startdatum : v2.Startdatum, Enddatum = overlap.Start, Wert = v1.Startdatum < v2.Startdatum ? v1.Wert : v2.Wert }; Verbrauch vmerge2 = new Verbrauch() { Obiskennzahl = v1.Obiskennzahl, Einheit = v1.Einheit, Wertermittlungsverfahren = v1.Wertermittlungsverfahren, Startdatum = overlap.Start, Enddatum = overlap.End }; if (redundant) { if (v1.Wert != v2.Wert) { throw new ArgumentException($"Data cannot be redundant if values ({v1.Wert}{v1.Einheit} vs. {v2.Wert}{v2.Einheit}) don't match for interval [{vmerge2.Startdatum}, {vmerge2.Enddatum})."); } vmerge2.Wert = v1.Wert; } else { vmerge2.Wert = v1.Wert + v2.Wert; } Verbrauch vmerge3 = new Verbrauch() { Obiskennzahl = v1.Obiskennzahl, Einheit = v1.Einheit, Wertermittlungsverfahren = v1.Wertermittlungsverfahren, Startdatum = overlap.End, Enddatum = v1.Enddatum > v2.Enddatum ? v1.Enddatum : v2.Enddatum, Wert = v1.Enddatum > v2.Enddatum ? v1.Wert : v2.Wert }; result.Add(vmerge1); result.Add(vmerge2); result.Add(vmerge3); } } else if (v1.Startdatum == v2.Enddatum || v2.Startdatum == v1.Enddatum) { DateTime start = v1.Startdatum < v2.Startdatum ? v1.Startdatum : v2.Startdatum; DateTime stop = v1.Enddatum > v2.Enddatum ? v1.Enddatum : v2.Enddatum; Verbrauch vmerge = new Verbrauch() { Obiskennzahl = v1.Obiskennzahl, Einheit = v1.Einheit, Wertermittlungsverfahren = v1.Wertermittlungsverfahren, Startdatum = start, Enddatum = stop }; if (v1.Einheit.IsExtensive()) { vmerge.Wert = v1.Wert + v2.Wert; result.Add(vmerge); } else if (v1.Wert == v2.Wert) // implicitly intensive { vmerge.Wert = v1.Wert; result.Add(vmerge); } else { // merging intensive verbrauch with different values is not possible. result.Add(v1); result.Add(v2); } } else { // laaaangweilig ;) result.Add(v1); result.Add(v2); } } else { // laaaangweilig ;) result.Add(v1); result.Add(v2); } result.RemoveWhere(v => v.Einheit.IsIntensive() && new TimeRange(v.Startdatum, v.Enddatum).Duration.TotalMilliseconds == 0); return(result); }
public static HashSet <Verbrauch> MergeRedundant(this Verbrauch v1, Verbrauch v2, Boolean biased) { return(v1.Merge(v2, true, biased)); }