private void UpdateRegisterValuesFromXml(XDocument raw, AdapterContext ctx)
        {
            Log.Information("Adding the current register value to the XML result file.");

            this.LastErrorMessages.Clear();
            UsagePointAdapterTRuDI model;

            try
            {
                Log.Information("Validating XSD schema");
                Ar2418Validation.ValidateSchema(raw);

                Log.Information("Parsing model");
                model = XmlModelParser.ParseHanAdapterModel(raw?.Root?.Descendants());

                Log.Information("Validating model");
                ModelValidation.ValidateHanAdapterModel(model);
            }
            catch (AggregateException ex)
            {
                foreach (var err in ex.InnerExceptions)
                {
                    Log.Error(err, err.Message);
                    this.LastErrorMessages.Add(err.Message);
                }

                throw;
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Loading XML data with current values failed: {0}", ex.Message);
                this.LastErrorMessages.Add(ex.Message);
                throw;
            }

            model.MeterReadings.Sort((a, b) => string.Compare(a.ReadingType.ObisCode, b.ReadingType.ObisCode, StringComparison.InvariantCultureIgnoreCase));
            this.CurrentDataResult.MeterReadings = model.MeterReadings;
            this.CurrentDataResult.Begin         = model.MeterReadings.FirstOrDefault()?.IntervalBlocks?.FirstOrDefault()?.Interval?.Start;
            var usagePoint = this.CurrentDataResult.Raw.Root.Elements().FirstOrDefault();
            var readings   = raw?.Root?.Elements().FirstOrDefault().Elements().Where(e => e.Name.LocalName == "MeterReading");

            usagePoint.Add(readings);

            if (this.CurrentDataResult.Begin != null)
            {
                var duration = model.MeterReadings.FirstOrDefault()?.IntervalBlocks?.FirstOrDefault()?.Interval?.Duration;
                if (duration != null)
                {
                    this.CurrentDataResult.End = this.CurrentDataResult.Begin + TimeSpan.FromSeconds(duration.Value);
                }
            }
        }
        public void TestGetErrors()
        {
            var xml   = XDocument.Load(@"Data\result_3_days_geterrorlist.xml");
            var model = XmlModelParser.ParseHanAdapterModel(xml.Root.Descendants());

            var target = new OriginalValueList(model.MeterReadings[0], Kind.Electricity);

            var errors = target.GetErrorsList();

            Assert.AreEqual(4, errors.Count);

            Assert.AreEqual(96, errors[0].ValueCount);
            Assert.AreEqual(0, errors[0].GapCount);
            Assert.IsFalse(errors[0].HasErrors);
            Assert.AreEqual(0, errors[0].FatalErrorCount);
            Assert.AreEqual(0, errors[0].WarningCount);
            Assert.AreEqual(0, errors[0].TempErrorCount);
            Assert.AreEqual(0, errors[0].CriticalTempErrorCount);
            Assert.AreEqual(96, errors[0].OkCount);
            Assert.AreEqual("2017-11-04T00:00:00+01:00", errors[0].Timestamp.ToIso8601Local());

            Assert.AreEqual(96, errors[1].ValueCount);
            Assert.AreEqual(1, errors[1].GapCount);
            Assert.IsTrue(errors[1].HasErrors);
            Assert.AreEqual(3, errors[1].FatalErrorCount);
            Assert.AreEqual(1, errors[1].WarningCount);
            Assert.AreEqual(2, errors[1].TempErrorCount);
            Assert.AreEqual(3, errors[1].CriticalTempErrorCount);
            Assert.AreEqual(86, errors[1].OkCount);
            Assert.AreEqual("2017-11-05T00:00:00+01:00", errors[1].Timestamp.ToIso8601Local());

            Assert.AreEqual(96, errors[2].ValueCount);
            Assert.AreEqual(0, errors[2].GapCount);
            Assert.IsTrue(errors[2].HasErrors);
            Assert.AreEqual(1, errors[2].FatalErrorCount);
            Assert.AreEqual(0, errors[2].WarningCount);
            Assert.AreEqual(0, errors[2].TempErrorCount);
            Assert.AreEqual(0, errors[2].CriticalTempErrorCount);
            Assert.AreEqual(95, errors[2].OkCount);
            Assert.AreEqual("2017-11-06T00:00:00+01:00", errors[2].Timestamp.ToIso8601Local());

            Assert.AreEqual(1, errors[3].ValueCount);
            Assert.AreEqual(0, errors[3].GapCount);
            Assert.IsFalse(errors[0].HasErrors);
            Assert.AreEqual(0, errors[3].FatalErrorCount);
            Assert.AreEqual(0, errors[3].WarningCount);
            Assert.AreEqual(0, errors[3].TempErrorCount);
            Assert.AreEqual(0, errors[3].CriticalTempErrorCount);
            Assert.AreEqual(1, errors[3].OkCount);
            Assert.AreEqual("2017-11-07T00:00:00+01:00", errors[3].Timestamp.ToIso8601Local());
        }
Exemple #3
0
        public void TestTaf1ExceptionToMuchTariffStages()
        {
            var deviceXml   = XDocument.Load(@"Data\result_1_month.xml");
            var deviceModel = XmlModelParser.ParseHanAdapterModel(deviceXml.Root.Descendants());

            var supplierXml   = XDocument.Load(@"Data\supplier_1_month_2_DayProfiles.xml");
            var supplierModel = XmlModelParser.ParseSupplierModel(supplierXml.Root.Descendants());

            var target = new TafAdapterTaf1();

            var ex = Assert.ThrowsException <InvalidOperationException>(() => target.Calculate(deviceModel, supplierModel));

            Assert.AreEqual("Die Anzahl der Tarifstufen darf die Anzahl der originären Messwertlisten nicht überschreiten.", ex.Message);
        }
Exemple #4
0
        public void TestTaf1ExceptionAMeterReadingIsNotAnOVL()
        {
            var deviceXml   = XDocument.Load(@"Data\result_1_month_1_ovl_1_meterReading.xml");
            var deviceModel = XmlModelParser.ParseHanAdapterModel(deviceXml.Root.Descendants());

            var supplierXml   = XDocument.Load(@"Data\supplier_1_month.xml");
            var supplierModel = XmlModelParser.ParseSupplierModel(supplierXml.Root.Descendants());

            var target = new TafAdapterTaf1();

            var ex = Assert.ThrowsException <InvalidOperationException>(() => target.Calculate(deviceModel, supplierModel));

            Assert.AreEqual("Es sind nur originäre Messwertlisten zulässig.", ex.Message);
        }
Exemple #5
0
        public void TestTaf1ExceptionTooManyOVL()
        {
            var deviceXml   = XDocument.Load(@"Data\result_1_month_4_ovl.xml");
            var deviceModel = XmlModelParser.ParseHanAdapterModel(deviceXml.Root.Descendants());

            var supplierXml   = XDocument.Load(@"Data\supplier_1_month.xml");
            var supplierModel = XmlModelParser.ParseSupplierModel(supplierXml.Root.Descendants());

            var target = new TafAdapterTaf1();

            var ex = Assert.ThrowsException <InvalidOperationException>(() => target.Calculate(deviceModel, supplierModel));

            Assert.AreEqual("Es werden maximal 3 originäre Messwertlisten unterstützt.", ex.Message);
        }
Exemple #6
0
        public void TestTaf1ExceptionEndValuePTBStatus4()
        {
            var deviceXml   = XDocument.Load(@"Data\result_1_month_end_statusPTB4.xml");
            var deviceModel = XmlModelParser.ParseHanAdapterModel(deviceXml.Root.Descendants());

            var supplierXml   = XDocument.Load(@"Data\supplier_1_month.xml");
            var supplierModel = XmlModelParser.ParseSupplierModel(supplierXml.Root.Descendants());

            var target = new TafAdapterTaf1();

            var end = supplierModel.AnalysisProfile.BillingPeriod.GetEnd();

            var ex = Assert.ThrowsException <InvalidOperationException>(() => target.Calculate(deviceModel, supplierModel));

            Assert.AreEqual($"Zu dem Zeitpunkt {end} ist kein Wert vorhanden oder der Status kritisch oder fatal.", ex.Message);
        }
Exemple #7
0
        public void TestTaf1ExceptionInvalidBillingPeriodStart()
        {
            var deviceXml   = XDocument.Load(@"Data\result_1_month.xml");
            var deviceModel = XmlModelParser.ParseHanAdapterModel(deviceXml.Root.Descendants());

            var supplierXml   = XDocument.Load(@"Data\supplier_1_month_start_at_10_2.xml");
            var supplierModel = XmlModelParser.ParseSupplierModel(supplierXml.Root.Descendants());

            var target = new TafAdapterTaf1();

            var start = supplierModel.AnalysisProfile.BillingPeriod.Start;

            var ex = Assert.ThrowsException <InvalidOperationException>(() => target.Calculate(deviceModel, supplierModel));

            Assert.AreEqual($"Die Abrechnungsperiode {start} startet nicht am Monatsanfang.", ex.Message);
        }
        public void TestOriginalValueListDupTimestamps()
        {
            var xml   = XDocument.Load(@"Data\oml_error_dup_timestamps.xml");
            var model = XmlModelParser.ParseHanAdapterModel(xml.Root.Descendants());

            var target = new OriginalValueList(model.MeterReadings[0], Kind.Electricity);

            Assert.AreEqual("1-0:1.8.0*255", target.Obis.ToString());
            Assert.AreEqual(0, target.GapCount);

            Assert.AreEqual(DateTime.Parse("2018-03-12T00:00:00+01:00"), target.Start);
            Assert.AreEqual(DateTime.Parse("2018-03-12T02:00:00+01:00"), target.End);

            var items = target.GetReadings(DateTime.MinValue, DateTime.MaxValue).ToList();

            Assert.AreEqual(9, items.Count);
        }
Exemple #9
0
        public void TestTaf1ExceptionInvalidSpecialDayProfilesCount()
        {
            var deviceXml   = XDocument.Load(@"Data\result_1_month.xml");
            var deviceModel = XmlModelParser.ParseHanAdapterModel(deviceXml.Root.Descendants());

            var supplierXml   = XDocument.Load(@"Data\supplier_1_month_plus_1_day.xml");
            var supplierModel = XmlModelParser.ParseSupplierModel(supplierXml.Root.Descendants());

            var target = new TafAdapterTaf1();

            var start = supplierModel.AnalysisProfile.BillingPeriod.Start;
            var end   = supplierModel.AnalysisProfile.BillingPeriod.GetEnd();
            var days  = (int)(end - start).TotalDays;

            var ex = Assert.ThrowsException <InvalidOperationException>(() => target.Calculate(deviceModel, supplierModel));

            Assert.AreEqual($"Die Anzahl der SpecialDayProfile Objekte muss einem vielfachen von { days} entsprechen.", ex.Message);
        }
Exemple #10
0
        public void TestTaf1ExceptionInvalidBillingPeriod2()
        {
            var deviceXml   = XDocument.Load(@"Data\result_1_month.xml");
            var deviceModel = XmlModelParser.ParseHanAdapterModel(deviceXml.Root.Descendants());

            var supplierXml   = XDocument.Load(@"Data\supplier_InvalidBillingPeriod2.xml");
            var supplierModel = XmlModelParser.ParseSupplierModel(supplierXml.Root.Descendants());

            var target = new TafAdapterTaf1();

            var start = supplierModel.AnalysisProfile.BillingPeriod.Start;
            var end   = supplierModel.AnalysisProfile.BillingPeriod.GetEnd();

            var ex = Assert.ThrowsException <InvalidOperationException>(() => target.Calculate(deviceModel, supplierModel));

            Assert.AreEqual($"Die angegebene Abrechnungsperiode von {(end - start).TotalDays} Tagen ist ungültigt. Unterstütz werden 1, 2, 3, 6 oder 12 Monate."
                            , ex.Message);
        }
        public void TestIsOriginalValueListStartNotAligned()
        {
            var xml   = XDocument.Load(@"Data\result_oml_start_not_aligned.xml");
            var model = XmlModelParser.ParseHanAdapterModel(xml.Root.Descendants());

            var target = new OriginalValueList(model.MeterReadings[0], Kind.Electricity);

            Assert.AreEqual("1-0:1.8.0*255", target.Obis.ToString());
            //Assert.AreEqual(3, target.GapCount);

            Assert.AreEqual(DateTime.Parse("2018-03-12T14:24:39+01:00"), target.Start);
            Assert.AreEqual(DateTime.Parse("2018-03-13T10:15:00+01:00"), target.End);

            var items = target.GetReadings(DateTime.MinValue, DateTime.MaxValue).ToList();

            Assert.AreEqual(83, items.Count);

            //Assert.AreEqual(DateTime.Parse("2017-11-29T17:09:00+01:00"), items[0].TimePeriod.Start);
        }
Exemple #12
0
        public void Test3Month()
        {
            var deviceXml   = XDocument.Load(@"Data\result_3_month.xml");
            var deviceModel = XmlModelParser.ParseHanAdapterModel(deviceXml.Root.Descendants());

            var supplierXml   = XDocument.Load(@"Data\supplier_3_month.xml");
            var supplierModel = XmlModelParser.ParseSupplierModel(supplierXml.Root.Descendants());

            var target = new TafAdapterTaf1();
            var result = target.Calculate(deviceModel, supplierModel);

            Assert.AreEqual("2017-08-01T00:00:00+02:00", result.Data.Begin.ToString("yyyy-MM-ddTHH:mm:ssK"));
            Assert.AreEqual("2017-11-01T00:00:00+01:00", result.Data.End.ToString("yyyy-MM-ddTHH:mm:ssK"));

            var data = result.Data as Taf1Data;

            Assert.AreEqual(1, data.SummaryRegister.Count);
            Assert.AreEqual("1-0:1.8.1*255", data.SummaryRegister[0].ObisCode.ToString());
            Assert.AreEqual(88360, data.SummaryRegister[0].Amount);
            Assert.AreEqual(1, data.SummaryRegister[0].TariffId);
        }
        public void TestIsOriginalValueListTaf7()
        {
            var xml   = XDocument.Load(@"Data\IF_Adapter_TRuDI_DatenTAF7.xml");
            var model = XmlModelParser.ParseHanAdapterModel(xml.Root.Descendants());

            var target = new OriginalValueList(model.MeterReadings[0], Kind.Electricity);

            Assert.AreEqual("1-0:1.8.0*255", target.Obis.ToString());
            Assert.AreEqual(0, target.GapCount);

            Assert.AreEqual(DateTime.Parse("2017-06-26T11:30:00+02:00"), target.Start);
            Assert.AreEqual(DateTime.Parse("2017-06-26T12:00:00+02:00"), target.End);

            var items = target.GetReadings(DateTime.MinValue, DateTime.MaxValue).ToList();

            Assert.AreEqual(3, items.Count);

            Assert.AreEqual(DateTime.Parse("2017-06-26T11:30:00+02:00"), items[0].TimePeriod.Start);
            Assert.AreEqual(DateTime.Parse("2017-06-26T11:45:00+02:00"), items[1].TimePeriod.Start);
            Assert.AreEqual(DateTime.Parse("2017-06-26T12:00:00+02:00"), items[2].TimePeriod.Start);
        }
        public void TestIsOriginalValueListGasZeroMeasurementPeriod()
        {
            var xml   = XDocument.Load(@"Data\result_oml_gas_0_period.xml");
            var model = XmlModelParser.ParseHanAdapterModel(xml.Root.Descendants());

            var target = new OriginalValueList(model.MeterReadings[0], Kind.Gas);

            Assert.AreEqual("7-0:3.1.0*255", target.Obis.ToString());
            Assert.AreEqual(3, target.GapCount);

            Assert.AreEqual(DateTime.Parse("2017-11-29T17:09:00+01:00"), target.Start);
            Assert.AreEqual(DateTime.Parse("2017-11-30T06:05:44+01:00"), target.End);

            var items = target.GetReadings(DateTime.MinValue, DateTime.MaxValue).ToList();

            Assert.AreEqual(4, items.Count);

            Assert.AreEqual(DateTime.Parse("2017-11-29T17:09:00+01:00"), items[0].TimePeriod.Start);
            Assert.AreEqual(DateTime.Parse("2017-11-30T00:04:46+01:00"), items[1].TimePeriod.Start);
            Assert.AreEqual(DateTime.Parse("2017-11-30T05:20:22+01:00"), items[2].TimePeriod.Start);
            Assert.AreEqual(DateTime.Parse("2017-11-30T06:05:44+01:00"), items[3].TimePeriod.Start);
        }
        public void TestIsOriginalValueListWinterToSummerTimeGap()
        {
            var xml   = XDocument.Load(@"Data\result_oml_winter_to_summer_time.xml");
            var model = XmlModelParser.ParseHanAdapterModel(xml.Root.Descendants());

            var target = new OriginalValueList(model.MeterReadings[0], Kind.Electricity);

            Assert.AreEqual("1-0:1.8.0*255", target.Obis.ToString());
            Assert.AreEqual(0, target.GapCount);

            Assert.AreEqual(DateTime.Parse("2017-03-26T00:00:00+01:00"), target.Start);
            Assert.AreEqual(DateTime.Parse("2017-03-26T06:00:00+02:00"), target.End);

            var items = target.GetReadings(DateTime.MinValue, DateTime.MaxValue).ToList();

            Assert.AreEqual(21, items.Count);

            Assert.AreEqual(DateTime.Parse("2017-03-26T00:00:00+01:00"), items[0].TimePeriod.Start);
            Assert.AreEqual(DateTime.Parse("2017-03-26T00:15:00+01:00"), items[1].TimePeriod.Start);
            Assert.AreEqual(DateTime.Parse("2017-03-26T00:30:00+01:00"), items[2].TimePeriod.Start);
            Assert.AreEqual(DateTime.Parse("2017-03-26T00:45:00+01:00"), items[3].TimePeriod.Start);
            Assert.AreEqual(DateTime.Parse("2017-03-26T01:00:00+01:00"), items[4].TimePeriod.Start);
            Assert.AreEqual(DateTime.Parse("2017-03-26T01:15:00+01:00"), items[5].TimePeriod.Start);
            Assert.AreEqual(DateTime.Parse("2017-03-26T01:30:00+01:00"), items[6].TimePeriod.Start);
            Assert.AreEqual(DateTime.Parse("2017-03-26T01:45:00+01:00"), items[7].TimePeriod.Start);
            Assert.AreEqual(DateTime.Parse("2017-03-26T03:00:00+02:00"), items[8].TimePeriod.Start);
            Assert.AreEqual(DateTime.Parse("2017-03-26T03:15:00+02:00"), items[9].TimePeriod.Start);
            Assert.AreEqual(DateTime.Parse("2017-03-26T03:30:00+02:00"), items[10].TimePeriod.Start);
            Assert.AreEqual(DateTime.Parse("2017-03-26T03:45:00+02:00"), items[11].TimePeriod.Start);
            Assert.AreEqual(DateTime.Parse("2017-03-26T04:00:00+02:00"), items[12].TimePeriod.Start);
            Assert.AreEqual(DateTime.Parse("2017-03-26T04:15:00+02:00"), items[13].TimePeriod.Start);
            Assert.AreEqual(DateTime.Parse("2017-03-26T04:30:00+02:00"), items[14].TimePeriod.Start);
            Assert.AreEqual(DateTime.Parse("2017-03-26T04:45:00+02:00"), items[15].TimePeriod.Start);
            Assert.AreEqual(DateTime.Parse("2017-03-26T05:00:00+02:00"), items[16].TimePeriod.Start);
            Assert.AreEqual(DateTime.Parse("2017-03-26T05:15:00+02:00"), items[17].TimePeriod.Start);
            Assert.AreEqual(DateTime.Parse("2017-03-26T05:30:00+02:00"), items[18].TimePeriod.Start);
            Assert.AreEqual(DateTime.Parse("2017-03-26T05:45:00+02:00"), items[19].TimePeriod.Start);
            Assert.AreEqual(DateTime.Parse("2017-03-26T06:00:00+02:00"), items[20].TimePeriod.Start);
        }
        public override int Run()
        {
            var connectResult = this.Connect();

            if (connectResult.error != null)
            {
                Console.WriteLine("Connect failed: {0}", connectResult.error);
                return(2);
            }

            var hanAdapter = this.CommonCommunicationConfiguration.HanAdapter;

            var contractsResult = hanAdapter.LoadAvailableContracts(
                this.CommonCommunicationConfiguration.CreateCancellationToken(),
                this.ProgressCallback).Result;

            if (contractsResult.error != null)
            {
                Console.WriteLine("LoadAvailableContracts failed: {0}", contractsResult.error);
                return(2);
            }

            var ctx = new AdapterContext();

            ctx.WithLogdata = true;

            ctx.Contract = contractsResult.contracts.FirstOrDefault(
                c =>
            {
                if (!string.IsNullOrWhiteSpace(this.loadDataConfiguration.UsagePointId))
                {
                    if (this.loadDataConfiguration.UsagePointId != c.MeteringPointId)
                    {
                        return(false);
                    }
                }

                if (this.loadDataConfiguration.UseTaf6 && c.TafId != TafId.Taf6)
                {
                    return(false);
                }

                return(this.loadDataConfiguration.TariffName == c.TafName);
            });

            if (ctx.Contract == null)
            {
                Console.WriteLine("Es wurde kein passender TAF gefunden.");
                return(2);
            }

            if (ctx.Contract.TafId != TafId.Taf7)
            {
                if (ctx.Contract.BillingPeriods == null || ctx.Contract.BillingPeriods.Count
                    <= this.loadDataConfiguration.BillingPeriodIndex)
                {
                    Console.WriteLine("Angegebene Abrechnungsperiode nicht gefunden.");
                    return(2);
                }

                ctx.BillingPeriod = ctx.Contract.BillingPeriods[this.loadDataConfiguration.BillingPeriodIndex];

                if (this.loadDataConfiguration.Start != null)
                {
                    ctx.Start = this.loadDataConfiguration.Start.Value;
                }
                else
                {
                    ctx.Start = ctx.BillingPeriod.Begin;
                }

                if (this.loadDataConfiguration.End != null)
                {
                    ctx.End = this.loadDataConfiguration.End.Value;
                }
                else if (ctx.BillingPeriod.End != null)
                {
                    ctx.End = ctx.BillingPeriod.End.Value;
                }
                else
                {
                    ctx.End = DateTime.Now;
                }
            }
            else
            {
                if (this.loadDataConfiguration.Start == null || this.loadDataConfiguration.End == null)
                {
                    Console.WriteLine("Bei TAF-7 muss ein Start- und End-Zeitpunkt angegeben werden.");
                    return(2);
                }

                ctx.Start = this.loadDataConfiguration.Start.Value;
                ctx.End   = this.loadDataConfiguration.End.Value;
            }

            var loadDataResult = hanAdapter.LoadData(
                ctx,
                this.CommonCommunicationConfiguration.CreateCancellationToken(),
                this.ProgressCallback).Result;


            if (loadDataResult.error != null)
            {
                Console.WriteLine("LoadData failed: {0}", loadDataResult.error);
                return(2);
            }

            try
            {
                if (this.loadDataConfiguration.SkipValidation)
                {
                    Ar2418Validation.ValidateSchema(loadDataResult.trudiXml);
                    var model = XmlModelParser.ParseHanAdapterModel(loadDataResult.trudiXml.Root?.Descendants());
                    ModelValidation.ValidateHanAdapterModel(model);
                    ContextValidation.ValidateContext(model, ctx);
                }
            }
            catch (AggregateException ex)
            {
                foreach (var err in ex.InnerExceptions)
                {
                    Console.WriteLine(err.Message);
                }

                return(2);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return(2);
            }

            if (string.IsNullOrWhiteSpace(this.CommonOptions.OutputFile))
            {
                return(0);
            }

            loadDataResult.trudiXml.Save(this.CommonOptions.OutputFile);
            return(0);
        }
        private void LoadDataFromXml(XDocument raw, AdapterContext ctx)
        {
            Log.Information("Loading XML file");
            this.LastErrorMessages.Clear();

            try
            {
                this.CurrentDataResult = new XmlDataResult {
                    Raw = raw
                };

                Log.Information("Validating XSD schema");
                Ar2418Validation.ValidateSchema(raw);

                Log.Information("Parsing model");
                this.CurrentDataResult.Model = XmlModelParser.ParseHanAdapterModel(this.CurrentDataResult?.Raw?.Root?.Descendants());

                Log.Information("Validating model");
                ModelValidation.ValidateHanAdapterModel(this.CurrentDataResult.Model);

                Log.Information("Validating model using the adapter context");
                ContextValidation.ValidateContext(this.CurrentDataResult.Model, ctx);

                if (this.CurrentSupplierFile?.Model != null)
                {
                    Log.Information("Validating model using supplier file model");
                    ContextValidation.ValidateContext(this.CurrentDataResult.Model, this.CurrentSupplierFile.Model, ctx);

                    Log.Information("Loading TAF adapter: {0}", this.CurrentSupplierFile.Model.AnalysisProfile.TariffUseCase);
                    var tafAdapter = TafAdapterRepository.LoadAdapter(this.CurrentSupplierFile.Model.AnalysisProfile.TariffUseCase);
                    this.CurrentSupplierFile.TafData = tafAdapter.Calculate(this.CurrentDataResult.Model, this.CurrentSupplierFile.Model);
                }
            }
            catch (UnknownTafAdapterException ex)
            {
                Log.Error(ex, "Unknown TAF adapter: {0}", ex.TafId);
                this.LastErrorMessages.Add($"Die Berechnung des Tarifanwendungsfall {ex.TafId} wird nicht unterstützt.");
                throw;
            }
            catch (AggregateException ex)
            {
                foreach (var err in ex.InnerExceptions)
                {
                    Log.Error(err, err.Message);
                    this.LastErrorMessages.Add(err.Message);
                }

                throw;
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Loading XML data failed: {0}", ex.Message);
                this.LastErrorMessages.Add(ex.Message);
                throw;
            }

            var originalValueLists =
                this.CurrentDataResult.Model.MeterReadings.Where(mr => mr.IsOriginalValueList()).Select(mr => new OriginalValueList(mr, this.CurrentDataResult.Model.ServiceCategory.Kind ?? Kind.Electricity)).ToList();

            var meterReadings = this.CurrentDataResult.Model.MeterReadings.Where(mr => !mr.IsOriginalValueList()).ToList();

            meterReadings.Sort((a, b) => string.Compare(a.ReadingType.ObisCode, b.ReadingType.ObisCode, StringComparison.InvariantCultureIgnoreCase));

            var ovlRegisters = originalValueLists.Where(ovl => ovl.MeterReading?.IntervalBlocks?.FirstOrDefault()?.Interval.Duration == 0).ToList();

            meterReadings.AddRange(ovlRegisters.Select(ovl => ovl.MeterReading));

            if (ovlRegisters.Count < originalValueLists.Count)
            {
                ovlRegisters.ForEach(ovl => originalValueLists.Remove(ovl));
            }

            foreach (var ovl in originalValueLists)
            {
                Log.Information("Original value list: meter: {0}, OBIS: {1}, {2} values", ovl.Meter, ovl.Obis, ovl.ValueCount);
            }

            foreach (var mr in meterReadings)
            {
                Log.Information("Meter reading: {@Meters}, OBIS: {1}", mr.Meters, mr.ReadingType.ObisCode);
            }

            this.CurrentDataResult.OriginalValueLists = originalValueLists;
            this.CurrentDataResult.MeterReadings      = meterReadings;
            this.CurrentDataResult.Begin = meterReadings.FirstOrDefault()?.IntervalBlocks?.FirstOrDefault()?.Interval?.Start;

            if (this.CurrentDataResult.Begin != null)
            {
                var duration = meterReadings.FirstOrDefault()?.IntervalBlocks?.FirstOrDefault()?.Interval?.Duration;
                if (duration != null)
                {
                    this.CurrentDataResult.End = this.CurrentDataResult.Begin + TimeSpan.FromSeconds(duration.Value);
                }
            }

            // If the analysis profile is missing, add it based on the contract info
            if (this.CurrentDataResult.Model.AnalysisProfile == null && ctx?.Contract != null)
            {
                this.AddAnalysisProfile(ctx);
            }
        }
        public void TestHistoricConsumption()
        {
            var xml   = XDocument.Load(@"Data\result_historic_consumption.xml");
            var model = XmlModelParser.ParseHanAdapterModel(xml.Root.Descendants());

            var target = new OriginalValueList(model.MeterReadings[0], Kind.Electricity);

            var values = target.HistoricValues;

            Assert.AreEqual(50, values.Count);
            CheckValue(values[0], "2019-12-31T00:00:00+01:00", "2020-01-01T00:00:00+01:00", 960, TimeUnit.Day);
            CheckValue(values[1], "2019-12-30T00:00:00+01:00", "2019-12-31T00:00:00+01:00", 960, TimeUnit.Day);
            CheckValue(values[2], "2019-12-29T00:00:00+01:00", "2019-12-30T00:00:00+01:00", 960, TimeUnit.Day);
            CheckValue(values[3], "2019-12-28T00:00:00+01:00", "2019-12-29T00:00:00+01:00", 960, TimeUnit.Day);
            CheckValue(values[4], "2019-12-27T00:00:00+01:00", "2019-12-28T00:00:00+01:00", 960, TimeUnit.Day);
            CheckValue(values[5], "2019-12-26T00:00:00+01:00", "2019-12-27T00:00:00+01:00", 960, TimeUnit.Day);
            CheckValue(values[6], "2019-12-25T00:00:00+01:00", "2019-12-26T00:00:00+01:00", 960, TimeUnit.Day);
            CheckValue(values[7], "2019-12-23T00:00:00+01:00", "2019-12-30T00:00:00+01:00", 6720, TimeUnit.Week);
            CheckValue(values[8], "2019-12-16T00:00:00+01:00", "2019-12-23T00:00:00+01:00", 6720, TimeUnit.Week);
            CheckValue(values[9], "2019-12-09T00:00:00+01:00", "2019-12-16T00:00:00+01:00", 6720, TimeUnit.Week);
            CheckValue(values[10], "2019-12-02T00:00:00+01:00", "2019-12-09T00:00:00+01:00", 6720, TimeUnit.Week);
            CheckValue(values[11], "2019-12-01T00:00:00+01:00", "2020-01-01T00:00:00+01:00", 29760, TimeUnit.Month);
            CheckValue(values[12], "2019-11-01T00:00:00+01:00", "2019-12-01T00:00:00+01:00", 28800, TimeUnit.Month);
            CheckValue(values[13], "2019-10-01T00:00:00+02:00", "2019-11-01T00:00:00+01:00", 29800, TimeUnit.Month);
            CheckValue(values[14], "2019-09-01T00:00:00+02:00", "2019-10-01T00:00:00+02:00", 28800, TimeUnit.Month);
            CheckValue(values[15], "2019-08-01T00:00:00+02:00", "2019-09-01T00:00:00+02:00", 29760, TimeUnit.Month);
            CheckValue(values[16], "2019-07-01T00:00:00+02:00", "2019-08-01T00:00:00+02:00", 29760, TimeUnit.Month);
            CheckValue(values[17], "2019-06-01T00:00:00+02:00", "2019-07-01T00:00:00+02:00", 28800, TimeUnit.Month);
            CheckValue(values[18], "2019-05-01T00:00:00+02:00", "2019-06-01T00:00:00+02:00", 29760, TimeUnit.Month);
            CheckValue(values[19], "2019-04-01T00:00:00+02:00", "2019-05-01T00:00:00+02:00", 28800, TimeUnit.Month);
            CheckValue(values[20], "2019-03-01T00:00:00+01:00", "2019-04-01T00:00:00+02:00", 29720, TimeUnit.Month);
            CheckValue(values[21], "2019-02-01T00:00:00+01:00", "2019-03-01T00:00:00+01:00", 26880, TimeUnit.Month);
            CheckValue(values[22], "2019-01-01T00:00:00+01:00", "2019-02-01T00:00:00+01:00", 29760, TimeUnit.Month);
            CheckValue(values[23], "2018-12-01T00:00:00+01:00", "2019-01-01T00:00:00+01:00", 29760, TimeUnit.Month);
            CheckValue(values[24], "2018-11-01T00:00:00+01:00", "2018-12-01T00:00:00+01:00", 28800, TimeUnit.Month);
            CheckValue(values[25], "2018-10-01T00:00:00+02:00", "2018-11-01T00:00:00+01:00", 29800, TimeUnit.Month);
            CheckValue(values[26], "2018-09-01T00:00:00+02:00", "2018-10-01T00:00:00+02:00", 28800, TimeUnit.Month);
            CheckValue(values[27], "2018-08-01T00:00:00+02:00", "2018-09-01T00:00:00+02:00", 29760, TimeUnit.Month);
            CheckValue(values[28], "2018-07-01T00:00:00+02:00", "2018-08-01T00:00:00+02:00", 29760, TimeUnit.Month);
            CheckValue(values[29], "2018-06-01T00:00:00+02:00", "2018-07-01T00:00:00+02:00", 28800, TimeUnit.Month);
            CheckValue(values[30], "2018-05-01T00:00:00+02:00", "2018-06-01T00:00:00+02:00", 29760, TimeUnit.Month);
            CheckValue(values[31], "2018-04-01T00:00:00+02:00", "2018-05-01T00:00:00+02:00", 28800, TimeUnit.Month);
            CheckValue(values[32], "2018-03-01T00:00:00+01:00", "2018-04-01T00:00:00+02:00", 29720, TimeUnit.Month);
            CheckValue(values[33], "2018-02-01T00:00:00+01:00", "2018-03-01T00:00:00+01:00", 26880, TimeUnit.Month);
            CheckValue(values[34], "2018-01-01T00:00:00+01:00", "2018-02-01T00:00:00+01:00", 29760, TimeUnit.Month);
            CheckValue(values[35], "2017-12-01T00:00:00+01:00", "2018-01-01T00:00:00+01:00", 29760, TimeUnit.Month);
            CheckValue(values[36], "2017-11-01T00:00:00+01:00", "2017-12-01T00:00:00+01:00", 28800, TimeUnit.Month);
            CheckValue(values[37], "2017-10-01T00:00:00+02:00", "2017-11-01T00:00:00+01:00", 29800, TimeUnit.Month);
            CheckValue(values[38], "2017-09-01T00:00:00+02:00", "2017-10-01T00:00:00+02:00", 28800, TimeUnit.Month);
            CheckValue(values[39], "2017-08-01T00:00:00+02:00", "2017-09-01T00:00:00+02:00", 29760, TimeUnit.Month);
            CheckValue(values[40], "2017-07-01T00:00:00+02:00", "2017-08-01T00:00:00+02:00", 29760, TimeUnit.Month);
            CheckValue(values[41], "2017-06-01T00:00:00+02:00", "2017-07-01T00:00:00+02:00", 28800, TimeUnit.Month);
            CheckValue(values[42], "2017-05-01T00:00:00+02:00", "2017-06-01T00:00:00+02:00", 29760, TimeUnit.Month);
            CheckValue(values[43], "2017-04-01T00:00:00+02:00", "2017-05-01T00:00:00+02:00", 28800, TimeUnit.Month);
            CheckValue(values[44], "2017-03-01T00:00:00+01:00", "2017-04-01T00:00:00+02:00", 29720, TimeUnit.Month);
            CheckValue(values[45], "2017-02-01T00:00:00+01:00", "2017-03-01T00:00:00+01:00", 26880, TimeUnit.Month);
            CheckValue(values[46], "2017-01-01T00:00:00+01:00", "2017-02-01T00:00:00+01:00", 29760, TimeUnit.Month);
            CheckValue(values[47], "2019-01-01T00:00:00+01:00", "2020-01-01T00:00:00+01:00", 350400, TimeUnit.Year);
            CheckValue(values[48], "2018-01-01T00:00:00+01:00", "2019-01-01T00:00:00+01:00", 350400, TimeUnit.Year);
            CheckValue(values[49], "2017-01-01T00:00:00+01:00", "2018-01-01T00:00:00+01:00", 350400, TimeUnit.Year);

            void CheckValue(HistoricConsumption item, string start, string end, long value, TimeUnit unitOfTime)
            {
                Assert.AreEqual(item.Value, value);
                Assert.AreEqual(item.Begin.ToIso8601Local(), start);
                Assert.AreEqual(item.End.ToIso8601Local(), end);
                Assert.AreEqual(item.UnitOfTime, unitOfTime);
            }
        }
        public override int Run()
        {
            var connectResult = this.Connect();

            if (connectResult.error != null)
            {
                Console.WriteLine("Connect failed: {0}", connectResult.error);
                return(2);
            }

            var hanAdapter = this.CommonCommunicationConfiguration.HanAdapter;

            var contractsResult = hanAdapter.LoadAvailableContracts(
                this.CommonCommunicationConfiguration.CreateCancellationToken(),
                this.ProgressCallback).Result;

            if (contractsResult.error != null)
            {
                Console.WriteLine("LoadAvailableContracts failed: {0}", contractsResult.error);
                return(2);
            }

            var contract = contractsResult.contracts.FirstOrDefault(
                c =>
            {
                if (!string.IsNullOrWhiteSpace(this.currentRegistersConfiguration.UsagePointId))
                {
                    if (this.currentRegistersConfiguration.UsagePointId != c.MeteringPointId)
                    {
                        return(false);
                    }
                }

                if (c.TafId == TafId.Taf6)
                {
                    return(false);
                }

                return(this.currentRegistersConfiguration.TariffName == c.TafName);
            });

            if (contract == null)
            {
                Console.WriteLine("Es wurde kein passender TAF gefunden.");
                return(2);
            }

            var currentRegisterResult = hanAdapter.GetCurrentRegisterValues(
                contract,
                this.CommonCommunicationConfiguration.CreateCancellationToken(),
                this.ProgressCallback).Result;


            if (currentRegisterResult.error != null)
            {
                Console.WriteLine("GetCurrentRegisterValues failed: {0}", currentRegisterResult.error);
                return(2);
            }

            try
            {
                if (this.currentRegistersConfiguration.SkipValidation)
                {
                    Ar2418Validation.ValidateSchema(currentRegisterResult.trudiXml);
                    var model = XmlModelParser.ParseHanAdapterModel(currentRegisterResult.trudiXml.Root?.Descendants());
                    ModelValidation.ValidateHanAdapterModel(model);
                    ContextValidation.ValidateContext(model, null);
                }
            }
            catch (AggregateException ex)
            {
                foreach (var err in ex.InnerExceptions)
                {
                    Console.WriteLine(err.Message);
                }

                return(2);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return(2);
            }

            if (string.IsNullOrWhiteSpace(this.CommonOptions.OutputFile))
            {
                return(0);
            }

            currentRegisterResult.trudiXml.Save(this.CommonOptions.OutputFile);
            return(0);
        }
        public void TestIsOriginalValueListTaf7WithGaps()
        {
            var xml   = XDocument.Load(@"Data\IF_Adapter_TRuDI_DatenTAF7_With_Gaps.xml");
            var model = XmlModelParser.ParseHanAdapterModel(xml.Root.Descendants());

            var target = new OriginalValueList(model.MeterReadings[0], Kind.Electricity);

            Assert.AreEqual("1-0:1.8.0*255", target.Obis.ToString());
            Assert.AreEqual(3, target.GapCount);

            Assert.AreEqual(DateTime.Parse("2017-06-26T11:30:00+02:00"), target.Start);
            Assert.AreEqual(DateTime.Parse("2017-06-26T15:15:00+02:00"), target.End);

            // Get only 2 items
            var items = target.GetReadings(DateTime.Parse("2017-06-26T11:45:00+02:00"), DateTime.Parse("2017-06-26T12:00:00+02:00")).ToList();

            Assert.AreEqual(2, items.Count);

            Assert.AreEqual(DateTime.Parse("2017-06-26T11:45:00+02:00"), items[0].TimePeriod.Start);
            Assert.IsNotNull(items[0].Value);

            Assert.AreEqual(DateTime.Parse("2017-06-26T12:00:00+02:00"), items[1].TimePeriod.Start);
            Assert.IsNotNull(items[1].Value);


            // Get all items
            items = target.GetReadings(DateTime.MinValue, DateTime.MaxValue).ToList();
            Assert.AreEqual(16, items.Count);

            Assert.AreEqual(DateTime.Parse("2017-06-26T11:30:00+02:00"), items[0].TimePeriod.Start);
            Assert.IsNotNull(items[0].Value);

            Assert.AreEqual(DateTime.Parse("2017-06-26T11:45:00+02:00"), items[1].TimePeriod.Start);
            Assert.IsNotNull(items[1].Value);

            Assert.AreEqual(DateTime.Parse("2017-06-26T12:00:00+02:00"), items[2].TimePeriod.Start);
            Assert.IsNotNull(items[2].Value);

            Assert.AreEqual(DateTime.Parse("2017-06-26T12:15:00+02:00"), items[3].TimePeriod.Start);
            Assert.IsNull(items[3].Value);

            Assert.AreEqual(DateTime.Parse("2017-06-26T12:30:00+02:00"), items[4].TimePeriod.Start);
            Assert.IsNotNull(items[4].Value);

            Assert.AreEqual(DateTime.Parse("2017-06-26T12:45:00+02:00"), items[5].TimePeriod.Start);
            Assert.IsNotNull(items[5].Value);

            Assert.AreEqual(DateTime.Parse("2017-06-26T13:00:00+02:00"), items[6].TimePeriod.Start);
            Assert.IsNotNull(items[6].Value);

            Assert.AreEqual(DateTime.Parse("2017-06-26T13:15:00+02:00"), items[7].TimePeriod.Start);
            Assert.IsNull(items[7].Value);

            Assert.AreEqual(DateTime.Parse("2017-06-26T13:30:00+02:00"), items[8].TimePeriod.Start);
            Assert.IsNull(items[8].Value);

            Assert.AreEqual(DateTime.Parse("2017-06-26T13:45:00+02:00"), items[9].TimePeriod.Start);
            Assert.IsNotNull(items[9].Value);

            Assert.AreEqual(DateTime.Parse("2017-06-26T14:00:00+02:00"), items[10].TimePeriod.Start);
            Assert.IsNull(items[10].Value);

            Assert.AreEqual(DateTime.Parse("2017-06-26T14:15:00+02:00"), items[11].TimePeriod.Start);
            Assert.IsNull(items[11].Value);

            Assert.AreEqual(DateTime.Parse("2017-06-26T14:30:00+02:00"), items[12].TimePeriod.Start);
            Assert.IsNull(items[12].Value);

            Assert.AreEqual(DateTime.Parse("2017-06-26T14:45:00+02:00"), items[13].TimePeriod.Start);
            Assert.IsNull(items[13].Value);

            Assert.AreEqual(DateTime.Parse("2017-06-26T15:00:00+02:00"), items[14].TimePeriod.Start);
            Assert.IsNotNull(items[14].Value);

            Assert.AreEqual(DateTime.Parse("2017-06-26T15:15:00+02:00"), items[15].TimePeriod.Start);
            Assert.IsNotNull(items[15].Value);

            // Get only gap items
            items = target.GetReadings(DateTime.Parse("2017-06-26T14:15:00+02:00"), DateTime.Parse("2017-06-26T14:30:00+02:00")).ToList();
            Assert.AreEqual(2, items.Count);

            Assert.AreEqual(DateTime.Parse("2017-06-26T14:15:00+02:00"), items[0].TimePeriod.Start);
            Assert.IsNull(items[0].Value);

            Assert.AreEqual(DateTime.Parse("2017-06-26T14:30:00+02:00"), items[1].TimePeriod.Start);
            Assert.IsNull(items[1].Value);

            // Get items with gap at beginn
            items = target.GetReadings(DateTime.Parse("2017-06-26T14:45:00+02:00"), DateTime.Parse("2017-06-26T15:15:00+02:00")).ToList();
            Assert.AreEqual(3, items.Count);

            Assert.AreEqual(DateTime.Parse("2017-06-26T14:45:00+02:00"), items[0].TimePeriod.Start);
            Assert.IsNull(items[0].Value);

            Assert.AreEqual(DateTime.Parse("2017-06-26T15:00:00+02:00"), items[1].TimePeriod.Start);
            Assert.IsNotNull(items[1].Value);

            Assert.AreEqual(DateTime.Parse("2017-06-26T15:15:00+02:00"), items[2].TimePeriod.Start);
            Assert.IsNotNull(items[2].Value);

            // Get items with gap at end
            items = target.GetReadings(DateTime.Parse("2017-06-26T13:45:00+02:00"), DateTime.Parse("2017-06-26T14:15:00+02:00")).ToList();
            Assert.AreEqual(3, items.Count);

            Assert.AreEqual(DateTime.Parse("2017-06-26T13:45:00+02:00"), items[0].TimePeriod.Start);
            Assert.IsNotNull(items[0].Value);

            Assert.AreEqual(DateTime.Parse("2017-06-26T14:00:00+02:00"), items[1].TimePeriod.Start);
            Assert.IsNull(items[1].Value);

            Assert.AreEqual(DateTime.Parse("2017-06-26T14:15:00+02:00"), items[2].TimePeriod.Start);
            Assert.IsNull(items[2].Value);
        }