private void MakeAbregelungWorksheet([NotNull] ScenarioSliceParameters slice, double maxDailyGen,
                                             [NotNull] Profile addedProfile)
        {
            RowCollection rc = new RowCollection("effect", "Effekt");

            for (double i = 0; i < 1; i += 0.01)
            {
                double storageSize = maxDailyGen * 2;
                var    minimzed    = ProfileSmoothing.FindBestPowerReductionRatio(addedProfile,
                                                                                  storageSize,
                                                                                  out var _,
                                                                                  out var reductionFactor, i);
                double friendlySize = storageSize / Constants.GWhFactor;
                Info("Size: " + i + " " + friendlySize + " gwh, Reduction factor: " + reductionFactor);
                RowBuilder rb = RowBuilder.Start("Size", friendlySize);
                rb.Add("storage", storageSize);
                rb.Add("ReductionFactor", reductionFactor);
                rb.Add("Capping", i);
                rb.Add("Max Power", minimzed.MaxPower() / 1000);
                rb.Add("Min Power", minimzed.MinPower() / 1000);
                rc.Add(rb);
            }

            var fnFactor = MakeAndRegisterFullFilename("CappingImpact.xlsx", slice);

            XlsxDumper.WriteToXlsx(fnFactor, rc);
            SaveToPublicationDirectory(fnFactor, slice, "4.5");
        }
        protected override void RunActualProcess()
        {
            var           dbRaw   = Services.SqlConnectionPreparer.GetDatabaseConnection(Stage.Raw, Constants.PresentSlice);
            var           dbHouse = Services.SqlConnectionPreparer.GetDatabaseConnection(Stage.Houses, Constants.PresentSlice);
            var           houses  = dbHouse.Fetch <House>();
            var           ebbe    = dbRaw.Fetch <EnergiebedarfsdatenBern>();
            RowCollection rc      = new RowCollection("Analysis", "Analysis");

            foreach (var house in houses)
            {
                RowBuilder rb       = RowBuilder.Start("House", house.ComplexName);
                var        ebbedata = ebbe.Where(x => house.EGIDs.Contains((int)x.egid)).ToList();
                foreach (var ebbeSet in ebbedata)
                {
                    ebbe.Remove(ebbeSet);
                }

                rb.Add("Ebbe", JsonConvert.SerializeObject(ebbedata));
                rc.Add(rb);
            }

            foreach (var ebbeset in ebbe)
            {
                RowBuilder rb = RowBuilder.Start("Ebbe eGid", ebbeset.egid);
                rb.Add("Ebbe", JsonConvert.SerializeObject(ebbeset));
                rc.Add(rb);
            }

            var fn = MakeAndRegisterFullFilename("HeatingSystemAnalysis.xlsx", Constants.PresentSlice);

            XlsxDumper.WriteToXlsx(fn, rc);
        }
        private void WriteProfilesToExcel([NotNull] Profile temperaturProfile,
                                          [NotNull] Profile houseEnergy,
                                          [NotNull] Profile heatPumpEnergysupply,
                                          [NotNull] string file)
        {
            //dump to csv
            RowCollection rc = new RowCollection("sheet1", "Sheet1");
            DateTime      dt = new DateTime(2017, 1, 1);

            for (int i = 0; i < 35040; i++)
            {
                RowBuilder rb = RowBuilder.Start("Idx", i);
                rb.Add("Time", dt.ToShortDateString() + " " + dt.ToShortTimeString());
                dt = dt.AddMinutes(15);
                rb.Add(temperaturProfile.Name, temperaturProfile.Values[i]);
                rb.Add(houseEnergy.Name, houseEnergy.Values[i]);
                rb.Add(heatPumpEnergysupply.Name, heatPumpEnergysupply.Values[i]);
                rc.Add(rb);
            }

            var           fn = Path.Combine(Config.Directories.UnitTestingDirectory, nameof(HeatPumpTest), file);
            FileInfo      fi = new FileInfo(fn);
            DirectoryInfo di = fi.Directory;

            if (di == null)
            {
                throw new FlaException("No path");
            }

            if (!di.Exists)
            {
                di.Create();
            }

            XlsxDumper.WriteToXlsx(fn, rc);
            Info("Wrote results to " + fn);
            Process.Start(di.FullName);
        }
Exemplo n.º 4
0
        protected override void RunActualProcess([NotNull] ScenarioSliceParameters slice)
        {
            if (!Services.RunningConfig.MakeHouseSums)
            {
                return;
            }

            var presentSums      = GetEnergySumPerHouseForThePresent();
            var energySums       = GetPlannedEnergySumPerHouseForScenario(slice);
            var energyInProfiles = GetEnergyInProfiles(slice);

            RowCollection rc = new RowCollection("Comparison", "Comparison");

            rc.ColumnsToSum.Add("Summe Gegenwart");
            rc.ColumnsToSum.Add("Summe Haus Collection");
            rc.ColumnsToSum.Add("Summe Profile");
            rc.SumDivisionFactor = 1_000_000;
            presentSums.Sort((x, y) => y.Energy.CompareTo(x.Energy));
            foreach (var presentSum in presentSums)
            {
                RowBuilder rb = RowBuilder.Start("Hausname", presentSum.HouseName);
                rb.Add("Summe Gegenwart", presentSum.Energy);
                rb.Add("Summe Haus Collection", energySums.Single(x => x.HouseName == presentSum.HouseName).Energy);
                var profile = energyInProfiles.FirstOrDefault(x => x.HouseName == presentSum.HouseName);
                if (profile != null)
                {
                    rb.Add("Summe Profile", profile.Energy);
                }

                rc.Add(rb);
            }

            var fn = MakeAndRegisterFullFilename("EnergyComparison.xlsx", slice);

            XlsxDumper.WriteToXlsx(fn, rc);
            SaveToArchiveDirectory(fn, RelativeDirectory.Report, slice);
        }
Exemplo n.º 5
0
        private void WriteSumLine([NotNull][ItemNotNull] List <CSVFile> csvs1, [NotNull] ScenarioSliceParameters slice)
        {
            if (slice.DstYear != 2050 && slice.SmartGridEnabled)
            {
                return;
            }

            string        suffix = csvs1[0].GenerationOrLoad.ToString().ToLower();
            var           fn     = MakeAndRegisterFullFilename("SummedProfilePerTrafokreis." + suffix + ".csv", slice);
            RowCollection rc     = new RowCollection("Sheet1", "Sheet1");

            using (StreamWriter sumfile = new StreamWriter(fn)) {
                Info("writing " + csvs1.Count + " sum lines for " + suffix);
                foreach (var csv in csvs1)
                {
                    double[] arr = new double[35040];
                    foreach (var line in csv.Lines)
                    {
                        for (int i = 0; i < 35040; i++)
                        {
                            arr[i] += line.Values[i];
                        }
                    }

                    Profile    p  = new Profile(csv.FileName ?? throw new InvalidOperationException(), arr.ToList().AsReadOnly(), EnergyOrPower.Energy);
                    RowBuilder rb = RowBuilder.Start("Name", csv.FileName);
                    rb.Add("Value", p.EnergySum());
                    rc.Add(rb);
                    sumfile.WriteLine(csv.FileName + ";" + p.GetCSVLine());
                }

                sumfile.Close();
            }

            var xlsfn = MakeAndRegisterFullFilename("SumsPerTrafokreis." + suffix + ".xlsx", slice);

            XlsxDumper.WriteToXlsx(xlsfn, rc);
            SaveToArchiveDirectory(fn, RelativeDirectory.Trafokreise, slice);
            SaveToArchiveDirectory(xlsfn, RelativeDirectory.Report, slice);
        }
Exemplo n.º 6
0
 protected override void SetAdditionalFieldsForRow([NotNull] RowBuilder rb)
 {
     rb.Add("Name", Name);
     rb.Add("Trafokreis", Trafokreis);
 }
Exemplo n.º 7
0
 protected override void SetAdditionalFieldsForRow([NotNull] RowBuilder rb)
 {
     rb.Add("Name", Name).Add("ProfileType", EnergyOrPower).Add("ValueCount", Values.Count).Add("EnergySum", Values.Sum());
 }
        public static RowCollection MakeRowCollectionForSingleSheet <T>(int year, int timeStepWidthInMinutes, [NotNull] IValueProvider wsc)
        {
            //dump to csv
            RowCollection rc          = new RowCollection(wsc.SheetName, wsc.YAxisName);
            DateTime      dt          = new DateTime(year, 1, 1);
            int           columnCount = wsc.GetColumnCount();
            List <ReadOnlyCollection <T> > columns = new List <ReadOnlyCollection <T> >();

            for (int i = 0; i < columnCount; i++)
            {
                columns.Add(wsc.GetValues <T>(i));
            }

            int maxProfileCount = columns.Max(x => x.Count);
            var names           = wsc.GetColumnNames();

            if (names.Count != names.Distinct().Count())
            {
                string s = "";
                foreach (var name in names)
                {
                    var count = names.Count(x => x == name);
                    if (count > 1)
                    {
                        s += name + ": " + count + "\n";
                    }
                }

                throw new FlaException("Profile names need to be unique:" + s);
            }

            if (wsc.GetColumnCount() == 0)
            {
                throw new FlaException("no profiles");
            }

            foreach (var profile in columns)
            {
                if (profile.Count == 0)
                {
                    throw new FlaException("no values in profile");
                }
            }

            for (int row = 0; row < maxProfileCount; row++)
            {
                RowBuilder rb = RowBuilder.Start("Idx", row);
                rc.Add(rb);
                rb.Add("Time", dt.ToString("ddd, dd.MM.yyyy") + "\n" + dt.ToString("HH:mm"));
                if (row > 5)
                {
                    rb.Add("Time (date only)", dt.ToString("dd.MM.yyyy"));
                }
                else
                {
                    rb.Add("Time (date only)", null);
                }

                dt = dt.AddMinutes(timeStepWidthInMinutes);
                for (int col = 0; col < columnCount; col++)
                {
                    if (columns[col].Count > row)
                    {
                        rb.Add(names[col], columns[col][row]);
                    }
                }
            }

            return(rc);
        }
Exemplo n.º 9
0
        protected override void RunActualProcess(ScenarioSliceParameters slice)
        {
            var dbProfileExport = Services.SqlConnectionPreparer.GetDatabaseConnection(Stage.ProfileGeneration, slice, DatabaseCode.HouseProfiles);
            var saLoad          = SaveableEntry <Prosumer> .GetSaveableEntry(dbProfileExport, SaveableEntryTableType.HouseLoad, Services.Logger);

            var saGeneration = SaveableEntry <Prosumer> .GetSaveableEntry(dbProfileExport, SaveableEntryTableType.HouseGeneration, Services.Logger);

            var dbArchiving = Services.SqlConnectionPreparer.GetDatabaseConnection(Stage.ProfileAnalysis, slice, DatabaseCode.Smartgrid);

            dbArchiving.RecreateTable <SmartGridInformation>();
            var saArchiveEntry = SaveableEntry <ArchiveEntry> .GetSaveableEntry(dbArchiving, SaveableEntryTableType.Smartgrid, Services.Logger);

            int count      = 0;
            var smartSlice = slice.CopyThisSlice();

            smartSlice.SmartGridEnabled = true;
            RowCollection prosumerCollection = new RowCollection("Prosumers", "Prosumers");
            Stopwatch     sw      = Stopwatch.StartNew();
            const string  tkfield = "Trafokreis";
            Stopwatch     swIdx   = Stopwatch.StartNew();

            saLoad.CreateIndexIfNotExists(tkfield);
            saGeneration.CreateIndexIfNotExists(tkfield);
            Info("Creating the index took " + swIdx.Elapsed);
            var trafos = saLoad.SelectSingleDistinctField <string>(tkfield);

            Info("Reading trafokreise took " + sw.Elapsed);
            Dictionary <string, Profile> trafokreiseLoad       = new Dictionary <string, Profile>();
            Dictionary <string, Profile> trafokreiseGeneration = new Dictionary <string, Profile>();
            ChangableProfile             cityload       = ChangableProfile.FromProfile(Profile.MakeConstantProfile(0, "Sum", Profile.ProfileResolution.QuarterHour));
            ChangableProfile             cityGeneration =
                ChangableProfile.FromProfile(Profile.MakeConstantProfile(0, "Sum", Profile.ProfileResolution.QuarterHour));
            ChangableProfile smartCityLoad =
                ChangableProfile.FromProfile(Profile.MakeConstantProfile(0, "Sum", Profile.ProfileResolution.QuarterHour));
            ChangableProfile smartCityGeneration =
                ChangableProfile.FromProfile(Profile.MakeConstantProfile(0, "Sum", Profile.ProfileResolution.QuarterHour));
            RowCollection        smartGridPointValues = new RowCollection("SmartGridHASummaries", "SmartGridHASummaries");
            SmartGridInformation smartGridInformation = new SmartGridInformation();

            foreach (var trafo in trafos)
            {
                //if (count > 500) {
                //continue;
                //}
                Dictionary <string, List <Prosumer> > prosumersByHa = new Dictionary <string, List <Prosumer> >();
                ChangableProfile trafoLoadSum =
                    ChangableProfile.FromProfile(Profile.MakeConstantProfile(0, "Sum", Profile.ProfileResolution.QuarterHour));
                foreach (var prosumer in saLoad.ReadSubsetOfTableDBAsEnumerable(tkfield, trafo))
                {
                    RowBuilder rb = RowBuilder.Start("Name", prosumer.Name);
                    rb.Add("Energy", prosumer.Profile?.EnergySum());
                    rb.Add("HA", prosumer.HausanschlussKey);
                    rb.Add("Trafokreis", prosumer.TrafoKreis);
                    prosumerCollection.Add(rb);
                    count++;
                    if (count % 50 == 0)
                    {
                        Info("Processing Prosumers Load: " + count + " " + sw.Elapsed);
                    }

                    if (!string.IsNullOrWhiteSpace(prosumer.HausanschlussKey))
                    {
                        if (!prosumersByHa.ContainsKey(prosumer.HausanschlussKey))
                        {
                            prosumersByHa.Add(prosumer.HausanschlussKey, new List <Prosumer>());
                        }

                        prosumersByHa[prosumer.HausanschlussKey].Add(prosumer);
                    }

                    trafoLoadSum.Add(prosumer.Profile ?? throw new FlaException("empty profile"));
                }

                AnalysisKey  keyload = new AnalysisKey(trafo, null, SumType.ByTrafokreis, GenerationOrLoad.Load, null, null, null);
                ArchiveEntry aeload  = new ArchiveEntry("Trafokreis " + trafo, keyload, trafoLoadSum.ToProfile(), GenerationOrLoad.Load, trafo);
                saArchiveEntry.AddRow(aeload);

                trafokreiseLoad.Add(trafo, trafoLoadSum.ToProfile());
                var trafoGenerationSum = Profile.MakeConstantProfile(0, "Sum", Profile.ProfileResolution.QuarterHour);
                foreach (var prosumer in saGeneration.ReadSubsetOfTableDBAsEnumerable(tkfield, trafo))
                {
                    RowBuilder rb = RowBuilder.Start("Name", prosumer.Name);
                    rb.Add("Energy", prosumer.Profile?.EnergySum());
                    rb.Add("HA", prosumer.HausanschlussKey);
                    rb.Add("Trafokreis", prosumer.TrafoKreis);
                    prosumerCollection.Add(rb);
                    if (count % 50 == 0)
                    {
                        Info("Processing Prosumers Generation: " + count + " " + sw.Elapsed);
                    }

                    if (!string.IsNullOrWhiteSpace(prosumer.HausanschlussKey))
                    {
                        if (!prosumersByHa.ContainsKey(prosumer.HausanschlussKey))
                        {
                            prosumersByHa.Add(prosumer.HausanschlussKey, new List <Prosumer>());
                        }

                        prosumersByHa[prosumer.HausanschlussKey].Add(prosumer);
                    }

                    //var powerLimited = prosumer.Profile?.LimitToPercentageOfMax(0.5)?? throw new FlaException("blub");
                    //if(powerLimited.Values.Count ==0) { throw new FlaException("huch?");}
                    trafoGenerationSum = trafoGenerationSum.Add(prosumer.Profile ?? throw new FlaException(), "Sum");
                }

                AnalysisKey  key = new AnalysisKey(trafo, null, SumType.ByTrafokreis, GenerationOrLoad.Generation, null, null, null);
                ArchiveEntry ae  = new ArchiveEntry("Trafokreis " + trafo, key, trafoGenerationSum, GenerationOrLoad.Generation, trafo);
                saArchiveEntry.AddRow(ae);
                trafokreiseGeneration.Add(trafo, trafoGenerationSum);
                cityload.Add(trafoLoadSum);
                cityGeneration.Add(trafoGenerationSum);
                //if (count > 16000) {
                ApplySmartGridstuff(prosumersByHa, trafo, smartCityLoad, smartCityGeneration, smartGridPointValues, smartGridInformation, smartSlice);
                //}
            }

            var addedSmart       = smartCityLoad.ToProfile().Add(smartCityGeneration.ToProfile(), "Netto-Last (smart)");
            var addedSerializeFn = MakeAndRegisterFullFilename("addedProfile.lz4", slice);

            dbArchiving.BeginTransaction();
            dbArchiving.Save(smartGridInformation);
            dbArchiving.CompleteTransaction();
            SaveCityProfile(cityload, saArchiveEntry, SummedLoadType.CityLoad, GenerationOrLoad.Load);
            SaveCityProfile(cityGeneration, saArchiveEntry, SummedLoadType.CityGeneration, GenerationOrLoad.Generation);
            SaveCityProfile(smartCityGeneration, saArchiveEntry, SummedLoadType.SmartCityGeneration, GenerationOrLoad.Generation);
            SaveCityProfile(smartCityLoad, saArchiveEntry, SummedLoadType.SmartCityLoad, GenerationOrLoad.Load);
            saArchiveEntry.MakeCleanTableForListOfFields(false);
            saArchiveEntry.SaveDictionaryToDatabase(MyLogger);

            FileStream fs     = new FileStream(addedSerializeFn, FileMode.Create);
            var        added  = cityload.ToProfile().Subtract(cityGeneration.ToProfile(), "Netto-Last (konventionell)");
            var        lz4Arr = LZ4MessagePackSerializer.Serialize(added);

            fs.Write(lz4Arr, 0, lz4Arr.Length);
            fs.Close();
            MakePlotlyTrafostationBoxPlots("Boxplot_Load_OhneMV.html", trafokreiseLoad, slice, true);
            MakePlotlyTrafostationBoxPlots("Boxplot_Gen_OhneMV.html", trafokreiseGeneration, slice, true);

            var fn = MakeAndRegisterFullFilename("ProsumerDump.xlsx", slice);

            XlsxDumper.DumpProfilesToExcel(fn,
                                           slice.DstYear,
                                           15,
                                           new RowWorksheetContent(prosumerCollection),
                                           new RowWorksheetContent(smartGridPointValues));
            var           fnProf             = MakeAndRegisterFullFilename("SmartGridProfiles_distributedStorage.xlsx", slice);
            RowCollection rc                 = new RowCollection("StatusInfo", "Status");
            double        avgReductionFactor = smartGridInformation.SummedReductionFactor / smartGridInformation.NumberOfReductionFactors;

            rc.Add(RowBuilder.Start("Total storage size", smartGridInformation.TotalStorageSize)
                   .Add("Number of Prosumers", smartGridInformation.NumberOfProsumers)
                   .Add("Citywide Reduction", avgReductionFactor)
                   .Add("MinimumLoadBefore", added.MinPower())
                   .Add("MinLoadSmart", addedSmart.MinPower())
                   .Add("MaxLoadBefore", added.MaxPower())
                   .Add("MaxLoadSmart", addedSmart.MaxPower())
                   );

            XlsxDumper.DumpProfilesToExcel(fnProf,
                                           slice.DstYear,
                                           15,
                                           new RowWorksheetContent(rc),
                                           new ProfileWorksheetContent("load", "Last [MW]", 240, cityload.ToProfile()),
                                           new ProfileWorksheetContent("generation", "Erzeugung [MW]", 240, cityGeneration.ToProfile()),
                                           new ProfileWorksheetContent("added", "Netto-Last [kW]", 240, added),
                                           new ProfileWorksheetContent("smartload", "Last (smart) [MW]", 240, smartCityLoad.ToProfile()),
                                           new ProfileWorksheetContent("smartgeneration", "Erzeugung (smart) [MW]", 240, smartCityGeneration.ToProfile()),
                                           new ProfileWorksheetContent("smartadded", "Netto-Last [kW]", 240, added, addedSmart));
            SaveToArchiveDirectory(fnProf, RelativeDirectory.Report, smartSlice);
            SaveToPublicationDirectory(fnProf, slice, "4.5");
            SaveToPublicationDirectory(fnProf, slice, "5");
        }
        private void MakeStorageSizeSheet([NotNull] ScenarioSliceParameters slice, double maxDailyGen,
                                          [NotNull] Profile addedProfile)
        {
            RowCollection rc = new RowCollection("effect", "Effekt");

            for (double i = 0; i < 10; i += 0.1)
            {
                double storageSize = maxDailyGen * i;
                var    minimzed    = ProfileSmoothing.FindBestPowerReductionRatio(addedProfile,
                                                                                  storageSize,
                                                                                  out var _,
                                                                                  out var reductionFactor, 1);
                var minimzed2 = ProfileSmoothing.FindBestPowerReductionRatio(addedProfile,
                                                                             storageSize,
                                                                             out var _,
                                                                             out var reductionFactor2, 0.5);
                double friendlySize = storageSize / Constants.GWhFactor;
                Info("Size: " + i + " " + friendlySize + " gwh, Reduction factor: " + reductionFactor);
                RowBuilder rb = RowBuilder.Start("Size", friendlySize);
                rb.Add("DaySize", i);
                rb.Add("ReductionFactor", reductionFactor);
                rb.Add("Max Power", minimzed.MaxPower() / 1000);
                rb.Add("Min Power", minimzed.MinPower() / 1000);
                rb.Add("Energy", minimzed.EnergySum() / 1000000);
                rb.Add("EnergyFromGrid", minimzed.GetOnlyPositive("pos").EnergySum() / 1000000);
                rb.Add("EnergyToGrid", minimzed.GetOnlyNegative("neg").EnergySum() / 1000000);
                rb.Add("ReductionFactor Curtailed", reductionFactor2);
                rb.Add("Max Power Curtailed", minimzed2.MaxPower() / 1000);
                rb.Add("Min Power Curtailed", minimzed2.MinPower() / 1000);
                rb.Add("Energy Curtailed", minimzed2.EnergySum() / 1000000);
                rb.Add("EnergyFromGrid Curtailed", minimzed2.GetOnlyPositive("pos").EnergySum() / 1000000);
                rb.Add("EnergyToGrid Curtailed", minimzed2.GetOnlyNegative("neg").EnergySum() / 1000000);
                rc.Add(rb);
            }

            var fnFactor = MakeAndRegisterFullFilename("BatterySizeImpact.xlsx", slice);

            XlsxDumper.WriteToXlsx(fnFactor, rc);
            SaveToPublicationDirectory(fnFactor, slice, "4.5");
        }
        protected override void RunActualProcess(ScenarioSliceParameters slice)
        {
            if (!slice.Equals(Constants.PresentSlice))
            {
                return;
            }

            var dbHouses = Services.SqlConnectionPreparer.GetDatabaseConnection(Stage.Houses, slice);

            Info("using house db in  " + dbHouses.ConnectionString);
            var houses = dbHouses.Fetch <House>();
            HouseComponentRepository hcr = new HouseComponentRepository(dbHouses);
            var hausanschlusses          = dbHouses.Fetch <Hausanschluss>();
            var dbRaw                   = Services.SqlConnectionPreparer.GetDatabaseConnection(Stage.Raw, Constants.PresentSlice);
            var suppIsn                 = dbRaw.Fetch <HausanschlussImportSupplement>();
            var standortDict            = new Dictionary <string, string>();
            var rlms                    = dbRaw.Fetch <RlmProfile>();
            List <AssignmentEntry> ases = new List <AssignmentEntry>();

            foreach (var supplement in suppIsn)
            {
                if (!string.IsNullOrWhiteSpace(supplement.TargetStandort))
                {
                    if (standortDict.ContainsKey(supplement.TargetStandort))
                    {
                        throw new FlaException("Already contains standort " + supplement.TargetStandort);
                    }

                    standortDict.Add(supplement.TargetStandort, supplement.HaObjectid);
                }

                AssignmentEntry ase = ases.FirstOrDefault(x => x.ObjectId == supplement.HaObjectid);
                if (ase == null)
                {
                    ase = new AssignmentEntry(supplement.HaObjectid);
                    ases.Add(ase);
                }

                ase.Targets.Add(supplement.TargetStandort);
                ase.TargetCount++;
            }

            List <string>        checkedStandorte       = new List <string>();
            var                  lgzs                   = ReadZuordnungLastgänge();
            var                  successfullAssignments = new List <LastgangZuordnung>();
            RowCollection        rc = new RowCollection("sheet", "Sheet1");
            List <PvSystemEntry> assignedPVsystems = new List <PvSystemEntry>();
            List <PvSystemEntry> otherPVsystems    = new List <PvSystemEntry>();

            foreach (House house in houses)
            {
                var houseComponents = house.CollectHouseComponents(hcr);
                foreach (var component in houseComponents)
                {
                    if (component.Standort == null)
                    {
                        continue;
                    }

                    if (standortDict.ContainsKey(component.Standort))
                    {
                        Hausanschluss ha             = hausanschlusses.Single(x => x.Guid == component.HausAnschlussGuid);
                        string        targetObjectID = standortDict[component.Standort];
                        if (ha.ObjectID != targetObjectID)
                        {
                            throw new FlaException("Incorrect hausanschluss for " + component.Name + ": was supposed to be " + targetObjectID +
                                                   " but instead was " + ha.ObjectID + " (standort: " + component.Standort);
                        }

                        var ase = ases.Single(x => x.ObjectId == ha.ObjectID);
                        ase.AssignedCount++;
                        ase.Assigned.Add(component.Standort);
                        checkedStandorte.Add(component.Standort);
                    }

                    if (component.HouseComponentType == HouseComponentType.BusinessWithLastgangHighVoltage)
                    {
                        var businessEntry = (BusinessEntry)component;
                        var rlmfn         = businessEntry.RlmProfileName ?? throw new FlaException("No file");
                        var ha            = hausanschlusses.First(x => x.Guid == businessEntry.HausAnschlussGuid);
                        var rlm           = rlms.Single(x => x.Name == businessEntry.RlmProfileName);
                        var energysum     = new Profile(rlm.Profile).EnergySum();
                        LogAssignment(lgzs,
                                      rlmfn,
                                      ha,
                                      successfullAssignments,
                                      rc,
                                      businessEntry.Name,
                                      businessEntry.Standort,
                                      suppIsn,
                                      "HS",
                                      businessEntry.EffectiveEnergyDemand,
                                      energysum,
                                      house.ComplexName,
                                      businessEntry.FinalIsn);
                    }

                    if (component.HouseComponentType == HouseComponentType.BusinessWithLastgangLowVoltage)
                    {
                        var businessEntry = (BusinessEntry)component;
                        var rlmfn         = businessEntry.RlmProfileName ?? throw new FlaException("no file?");
                        var ha            = hausanschlusses.First(x => x.Guid == businessEntry.HausAnschlussGuid);
                        var rlm           = rlms.Single(x => x.Name == businessEntry.RlmProfileName);
                        var energysum     = new Profile(rlm.Profile).EnergySum();
                        LogAssignment(lgzs,
                                      rlmfn,
                                      ha,
                                      successfullAssignments,
                                      rc,
                                      businessEntry.Name,
                                      businessEntry.Standort,
                                      suppIsn,
                                      "NS",
                                      businessEntry.EffectiveEnergyDemand,
                                      energysum,
                                      house.ComplexName,
                                      businessEntry.FinalIsn);
                    }

                    if (component.HouseComponentType == HouseComponentType.Kwkw)
                    {
                        var kwkw      = (KleinWasserkraft)component;
                        var rlmfn     = kwkw.RlmProfileName;
                        var ha        = hausanschlusses.First(x => x.Guid == kwkw.HausAnschlussGuid);
                        var rlm       = rlms.Single(x => x.Name == kwkw.RlmProfileName);
                        var energysum = new Profile(rlm.Profile).EnergySum();
                        LogAssignment(lgzs,
                                      rlmfn,
                                      ha,
                                      successfullAssignments,
                                      rc,
                                      kwkw.Name,
                                      kwkw.Standort,
                                      suppIsn,
                                      "WKW",
                                      kwkw.EffectiveEnergyDemand,
                                      energysum,
                                      house.ComplexName,
                                      kwkw.FinalIsn);
                    }

                    if (component.HouseComponentType == HouseComponentType.Photovoltaik)
                    {
                        var ha = hausanschlusses.First(x => x.Guid == component.HausAnschlussGuid);
                        if (lgzs.Any(x => string.Equals(x.Knoten.ToLower(), ha.ObjectID.ToLower(), StringComparison.InvariantCultureIgnoreCase)))
                        {
                            assignedPVsystems.Add((PvSystemEntry)component);
                        }
                        else
                        {
                            otherPVsystems.Add((PvSystemEntry)component);
                        }
                    }
                }
            }

            foreach (var zuordnung in lgzs)
            {
                if (!successfullAssignments.Contains(zuordnung))
                {
                    RowBuilder rb         = RowBuilder.Start("Lastgang", zuordnung.FileName).Add("Diren Profilename", zuordnung.Knoten);
                    var        has        = hausanschlusses.Where(x => x.ObjectID == zuordnung.Knoten).ToList();
                    var        haguids    = has.Select(x => x.Guid).Distinct().ToList();
                    var        pvs        = assignedPVsystems.Where(x => haguids.Contains(x.HausAnschlussGuid)).ToList();
                    var        houseGuids = has.Select(x => x.HouseGuid).Distinct().ToList();
                    var        otherPV    = otherPVsystems.Where(x => houseGuids.Contains(x.HouseGuid));
                    rb.Add("PV Systems", string.Join(";", pvs.Select(x => x.Name)));
                    rb.Add("Other PV Systems@house", string.Join(";", otherPV.Select(x => x.Name)));
                    var rlm = rlms.Where(x => x.Name.Contains(zuordnung.FileName)).ToList();
                    for (int i = 0; i < rlm.Count; i++)
                    {
                        var energysum = new Profile(rlm[i].Profile).EnergySum();
                        rb.Add("Profilesumme " + i, energysum);
                    }

                    rc.Add(rb);
                    if (has.Count > 0)
                    {
                        List <string> housenames = new List <string>();
                        foreach (var ha in has)
                        {
                            var house = houses.First(x => x.Guid == ha.HouseGuid);
                            housenames.Add(house.ComplexName);
                        }

                        rb.Add("Hausname", string.Join(",", housenames.Distinct()));
                    }
                }
            }

            foreach (var pVsystem in otherPVsystems)
            {
                House house = houses.First(x => x.Guid == pVsystem.HouseGuid);
                var   rb    = RowBuilder.Start("Hausname", house.ComplexName);
                rb.Add("Effective Energy", pVsystem.EffectiveEnergyDemand);
                rb.Add("Planned Energy", pVsystem.EffectiveEnergyDemand);
                var ha = hausanschlusses.First(x => x.Guid == pVsystem.HausAnschlussGuid);
                rb.Add("Zugeordnete ObjektID", ha.ObjectID);
                rc.Add(rb);
            }

            var fn = MakeAndRegisterFullFilename("WrongAssignments.xlsx", slice);

            XlsxDumper.WriteToXlsx(fn, rc);

            var missingAssigments = lgzs.Where(x => !successfullAssignments.Contains(x)).ToList();

            if (missingAssigments.Count > 0)
            {
                Info("Missing assignments: " + string.Join("\n", missingAssigments.Select(x => x.FileName)));
            }

            foreach (var pair in standortDict)
            {
                if (!checkedStandorte.Contains(pair.Key))
                {
                    //throw new FlaException("Didn't find supplemental standort " + pair.Value + " in the list of components. Typo?");
                }
            }

            foreach (var ase in ases)
            {
                foreach (var target in ase.Targets)
                {
                    if (!ase.Assigned.Contains(target))
                    {
                        //  throw new FlaException("Missing " + target + " from the list of assigned standorts");
                    }
                }

                foreach (var assigned in ase.Assigned)
                {
                    if (!ase.Targets.Contains(assigned))
                    {
                        //throw new FlaException("Missing " + assigned + " from the list of target standorts");
                    }
                }
            }
        }
Exemplo n.º 12
0
        protected override void RunActualProcess([NotNull] ScenarioSliceParameters slice)
        {
            var dbSrcHouses = Services.SqlConnectionPreparer.GetDatabaseConnection(Stage.Houses, slice.PreviousSliceNotNull);
            var dbDstHouses = Services.SqlConnectionPreparer.GetDatabaseConnection(Stage.Houses, slice);

            dbDstHouses.RecreateTable <PvSystemEntry>();
            dbDstHouses.RecreateTable <PVPotential>();
            var srcHouses          = dbSrcHouses.Fetch <House>();
            var srcPVPotentials    = dbSrcHouses.Fetch <PVPotential>();
            var srcPvSystemEntries = dbSrcHouses.Fetch <PvSystemEntry>();
            var hausanschlusses    = dbDstHouses.Fetch <Hausanschluss>();

            dbDstHouses.BeginTransaction();
            foreach (var potential in srcPVPotentials)
            {
                potential.ID = 0;
                dbDstHouses.Save(potential);
            }

            //copy pv systems from previous slice
            HashSet <string>            houseGuidsForSystemsWithPV = new HashSet <string>();
            Dictionary <string, double> pvPotentialByHouseGuid     = new Dictionary <string, double>();

            foreach (var pvpot in srcPVPotentials)
            {
                if (!houseGuidsForSystemsWithPV.Contains(pvpot.HouseGuid))
                {
                    houseGuidsForSystemsWithPV.Add(pvpot.HouseGuid);
                    pvPotentialByHouseGuid.Add(pvpot.HouseGuid, 0);
                }

                pvPotentialByHouseGuid[pvpot.HouseGuid] += pvpot.SonnendachStromErtrag;
            }

            var potentialhousesForPvSystems = srcHouses.Where(x => houseGuidsForSystemsWithPV.Contains(x.Guid)).ToList();

            foreach (var entry in srcPvSystemEntries)
            {
                var toremove = potentialhousesForPvSystems.FirstOrDefault(x => x.Guid == entry.HouseGuid);
                if (toremove != null)
                {
                    potentialhousesForPvSystems.Remove(toremove);
                }

                if (entry.PVAreas.Count == 0)
                {
                    throw new FlaException("No PV System areas defined.");
                }

                entry.ID = 0;
                dbDstHouses.Save(entry);
            }

            var  pvToInstallInkWh   = slice.PvPowerToInstallInGwh * 1_000_000;
            bool continueAllocation = true;
            int  pvSystemCount      = 0;

            while (pvToInstallInkWh > 0 && continueAllocation)
            {
                //make ranges
                var rangeEntries = SetRanges(potentialhousesForPvSystems, pvPotentialByHouseGuid);
                if (rangeEntries.Count == 0)
                {
                    continueAllocation = false;
                    continue;
                }

                //randomly pick
                var max        = rangeEntries.Max(x => x.EndRange);
                var pick       = Services.Rnd.NextDouble() * max;
                var rangeEntry = rangeEntries.Single(x => pick >= x.StartRange && pick <= x.EndRange);
                //remove house
                potentialhousesForPvSystems.Remove(rangeEntry.House);
                //save pvsystementry
                var pvPotenial = pvPotentialByHouseGuid[rangeEntry.House.Guid];
                pvSystemCount++;
                string erzeugerid    = "PV-" + slice.DstYear + "-" + pvSystemCount;
                var    hausanschlsus = rangeEntry.House.GetHausanschlussByIsn(new List <int>(), erzeugerid, hausanschlusses, MyLogger) ??
                                       throw new FlaException("no hausanschluss");
                if (hausanschlsus.ObjectID.ToLower().Contains("leuchte"))
                {
                    throw new FlaException("pv an leuchte in " + slice.DstYear + " " + hausanschlsus.ObjectID);
                }

                var pvSystemEntry = new PvSystemEntry(rangeEntry.House.Guid,
                                                      Guid.NewGuid().ToString(),
                                                      hausanschlsus.Guid,
                                                      rangeEntry.House.ComplexName,
                                                      erzeugerid,
                                                      slice.DstYear)
                {
                    EffectiveEnergyDemand = pvPotenial
                };
                var areas = srcPVPotentials.Where(x => x.HouseGuid == rangeEntry.House.Guid).ToList();
                foreach (var area in areas)
                {
                    pvSystemEntry.PVAreas.Add(new PVSystemArea(area.Ausrichtung, area.Neigung, area.SonnendachStromErtrag));
                }

                if (pvSystemEntry.PVAreas.Count == 0)
                {
                    throw new FlaException("No PV System areas defined.");
                }

                pvToInstallInkWh       -= pvSystemEntry.EffectiveEnergyDemand;
                pvSystemEntry.BuildYear = slice.DstYear;
                dbDstHouses.Save(pvSystemEntry);
                //deduct from pvtoinstall
            }

            dbDstHouses.CompleteTransaction();
            var           newPVs = dbDstHouses.FetchAsRepo <PvSystemEntry>();
            RowCollection rc     = new RowCollection("pv", "pv");

            foreach (var pv in newPVs)
            {
                foreach (var area in pv.PVAreas)
                {
                    RowBuilder rb = RowBuilder.Start("HA", pv.HausAnschlussGuid);
                    rc.Add(rb);
                    rb.Add("Azimut", area.Azimut);
                    rb.Add("Tilt", area.Tilt);
                    rb.Add("Energy", area.Energy);
                }
            }

            var fn = MakeAndRegisterFullFilename("PVExport.xlsx", slice);

            XlsxDumper.WriteToXlsx(fn, rc);
        }
Exemplo n.º 13
0
        protected override void RunChartMaking()
        {
            var slice = Constants.PresentSlice;
            //var dbHouse = Services.SqlConnectionPreparer.GetDatabaseConnection(Stage.Houses, Constants.PresentSlice);
            var ap               = new AnalysisRepository(Services.RunningConfig);
            var dbHouse          = ap.GetSlice(Constants.PresentSlice);
            var houses           = dbHouse.Fetch <House>();
            var houseTypeEntries = dbHouse.Fetch <HouseTypeEntry>();

            MakeHouseTypeEntries();
            MakeHouseTypeMap();
            MakeEnergyUseXls();
            void MakeEnergyUseXls()
            {
                var        households   = dbHouse.Fetch <Household>();
                var        businesses   = dbHouse.Fetch <BusinessEntry>();
                var        infra        = dbHouse.Fetch <BuildingInfrastructure>();
                var        light        = dbHouse.Fetch <StreetLightingEntry>();
                var        dhw          = dbHouse.Fetch <DHWHeaterEntry>();
                var        rc           = new RowCollection("energy", "energy");
                RowBuilder rb           = RowBuilder.Start("Haushalte", households.Sum(x => x.EffectiveEnergyDemand) / Constants.GWhFactor);
                var        bigcustomers = businesses.Where(x => x.EffectiveEnergyDemand > 20000);
                var        small        = businesses.Where(x => x.EffectiveEnergyDemand <= 20000);

                rb.Add("Geschäftskunden > 20 MWh", bigcustomers.Sum(x => x.EffectiveEnergyDemand) / Constants.GWhFactor);
                rb.Add("Geschäftskunden < 20 MWh", small.Sum(x => x.EffectiveEnergyDemand) / Constants.GWhFactor);
                rb.Add("Gebäudeinfrastruktur", infra.Sum(x => x.EffectiveEnergyDemand) / Constants.GWhFactor);
                rb.Add("Strassenbeleuchtung", light.Sum(x => x.YearlyElectricityUse) / Constants.GWhFactor);
                rb.Add("Elektroboiler", dhw.Sum(x => x.EffectiveEnergyDemand) / Constants.GWhFactor);

                rc.Add(rb);
                var fn = MakeAndRegisterFullFilename("EnergyTreeMap.xlsx", Constants.PresentSlice);

                XlsxDumper.WriteToXlsx(fn, rc);
                SaveToPublicationDirectory(fn, Constants.PresentSlice, "4.2");
            }

            void MakeHouseTypeEntries()
            {
                var ssa = new SingleSankeyArrow("HouseTypeEntries", 1500, MyStage,
                                                SequenceNumber, Name, slice, Services);

                ssa.AddEntry(new SankeyEntry("Houses", houses.Count, 5000, Orientation.Straight));
                var countsPerType = new Dictionary <HouseType, int>();

                foreach (var entry in houseTypeEntries)
                {
                    if (!countsPerType.ContainsKey(entry.HouseType))
                    {
                        countsPerType.Add(entry.HouseType, 0);
                    }

                    countsPerType[entry.HouseType]++;
                }

                foreach (var pair in countsPerType)
                {
                    ssa.AddEntry(new SankeyEntry(pair.Key.ToString(), pair.Value * -1, 2000, Orientation.Up));
                }

                Services.PlotMaker.MakeSankeyChart(ssa);
            }

            void MakeHouseTypeMap()
            {
                var rgbs = new Dictionary <HouseType, RGB>();
                var hs   = houseTypeEntries.Select(x => x.HouseType).Distinct().ToList();
                var idx  = 0;

                foreach (var type in hs)
                {
                    var rgb = ColorGenerator.GetRGB(idx++);
                    if (rgb.R == 255 && rgb.B == 255 && rgb.G == 255)
                    {
                        rgb = new RGB(200, 200, 200);
                    }

                    if (rgb.R == 255 && rgb.B == 0 && rgb.G == 0)
                    {
                        rgb = Constants.Orange;
                    }

                    rgbs.Add(type, rgb);
                }

                RGB GetColor(House h)
                {
                    var hse = houseTypeEntries.Single(x => x.HouseGuid == h.Guid);

                    return(rgbs[hse.HouseType]);
                }

                var mapPoints = houses.Select(x => x.GetMapColorForHouse(GetColor)).ToList();

                var filename      = MakeAndRegisterFullFilename("HouseTypeMap.png", slice);
                var legendEntries = new List <MapLegendEntry>();

                foreach (var pair in rgbs)
                {
                    legendEntries.Add(new MapLegendEntry(pair.Key.ToString(), pair.Value));
                }

                Services.PlotMaker.MakeOsmMap(Name, filename, mapPoints, new List <WgsPoint>(), legendEntries, new List <LineEntry>());
            }
        }
        protected override void RunActualProcess()
        {
            var dbHouses  = Services.SqlConnectionPreparer.GetDatabaseConnection(Stage.Houses, Constants.PresentSlice);
            var dbComplex = Services.SqlConnectionPreparer.GetDatabaseConnection(Stage.Complexes, Constants.PresentSlice);

            dbHouses.RecreateTable <HouseHeating>();
            var           buildingcomplexes       = dbComplex.Fetch <BuildingComplex>();
            var           dbRaw                   = Services.SqlConnectionPreparer.GetDatabaseConnection(Stage.Raw, Constants.PresentSlice);
            var           energieBedarfsDatenBern = dbRaw.Fetch <EnergiebedarfsdatenBern>();
            var           houses                  = dbHouses.Fetch <House>();
            var           potentialHeatingSystems = dbHouses.Fetch <PotentialHeatingSystemEntry>();
            RowCollection rc = new RowCollection("Heating", "Heizung");

            dbHouses.BeginTransaction();
            foreach (var h in houses)
            {
                RowBuilder rb = RowBuilder.Start("House", h.ComplexName);
                rc.Add(rb);
                var c            = buildingcomplexes.First(x => x.ComplexID == h.ComplexID);
                var hs           = potentialHeatingSystems.Where(x => x.HouseGuid == h.Guid).ToList();
                var houseHeating = new HouseHeating {
                    LocalnetFernwärmeEnergyUse = hs.Sum(x => x.YearlyFernwärmeDemand),
                    LocalnetGasEnergyUse       = hs.Sum(x => x.YearlyGasDemand),
                    HouseGuid = h.Guid,
                    LocalnetHeatingSystemEntryCount = hs.Count
                };
                rb.Add("Fernwärme", houseHeating.LocalnetFernwärmeEnergyUse).Add("LocalnetEntries", hs.Count);
                rb.Add("Standort", string.Join(",", hs.Select(x => x.Standort).Distinct()));
                rb.Add("Gas", houseHeating.LocalnetGasEnergyUse);
                rb.Add("EBF", h.EnergieBezugsFläche);
                rb.Add("Abrechnung", JsonConvert.SerializeObject(hs, Formatting.Indented));
                //collect ebbe daten
                foreach (var eGid in c.EGids)
                {
                    var ebdbs = energieBedarfsDatenBern.Where(x => x.egid == eGid).ToList();
                    if (ebdbs.Count > 1)
                    {
                        throw new Exception("too many ebdb");
                    }

                    if (ebdbs.Count == 1)
                    {
                        var eb = ebdbs[0];
                        houseHeating.KantonHeatingMethods.Add(GetHeatingMethodString((int)eb.upd_genhz));
                        houseHeating.KantonTotalEnergyDemand      += eb.calc_ehzww;
                        houseHeating.KantonHeizungEnergyDemand    += eb.calc_ehz;
                        houseHeating.KantonWarmwasserEnergyDemand += eb.calc_eww;
                        houseHeating.KantonDhwMethods.Add(GetHeatingMethodString(eb.upd_genww));
                    }
                }

                houseHeating.LocalnetCombinedEnergyDemand = houseHeating.LocalnetFernwärmeEnergyUse + houseHeating.LocalnetGasEnergyUse;
                houseHeating.LocalnetHeatingEnergyDensity = houseHeating.LocalnetAdjustedHeatingDemand / h.EnergieBezugsFläche;
                if (houseHeating.LocalnetHeatingEnergyDensity > 500)
                {
                    houseHeating.LocalnetHeatingEnergyDensity       = 250;
                    houseHeating.EnergyDensityIndustrialApplication = houseHeating.LocalnetHeatingEnergyDensity - 250;
                }

                houseHeating.KantonHeatingEnergyDensity = houseHeating.KantonTotalEnergyDemand / h.EnergieBezugsFläche;
                if (Math.Abs(houseHeating.LocalnetHeatingEnergyDensity) > 0.001)
                {
                    houseHeating.HeatingEnergyDifference = houseHeating.LocalnetHeatingEnergyDensity - houseHeating.KantonHeatingEnergyDensity;
                    if (double.IsNaN(houseHeating.HeatingEnergyDifference) || double.IsInfinity(houseHeating.HeatingEnergyDifference))
                    {
                        houseHeating.HeatingEnergyDifference = 0;
                    }
                }

                if (houseHeating.LocalnetHeatingEnergyDensity > 0)
                {
                    houseHeating.MergedHeatingEnergyDensity = houseHeating.LocalnetHeatingEnergyDensity;
                }
                else
                {
                    houseHeating.MergedHeatingEnergyDensity = houseHeating.KantonHeatingEnergyDensity;
                }

                if (houseHeating.MergedHeatingEnergyDensity < 0)
                {
                    throw new Exception("Negative heating intensity");
                }

                houseHeating.MergedHeatingDemand = 0;
                if (houseHeating.LocalnetCombinedEnergyDemand > 1)
                {
                    houseHeating.MergedHeatingDemand = houseHeating.LocalnetCombinedEnergyDemand;
                }
                else
                {
                    houseHeating.MergedHeatingDemand = houseHeating.KantonTotalEnergyDemand;
                }

                dbHouses.Save(h);
                dbHouses.Save(houseHeating);
            }

            dbHouses.CompleteTransaction();
            var fn = MakeAndRegisterFullFilename("heatingCalcsDump.xlsx", Constants.PresentSlice);

            XlsxDumper.WriteToXlsx(fn, rc);
        }
        protected override void RunActualProcess()
        {
            var dbHouse = Services.SqlConnectionPreparer.GetDatabaseConnection(Stage.Houses, Constants.PresentSlice);

            dbHouse.RecreateTable <BusinessEntry>();
            //load data
            var                  potentialBusinesses = dbHouse.Fetch <PotentialBusinessEntry>();
            var                  hausanschlusses     = dbHouse.Fetch <Hausanschluss>();
            var                  houses           = dbHouse.Fetch <House>();
            var                  validIsns        = houses.SelectMany(x => x.Hausanschluss.Select(y => y.Isn)).ToHashSet();
            List <int>           invalidIsns      = new List <int>();
            const int            randomlyChosenHa = 0;
            const int            reassignedHAs    = 0;
            List <BusinessEntry> businesses       = new List <BusinessEntry>();

            dbHouse.BeginTransaction();
            foreach (var pb in potentialBusinesses)
            {
                if ((pb.MyCategory == "Immobilien" || pb.MyCategory == "WEG") &&
                    pb.Standort != "Einschlagweg 59, Geschoss unbekannt, 3400 Burgdorf" &&
                    pb.Standort != "Fabrikweg 6, Geschoss unbekannt, 3400 Burgdorf")
                {
                    if (pb.HighVoltageYearlyElectricityUse > 0)
                    {
                        throw new FlaException("Building infrastructure with MS?");
                    }

                    var pbi = new PotentialBuildingInfrastructure(pb.HouseGuid,
                                                                  pb.BusinessName,
                                                                  pb.LowVoltageYearlyElectricityUse,
                                                                  pb.HighVoltageYearlyElectricityUse,
                                                                  pb.LowVoltageLocalnetEntries,
                                                                  pb.HighVoltageLocalnetEntries,
                                                                  pb.Standort, Guid.NewGuid().ToString());
                    dbHouse.Save(pbi);
                }
                else
                {
                    BusinessType bt = GetTypeFromDescription(pb.MyCategory);
                    var          be = new BusinessEntry(pb, bt);
                    be.HouseComponentType = HouseComponentType.BusinessNoLastgangLowVoltage;
                    //var hasIndustry = false;

                    /*if (pb.LowVoltageLocalnetEntries.Any(x => x.Rechnungsart == "Industrie") ||
                     *  pb.HighVoltageLocalnetEntries.Any(x => x.Rechnungsart == "Industrie")) {
                     *  hasIndustry = true;
                     * }*/

/*                    if (hasIndustry) {
 *                      be.BusinessType = BusinessType.Industrie;
 *                  }
 *                  else {
 *                      ;
 *                  }*/

                    //isn kontrolle
                    int validisn = 0;
                    foreach (int hhIsn in be.OriginalISNs)
                    {
                        if (!validIsns.Contains(hhIsn))
                        {
                            invalidIsns.Add(hhIsn);
                        }
                        else
                        {
                            validisn = hhIsn;
                        }
                    }

                    var house = houses.Single(x => x.Guid == be.HouseGuid);
                    if (validisn == 0)
                    {
                        be.FinalIsn = house.Hausanschluss[0].Isn;
                    }
                    else
                    {
                        be.FinalIsn = validisn;
                    }


                    var ha = hausanschlusses.Single(x => x.Guid == pb.HausAnschlussGuid);
                    if (ha == null)
                    {
                        throw new FlaException("ha was null");
                    }

                    /*     hausanschlusses.Where(x => x.HouseGuid == be.HouseGuid && x.Isn == be.FinalIsn).ToList();
                     * if (ha.Count == 0)
                     * {
                     *     //throw new FlaException("Kein Hausanschluss gefunden.");
                     *     reassignedHAs++;
                     *     be.HausAnschlussGuid = house.Hausanschluss[0].HausanschlussGuid;
                     * }
                     *
                     * if (ha.Count == 1)
                     * {
                     *     be.HausAnschlussGuid = ha[0].HausanschlussGuid;
                     * }
                     *
                     * if (ha.Count > 1)
                     * {
                     *     randomlyChosenHa++;
                     *     be.HausAnschlussGuid = ha[Services.Rnd.Next(ha.Count)].HausanschlussGuid;
                     *     //throw new FlaException("zu viele Hausanschlüsse gefunden.: " + ha.Count);
                     * }*/
                    be.HausAnschlussGuid = pb.HausAnschlussGuid;
                    businesses.Add(be);
                }
            }
            dbHouse.CompleteTransaction();
            AssignRlmProfiles(businesses, houses);
            foreach (var businessEntry in businesses)
            {
                if (businessEntry.LocalnetHighVoltageYearlyTotalElectricityUse > 0)
                {
                    if (businessEntry.HouseComponentType == HouseComponentType.BusinessNoLastgangLowVoltage)
                    {
                        businessEntry.HouseComponentType = HouseComponentType.BusinessNoLastgangHighVoltage;
                    }
                    else if (businessEntry.HouseComponentType == HouseComponentType.BusinessWithLastgangLowVoltage)
                    {
                        businessEntry.HouseComponentType = HouseComponentType.BusinessWithLastgangHighVoltage;
                    }
                }
            }

            Debug("Invalid Isns: " + invalidIsns.Distinct().Count());
            Debug("Zufällig ausgewählte Hausanschlüsse bei Häusern mit mehr als einem HA: " + randomlyChosenHa);
            Debug("Wohnungen mit neuem Hausanschluss wegen nicht gefundener ISN: " + reassignedHAs);
            int normalBusinesses = businesses.Count(x => x.HouseComponentType == HouseComponentType.BusinessNoLastgangLowVoltage);
            int rlmBusinesses    = businesses.Count(x => x.HouseComponentType == HouseComponentType.BusinessWithLastgangLowVoltage);

            Debug("Businesses without rlm:" + normalBusinesses + " with: " + rlmBusinesses);
            dbHouse.BeginTransaction();
            foreach (BusinessEntry entry in businesses)
            {
                dbHouse.Save(entry);
            }

            dbHouse.CompleteTransaction();
            RowCollection rc = new RowCollection("Businesses", "");

            foreach (var entry in businesses)
            {
                RowBuilder rb = RowBuilder.Start("Name", entry.BusinessName);
                rb.Add("Verbrauchstyp", entry.EnergyType);
                rb.Add("Verbrauch", entry.EffectiveEnergyDemand);
                rb.Add("Businesstype", entry.BusinessType.ToString());
                rc.Add(rb);
            }

            var fn = MakeAndRegisterFullFilename("Businesses.xlsx", Constants.PresentSlice);

            XlsxDumper.WriteToXlsx(fn, rc);
        }
        private static void LogAssignment([NotNull][ItemNotNull] List <LastgangZuordnung> lgzs,
                                          [NotNull] string rlmfn,
                                          [NotNull] Hausanschluss ha,
                                          [NotNull][ItemNotNull] List <LastgangZuordnung> successfullAssignments,
                                          [NotNull] RowCollection rc,
                                          [NotNull] string name,
                                          [NotNull] string standort,
                                          [NotNull][ItemNotNull] List <HausanschlussImportSupplement> supps,
                                          [NotNull] string srctype,
                                          double targetSum,
                                          double assignedSum,
                                          [NotNull] string housename,
                                          int isn)
        {
            var lgz = lgzs.First(x => rlmfn.Contains(x.FileName));

            successfullAssignments.Add(lgz);
            RowBuilder rb = new RowBuilder();

            rc.Add(rb);
            rb.Add("Typ", srctype);
            rb.Add("Name", name);
            rb.Add("Hausname", housename);
            rb.Add("Standort", standort);
            rb.Add("ISN", isn);
            rb.Add("Zugeordnete ObjektID", ha.ObjectID);
            rb.Add("MyFile", rlmfn);
            rb.Add("Profilename", lgz.FileName);
            rb.Add("Diren Knoten", lgz.Knoten);
            rb.Add("Abrechnungssumme", targetSum);
            rb.Add("Profilesumme", assignedSum);
            rb.Add("Skalierungsfaktor", targetSum / assignedSum);
            if (!string.Equals(ha.ObjectID, lgz.Knoten, StringComparison.CurrentCultureIgnoreCase))
            {
                rb.Add("Zuordnung", "Anders");
            }

            var supp = supps.FirstOrDefault(x => x.TargetStandort == standort);

            if (supp != null)
            {
                rb.Add("Explizite Zuordnung", "ja");
            }
        }
Exemplo n.º 17
0
        private void ApplySmartGridstuff([JetBrains.Annotations.NotNull] Dictionary <string, List <Prosumer> > dictionary,
                                         [JetBrains.Annotations.NotNull] string trafokreis,
                                         [JetBrains.Annotations.NotNull] ChangableProfile smartLoad,
                                         [JetBrains.Annotations.NotNull] ChangableProfile smartGeneration,
                                         [JetBrains.Annotations.NotNull] RowCollection smartGridPointValues,
                                         [JetBrains.Annotations.NotNull] SmartGridInformation summedSgi,
                                         [JetBrains.Annotations.NotNull] ScenarioSliceParameters smartSlice)
        {
            trafokreis = FilenameHelpers.CleanUmlaute(trafokreis);
            var loadFilename       = MakeAndRegisterFullFilename(trafokreis + ".load.csv", smartSlice, false);
            var generationFilename = MakeAndRegisterFullFilename(trafokreis + ".generation.csv", smartSlice, false);

            using (StreamWriter loadsw = new StreamWriter(loadFilename)) {
                using (StreamWriter generationsw = new StreamWriter(generationFilename)) {
                    foreach (var ha in dictionary)
                    {
                        var loadsum = ChangableProfile.FromProfile(Profile.MakeConstantProfile(0, "Sum", Profile.ProfileResolution.QuarterHour));
                        var gensum  = ChangableProfile.FromProfile(Profile.MakeConstantProfile(0, "Sum", Profile.ProfileResolution.QuarterHour));

                        foreach (var prosumer in ha.Value)
                        {
                            if (prosumer.GenerationOrLoad == GenerationOrLoad.Load)
                            {
                                loadsum.Add(prosumer.Profile ?? throw new FlaException());
                            }
                            else
                            {
                                gensum.Subtract(prosumer.Profile ?? throw new FlaException());
                            }
                        }

                        RowBuilder rb = RowBuilder.Start("Hausanschluss", ha.Key);
                        smartGridPointValues.Add(rb);
                        var loadProfile = loadsum.ToProfile();
                        rb.Add("Load Energy Sum [kWh]", loadProfile.EnergySum());
                        var genProfile = gensum.ToProfile();
                        rb.Add("Generation Energy Sum [kWh]", genProfile.EnergySum());
                        rb.Add("Number of Prosumers", ha.Value.Count);

                        var    sum             = loadProfile.Add(genProfile, "sum");
                        double storagesizeLoad = //Math.Abs(sum.MakeDailyAverages().Values.Max()) * 24 * 4 * 1.5;
                                                 loadProfile.EnergySum() / 1000 * 4;
                        double storageSizeGen = Math.Abs(genProfile.EnergySum()) / 1000 * 4;
                        double storagesize    = Math.Max(storageSizeGen, storagesizeLoad);
                        sum = ProfileSmoothing.FindBestPowerReductionRatio(sum, storagesize, out _, out var reductionFactor, 0.7);
                        //if (reductionFactor > 0.99) {
//                            storagesize = 0;
                        //}
                        summedSgi.NumberOfReductionFactors++;
                        summedSgi.SummedReductionFactor += reductionFactor;
                        summedSgi.TotalStorageSize      += storagesize;
                        summedSgi.NumberOfProsumers++;
                        rb.Add("Trafokreis", trafokreis);
                        rb.Add("Faktor", reductionFactor);
                        rb.Add("Storage Size", storagesize);
                        var positive = sum.GetOnlyPositive("positive");
                        smartLoad.Add(positive);
                        var negative = sum.GetOnlyNegative("negative");
                        smartGeneration.Add(negative);
                        rb.Add("Energy Sum  Size", storagesize);
                        string csvhakey = ha.Value.First().Isn + ";SM-Pros;MAXMEASUREDVALUE;" + ha.Key + ";";
                        if (positive.EnergySum() > 0)
                        {
                            loadsw.WriteLine(csvhakey + positive.GetCSVLine());
                        }

                        if (negative.EnergySum() < 0)
                        {
                            var generation = negative.MultiplyWith(-1, "generation");
                            generationsw.WriteLine(csvhakey + generation.GetCSVLine());
                        }

                        //positive.GetCSVLine()
                    }

                    loadsw.Close();
                    generationsw.Close();
                }
            }

            if (smartSlice.DstYear == 2050)
            {
                FileInfo lfn = new FileInfo(loadFilename);
                if (lfn.Length > 0)
                {
                    SaveToArchiveDirectory(loadFilename, RelativeDirectory.Load, smartSlice);
                }

                var gfn = new FileInfo(generationFilename);
                if (gfn.Length > 0)
                {
                    SaveToArchiveDirectory(generationFilename, RelativeDirectory.Generation, smartSlice);
                }
            }
        }
Exemplo n.º 18
0
        protected override void RunActualProcess()
        {
            var dbHouses = Services.SqlConnectionPreparer.GetDatabaseConnection(Stage.Houses, Constants.PresentSlice);

            dbHouses.RecreateTable <HeatingSystemEntry>();
            var dbRaw               = Services.SqlConnectionPreparer.GetDatabaseConnection(Stage.Raw, Constants.PresentSlice);
            var dbComplexes         = Services.SqlConnectionPreparer.GetDatabaseConnection(Stage.Complexes, Constants.PresentSlice);
            var rnd                 = new Random();
            var houses              = dbHouses.Fetch <House>();
            var hausanschlusses     = dbHouses.Fetch <Hausanschluss>();
            var houseHeatingMethods = dbHouses.Fetch <HouseHeating>();
            var feuerungsstättenRaw = dbRaw.Fetch <FeuerungsStaette>();
            var complexes           = dbComplexes.Fetch <BuildingComplex>();
            Dictionary <string, BuildingComplex> buildingComplexesByName = new Dictionary <string, BuildingComplex>();

            foreach (BuildingComplex complex in complexes)
            {
                buildingComplexesByName.Add(complex.ComplexName, complex);
            }

            var potentialHeatingSystems = dbHouses.Fetch <PotentialHeatingSystemEntry>();

            dbHouses.BeginTransaction();
            OverrideRepository overrideRepository = new OverrideRepository();
            double             totalFernwärme     = potentialHeatingSystems.Sum(x => x.YearlyFernwärmeDemand);
            var overrideEntries = overrideRepository.ReadEntries(Services);
            var houseNames      = houses.Select(x => x.ComplexName).ToHashSet();

            foreach (OverrideEntry entry in overrideEntries)
            {
                if (!houseNames.Contains(entry.ComplexName))
                {
                    throw new FlaException("Kein Haus für Override Entry " + entry.ComplexName + ". Vermutlich vertippt?");
                }
            }

            List <HeatingSystemEntry> hses = new List <HeatingSystemEntry>();

            foreach (var house in houses)
            {
                var complex = buildingComplexesByName[house.ComplexName];
                List <FeuerungsStaette> feuerungsStättenForHouse = feuerungsstättenRaw.Where(x => {
                    if (x.EGID == null)
                    {
                        throw new FlaException("x.EGID != null");
                    }

                    return(complex.EGids.Contains((long)x.EGID));
                }).ToList();

                //set the age of the heating system, randomly up to 30 years old
                var feuerungsstättenType = string.Join(",", feuerungsStättenForHouse.Select(x => x.Brennstoff?.ToString()).Distinct());
                var hausanschluss        = house.GetHausanschlussByIsn(new List <int>(), null, hausanschlusses, MyLogger, false);
                if (hausanschluss != null && hausanschluss.ObjectID.ToLower().Contains("kleinanschluss"))
                {
                    hausanschluss = null;
                }

                var hse = new HeatingSystemEntry(house.Guid,
                                                 Guid.NewGuid().ToString(),
                                                 feuerungsstättenType,
                                                 hausanschluss?.Guid,
                                                 house.ComplexName,
                                                 house.ComplexName + " - Heating System  - Unknown");
                hses.Add(hse);
                var oldestYear = feuerungsStättenForHouse.Min(x => x.KesselBaujahr);
                if (oldestYear == null || oldestYear.Value < 1800)
                {
                    hse.Age = rnd.Next(30);
                }
                else
                {
                    hse.Age = 2019 - oldestYear.Value;
                }

                hse.FeuerungsstättenPower = feuerungsStättenForHouse.Sum(x => {
                    if (x.KesselLeistung == null)
                    {
                        throw new FlaException("Kesselleistung was null");
                    }

                    return((double)x.KesselLeistung);
                });
                hse.EstimatedMinimumEnergyFromFeuerungsStätten = hse.FeuerungsstättenPower * 1500;
                hse.EstimatedMaximumEnergyFromFeuerungsStätten = hse.FeuerungsstättenPower * 2200;
                //this is a localnet heating system, so use the localnet information
                var           potentialHouseHeatingSystems = potentialHeatingSystems.Where(x => x.HouseGuid == house.Guid).ToList();
                var           houseHeatingMethod           = houseHeatingMethods.Single(x => x.HouseGuid == house.Guid);
                double        totalHeatDemand = 0;
                OverrideEntry ore             = overrideEntries.FirstOrDefault(x => x.ComplexName == house.ComplexName);
                if (ore != null)
                {
                    Debug("Override Entry for " + house.ComplexName);
                }

                if (potentialHouseHeatingSystems.Count > 0)
                {
                    var totalGas   = potentialHouseHeatingSystems.Sum(x => x.YearlyGasDemand);
                    var totalWärme = potentialHouseHeatingSystems.Sum(x => x.YearlyFernwärmeDemand);
                    if (totalGas > 0)
                    {
                        //localnet heizung
                        totalHeatDemand = totalGas;
                        hse.OriginalHeatingSystemType    = HeatingSystemType.GasheatingLocalnet;
                        hse.SynthesizedHeatingSystemType = HeatingSystemType.Gas;
                        if (totalWärme > 0)
                        {
                            throw new Exception("Both wärme and gas");
                        }

                        if (ore != null)
                        {
                            throw new FlaException("Overrride Entry für Localnet Gas Gebäude: " + house.ComplexName +
                                                   ", but that doesn't make sense");
                        }
                    }

                    if (totalWärme > 0)
                    {
                        totalHeatDemand = totalWärme;
                        hse.OriginalHeatingSystemType    = HeatingSystemType.FernwärmeLocalnet;
                        hse.SynthesizedHeatingSystemType = HeatingSystemType.Fernwärme;
                    }
                } // no data, so use feuerungsstätten
                else if (ore != null)
                {
                    //kanton heizung
                    hse.OriginalHeatingSystemType = HeatingSystemType.None;
                    if (ore.HeatingSystemType == HeatingSystemType.Heatpump && hse.HausAnschlussGuid == null)
                    {
                        hse.SynthesizedHeatingSystemType = HeatingSystemType.None;
                    }

                    hse.SynthesizedHeatingSystemType = ore.HeatingSystemType;
                    totalHeatDemand = ore.Amount;
                }
                else if (feuerungsStättenForHouse.Count > 0)
                {
                    var fs = feuerungsStättenForHouse[0];
                    if (fs.Brennstoff == "Oel")
                    {
                        hse.OriginalHeatingSystemType    = HeatingSystemType.FeuerungsstättenOil;
                        hse.SynthesizedHeatingSystemType = HeatingSystemType.Öl;
                        totalHeatDemand = houseHeatingMethod.KantonTotalEnergyDemand;
                    }
                    else if (fs.Brennstoff == "Gas")
                    {
                        hse.OriginalHeatingSystemType = HeatingSystemType.FeuerungsstättenGas;
                        //beco says gas, but can't be, because localnet says no
                        hse.SynthesizedHeatingSystemType = HeatingSystemType.Öl;
                        totalHeatDemand = houseHeatingMethod.KantonTotalEnergyDemand;
                    }
                    else
                    {
                        throw new Exception("invalid heating system");
                    }
                } // no beco, so use ebbe daten
                else if (houseHeatingMethod.KantonHeatingMethods.Count > 0)
                {
                    //kanton heizung
                    var kantonHeatingMethod = houseHeatingMethod.KantonHeatingMethods[0];
                    GetKantonHeatingSystem(kantonHeatingMethod, hse, houseHeatingMethod, ref totalHeatDemand);
                }
                else if (feuerungsStättenForHouse.Count > 0)
                {
                    var fs = feuerungsStättenForHouse[0];
                    if (fs.Brennstoff == "Oel")
                    {
                        hse.OriginalHeatingSystemType    = HeatingSystemType.FeuerungsstättenOil;
                        hse.SynthesizedHeatingSystemType = HeatingSystemType.Öl;
                        totalHeatDemand = houseHeatingMethod.KantonTotalEnergyDemand;
                    }
                    else if (fs.Brennstoff == "Gas")
                    {
                        hse.OriginalHeatingSystemType = HeatingSystemType.FeuerungsstättenGas;
                        //beco says gas, but can't be, because localnet says no
                        hse.SynthesizedHeatingSystemType = HeatingSystemType.Öl;
                        totalHeatDemand = houseHeatingMethod.KantonTotalEnergyDemand;
                    }
                    else
                    {
                        throw new Exception("invalid heating system");
                    }
                } // no beco, so use ebbe daten
                else if (houseHeatingMethod.KantonHeatingMethods.Count > 0)
                {
                    //kanton heizung
                    var kantonHeatingMethod = houseHeatingMethod.KantonHeatingMethods[0];

                    GetKantonHeatingSystem(kantonHeatingMethod, hse, houseHeatingMethod, ref totalHeatDemand);
                }
                else
                {
                    hse.OriginalHeatingSystemType    = HeatingSystemType.None;
                    hse.SynthesizedHeatingSystemType = HeatingSystemType.None;
                    totalHeatDemand = 0;
                }

                if (hse.SynthesizedHeatingSystemType == HeatingSystemType.Heatpump && hse.HausAnschlussGuid == null)
                {
                    hse.SynthesizedHeatingSystemType = HeatingSystemType.None;
                }

                if (hse.SynthesizedHeatingSystemType == HeatingSystemType.Electricity && hse.HausAnschlussGuid == null)
                {
                    throw new FlaException("electric heating without anschluss");
                }

                if (hse.SynthesizedHeatingSystemType == HeatingSystemType.Heatpump && hse.HausAnschlussGuid == null)
                {
                    throw new FlaException("hp heating without anschluss");
                }

                hse.Standort              = house.ComplexName + " - " + hse.SynthesizedHeatingSystemType;
                hse.ProvideProfile        = false;
                hse.HeatingSystemType2017 = hse.SynthesizedHeatingSystemType;
                if (house.Appartments.Count == 0)
                {
                    throw new FlaException("Not a single area in the house " + house.ComplexName);
                }

                double avgHeatDemand = totalHeatDemand / house.Appartments.Count;
                foreach (var appartment in house.Appartments)
                {
                    hse.HeatDemands.Add(new AppartmentHeatingDemand(appartment.Guid,
                                                                    appartment.EnergieBezugsFläche,
                                                                    avgHeatDemand,
                                                                    Constants.PresentSlice.DstYear));
                }

                if (Math.Abs(hse.HeatDemand - totalHeatDemand) > 0.01)
                {
                    throw new FlaException("Invalid heat demand");
                }

                hse.OriginalHeatDemand2017 = hse.HeatDemand;
                dbHouses.Save(hse);
            }

            dbHouses.CompleteTransaction();
            double finalFernwärme = hses.Where(x => x.SynthesizedHeatingSystemType == HeatingSystemType.Fernwärme).Sum(x => x.EffectiveEnergyDemand);

            if (Math.Abs(finalFernwärme - totalFernwärme) > 1)
            {
                throw new FlaException("Fernwärme changed: Nach allem:" + finalFernwärme + " davor: " + totalFernwärme);
            }

            RowCollection rc = new RowCollection("Validation", "Validierung");

            foreach (var feuerungsStaette in feuerungsstättenRaw)
            {
                string     adress = feuerungsStaette.Strasse + " " + feuerungsStaette.Hausnummer;
                RowBuilder rb     = RowBuilder.Start("FeuerungsAdresse", adress);
                rc.Add(rb);
                rb.Add("Brennstoff", feuerungsStaette.Brennstoff);
                rb.Add("Energienutzung", feuerungsStaette.Energienutzung);
                rb.Add("Leistung", feuerungsStaette.KesselLeistung);
                if (feuerungsStaette.EGID != null)
                {
                    int egid  = (int)feuerungsStaette.EGID;
                    var house = houses.FirstOrDefault(x => x.EGIDs.Contains(egid));
                    if (house != null)
                    {
                        rb.Add("Haus", house.ComplexName);
                        rb.Add("HausAdresse", house.Adress);
                        HeatingSystemEntry hse = hses.Single(x => x.HouseGuid == house.Guid);
                        rb.Add("Gewählter Heizungstyp 1", hse.OriginalHeatingSystemType.ToString());
                        rb.Add("Gewählter Heizungstyp 2", hse.SynthesizedHeatingSystemType.ToString());
                        rb.Add("EBF", house.EnergieBezugsFläche);
                    }
                    else
                    {
                        var h2 = houses.FirstOrDefault(x => x.Adress?.Contains(adress) == true);
                        if (h2 != null)
                        {
                            rb.Add("Findbar über Adresse", h2.ComplexName);

                            HeatingSystemEntry hse = hses.Single(x => x.HouseGuid == h2.Guid);
                            rb.Add("Gewählter Heizungstyp 1", hse.OriginalHeatingSystemType.ToString());
                            rb.Add("Gewählter Heizungstyp 2", hse.SynthesizedHeatingSystemType.ToString());
                            rb.Add("EBF", h2.EnergieBezugsFläche);
                        }
                    }
                }
                else
                {
                    rb.Add("Egid fehlt", "True");
                }
            }

            var fn = MakeAndRegisterFullFilename("Feuerungsstätten-Validation.xlsx", Constants.PresentSlice);

            XlsxDumper.WriteToXlsx(fn, rc);
        }
        protected override void RunActualProcess()
        {
            var dbHouses = Services.SqlConnectionPreparer.GetDatabaseConnection(Stage.Houses, Constants.PresentSlice);

            dbHouses.RecreateTable <DHWHeaterEntry>();
            var houses          = dbHouses.Fetch <House>();
            var households      = dbHouses.Fetch <Household>();
            var houseHeatings   = dbHouses.Fetch <HouseHeating>();
            var hausanschlusses = dbHouses.Fetch <Hausanschluss>();

            if (houseHeatings.All(x => x.KantonDhwMethods.Count == 0))
            {
                throw new Exception("not a single  dhw heating method was set");
            }

            if (houseHeatings.All(x => x.KantonHeatingMethods.Count == 0))
            {
                throw new Exception("not a single  space heating method was set");
            }

            RowCollection rc = new RowCollection("Sheet1", "Sheet1");

            dbHouses.BeginTransaction();
            foreach (var house in houses)
            {
                var householdInHouse = households.Where(x => x.HouseGuid == house.Guid).ToList();
                var occupantsInHouse = householdInHouse.SelectMany(x => x.Occupants).ToList();
                var dhwHeaterEntry   = new DHWHeaterEntry(house.Guid, Guid.NewGuid().ToString(), "DHW@" + house.ComplexName);
                var houseHeating     = houseHeatings.Single(x => x.HouseGuid == house.Guid);
                var heatingMethod    = HeatingSystemType.Unbekannt;
                if (houseHeating.KantonDhwMethods.Count > 0)
                {
                    heatingMethod = houseHeating.GetDominantDhwHeatingMethod();
                }

                var        peopleInHouse = occupantsInHouse.Count;
                RowBuilder rb            = RowBuilder.Start("House", house.ComplexName);
                rc.Add(rb);
                rb.Add("Households", households.Count);
                rb.Add("Persons", occupantsInHouse.Count);

                rb.Add("Ebbe DHW Estimate", houseHeating.KantonWarmwasserEnergyDemand);
                switch (heatingMethod)
                {
                case HeatingSystemType.Electricity:
                    dhwHeaterEntry.DhwHeatingSystemType = DhwHeatingSystem.Electricity;
                    // electricity at night
                    break;

                case HeatingSystemType.SolarThermal:
                    dhwHeaterEntry.DhwHeatingSystemType = DhwHeatingSystem.Electricity;
                    break;

                case HeatingSystemType.Gas:
                    dhwHeaterEntry.DhwHeatingSystemType = DhwHeatingSystem.Gasheating;
                    break;

                case HeatingSystemType.Heatpump:
                    dhwHeaterEntry.DhwHeatingSystemType = DhwHeatingSystem.Electricity;
                    break;

                case HeatingSystemType.Fernwärme:
                    dhwHeaterEntry.DhwHeatingSystemType = DhwHeatingSystem.DistrictHeating;
                    break;

                case HeatingSystemType.Other:
                    dhwHeaterEntry.DhwHeatingSystemType = DhwHeatingSystem.Electricity;
                    break;

                case HeatingSystemType.None:
                    dhwHeaterEntry.DhwHeatingSystemType = DhwHeatingSystem.None;
                    break;

                case HeatingSystemType.Öl:
                    dhwHeaterEntry.DhwHeatingSystemType = DhwHeatingSystem.OilHeating;
                    break;

                case HeatingSystemType.Holz:
                    dhwHeaterEntry.DhwHeatingSystemType = DhwHeatingSystem.Electricity;
                    break;

                case HeatingSystemType.Unbekannt:
                    dhwHeaterEntry.DhwHeatingSystemType = DhwHeatingSystem.Electricity;
                    break;

                case HeatingSystemType.GasheatingLocalnet:
                    dhwHeaterEntry.DhwHeatingSystemType = DhwHeatingSystem.Gasheating;
                    break;

                case HeatingSystemType.FernwärmeLocalnet:
                    throw new Exception("Unknown heating method: " + heatingMethod);

                case HeatingSystemType.FeuerungsstättenOil:
                    throw new Exception("Unknown heating method: " + heatingMethod);

                case HeatingSystemType.FeuerungsstättenGas:
                    throw new Exception("Unknown heating method: " + heatingMethod);

                case HeatingSystemType.Kohle:
                    throw new Exception("Unknown heating method: " + heatingMethod);

                default: throw new Exception("Unknown heating method: " + heatingMethod);
                }

                rb.Add("Heating Method", dhwHeaterEntry.DhwHeatingSystemType);

                double        totalEnergy = 0;
                double        dhwEnergy   = 0;
                Hausanschluss hausanschluss;
                string        hausanschlussGuid = null;
                string        standort          = null;
                foreach (var hh in householdInHouse)
                {
                    double personEnergy = hh.EffectiveEnergyDemand / hh.Occupants.Count;
                    if (personEnergy > 1800)
                    {
                        dhwHeaterEntry.DhwHeatingSystemType = DhwHeatingSystem.Electricity;
                    }
                }

                foreach (var hh in householdInHouse)
                {
                    double hhdhwEnergy  = 0;
                    double personEnergy = hh.EffectiveEnergyDemand / hh.Occupants.Count;

                    if (dhwHeaterEntry.DhwHeatingSystemType == DhwHeatingSystem.Electricity)
                    {
                        hhdhwEnergy = CalculateDHWEnergy(personEnergy) * hh.Occupants.Count;
                    }

                    var rbhh = RowBuilder.Start("household", hh.Name);
                    rbhh.Add("Persons", hh.Occupants.Count);
                    rbhh.Add("Energy Per Person in Household [kWh]", hhdhwEnergy);
                    rbhh.Add("Household DHW heating method", dhwHeaterEntry.DhwHeatingSystemType);
                    rbhh.Add("Household Energy", hh.EffectiveEnergyDemand);
                    rc.Add(rbhh);
                    if (Math.Abs(hh.EffectiveEnergyDemand - hh.LocalnetLowVoltageYearlyTotalElectricityUse) > 0.1)
                    {
                        if (Math.Abs(hh.EffectiveEnergyDemand - (hh.LocalnetLowVoltageYearlyTotalElectricityUse + dhwEnergy)) > 0.1)
                        {
                            throw new FlaException("Energy use does not fit");
                        }
                    }

                    hh.SetEnergyReduction("DHW", hhdhwEnergy);
                    if (hh.EffectiveEnergyDemand < 0)
                    {
                        throw new FlaException("Effective Energy demand was null");
                    }

                    totalEnergy      += hh.EffectiveEnergyDemand;
                    hausanschlussGuid = hh.HausAnschlussGuid;
                    standort          = hh.Standort;
                    dbHouses.Save(hh);
                    dhwEnergy += hhdhwEnergy;
                }

                if (hausanschlussGuid != null)
                {
                    hausanschluss = hausanschlusses.Single(x => x.Guid == hausanschlussGuid);
                }
                else
                {
                    hausanschluss = house.GetHausanschlussByIsn(new List <int>(), null, hausanschlusses, MyLogger) ??
                                    throw new FlaException("no hausanschluss");
                }

                dhwHeaterEntry.Standort              = standort;
                dhwHeaterEntry.HausAnschlussGuid     = hausanschluss.Guid;
                dhwHeaterEntry.EffectiveEnergyDemand = dhwEnergy;
                if (totalEnergy < 0)
                {
                    throw new FlaException("Negative total energy");
                }

                rb.Add("Total Energy Originally [kWh]", totalEnergy);
                rb.Add("Total Energy DHW [kWh]", dhwEnergy);
                rb.Add("DHW Power [kWh]", dhwEnergy / 365 / 2);
                rb.Add("Total Energy After Dhw [kWh]", totalEnergy - dhwEnergy);
                rb.Add("Energy Per Person [kWh]", totalEnergy / peopleInHouse);

                dbHouses.Save(dhwHeaterEntry);
            }

            dbHouses.CompleteTransaction();
            var hhdump = MakeAndRegisterFullFilename("Households.xlsx", Constants.PresentSlice);

            XlsxDumper.WriteToXlsx(hhdump, rc);
        }