public bool PrepareLoadProfileIfNeeded([NotNull] ProviderParameterDto parameters) { Module.SetPrint(0); //var relevantPotentials = _pvPotentials.Where(x => x.HouseGuid == houseComponent.HouseGuid); PvSystemEntry entry = (PvSystemEntry)parameters.HouseComponent; int idx = 0; foreach (var area in entry.PVAreas) { var key = MakeKeyFromPVArea(area); var keystr = key.GetKey(); //key has been checked in this run if (_checkedKeys.Contains(keystr)) { continue; } _checkedKeys.Add(keystr); bool isInDb = _saveableEntries.CheckForName(keystr, MyLogger); if (isInDb) { continue; } Info("Missing pv profile for " + keystr + ", generating..."); PVSystemSettings pvs = new PVSystemSettings(key, 1, 1, MyLogger, idx++); var profile = pvs.Run(Services.RunningConfig); _saveableEntries.AddRow(profile); _saveableEntries.SaveDictionaryToDatabase(MyLogger); } return(true); }
protected override void RunActualProcess() { SqlConnection.RecreateTable <PvSystemEntry>(Stage.Houses, Constants.PresentSlice); var dbRaw = SqlConnection.GetDatabaseConnection(Stage.Raw, Constants.PresentSlice).Database; var dbHouses = SqlConnection.GetDatabaseConnection(Stage.Houses, Constants.PresentSlice).Database; var houses = dbHouses.Fetch <House>(); var pvanlagen = dbRaw.Fetch <LocalnetPVAnlage>(); var pvPotentials = dbHouses.Fetch <PVPotential>(); dbHouses.BeginTransaction(); double totalPowerOfIgnoredSystems = 0; foreach (var house in houses) { if (house.ErzeugerIDs.Count == 0) { continue; } foreach (var houseErzeugerID in house.ErzeugerIDs) { if (houseErzeugerID.StartsWith("PV")) { var pvl = pvanlagen.FirstOrDefault(x => x.Anlagenummer == houseErzeugerID); if (pvl == null) { continue; } var hausanschlussguid = house.Hausanschluss[0].HausanschlussGuid; var pse = new PvSystemEntry(house.HouseGuid, Guid.NewGuid().ToString(), hausanschlussguid, house.ComplexName); var areas = pvPotentials.Where(x => x.HouseGuid == house.HouseGuid).ToList(); foreach (var area in areas) { pse.PVAreas.Add(new PVSystemArea(area.Ausrichtung, area.Neigung, area.SonnendachStromErtrag)); } int dstIdx = Services.Rnd.Next(house.Hausanschluss.Count); pse.HausAnschlussGuid = house.Hausanschluss[dstIdx].HausanschlussGuid; if (pse.PVAreas.Count == 0) { pse.PVAreas.Add(new PVSystemArea(0, 30, pvl.Leistungkwp * 1000)); Info("No PV System areas defined: " + house.ComplexName + " Power: " + pvl.Leistungkwp); totalPowerOfIgnoredSystems += pvl.Leistungkwp; } dbHouses.Save(pse); } } } double totalpower = pvanlagen.Sum(x => x.Leistungkwp); Info("Total Ignored Power because no Sonnendach data is available:" + totalPowerOfIgnoredSystems + " / " + totalpower); dbHouses.CompleteTransaction(); }
public void RunPVProviderTest() { // ReSharper disable AssignNullToNotNullAttribute var dbdto = new DBDto(null, null, null, null, null); // ReSharper restore AssignNullToNotNullAttribute // ReSharper disable twice AssignNullToNotNullAttribute ServiceRepository services = new ServiceRepository(null, null, Logger, Config, new Random(1)); PVProfileProvider pvp = new PVProfileProvider(services, Constants.PresentSlice, dbdto); PvSystemEntry pve = new PvSystemEntry("houseguid", "pvguid", "haguid", "myname", "pv123", 2017); pve.PVAreas = new List <PVSystemArea> { new PVSystemArea(30, 30, 1000) }; HouseComponentRo hcro = new HouseComponentRo("myname", "PV", 1, 1, "status", "isns", "standort", 0); ProviderParameterDto pp = new ProviderParameterDto(pve, null, hcro); pvp.PrepareLoadProfileIfNeeded(pp); }
protected override Prosumer ProvidePrivateProfile([NotNull] ProviderParameterDto ppdto) { Module.SetPrint(0); //var relevantPotentials = _pvPotentials.Where(x => x.HouseGuid == houseComponent.HouseGuid); PvSystemEntry entry = (PvSystemEntry)ppdto.HouseComponent; if (_dbDto.Hausanschlusse == null) { throw new FlaException("hausanschlüsse were not initalized"); } if (_dbDto.Hausanschlusse.Count == 0) { throw new FlaException("not a single hausanschluss"); } Hausanschluss hausanschluss = _dbDto.Hausanschlusse.FirstOrDefault(x => x.Guid == entry.HausAnschlussGuid); if (hausanschluss == null) { throw new FlaException("No hausanschluss found for guid: " + entry.HausAnschlussGuid); } if (hausanschluss.ObjectID.ToLower().Contains("leuchte")) { throw new FlaException("PV anlage an einer leuchte! " + hausanschluss.ObjectID + " - " + entry.Name); } //TODO: change this to use pv system areas from the pvsystem entry Profile sumProf = Profile.MakeConstantProfile(0, ppdto.HouseComponent.Name, Profile.ProfileResolution.QuarterHour); if (Math.Abs(entry.PVAreas.Sum(x => x.Energy) - entry.EffectiveEnergyDemand) > 0.1) { throw new FlaException("Sum of the pv areas did not match pv entry sum"); } foreach (var area in entry.PVAreas) { var key = MakeKeyFromPVArea(area); var keystr = key.GetKey(); var areaProfiles = _saveableEntries.LoadAllOrMatching("Name", keystr); if (areaProfiles.Count != 1) { throw new FlaException("Invalid count"); } var areaProfile = areaProfiles[0]; areaProfile.EnergyOrPower = EnergyOrPower.Energy; areaProfile = areaProfile.ScaleToTargetSum(area.Energy, entry.Name, out var _); sumProf = sumProf.Add(areaProfile, entry.Name); } if (Math.Abs(Slice.PVCurtailToXPercent) < 0.00001) { throw new FlaException("Found curtailment to 0"); } if (sumProf.EnergySum() < 0) { throw new FlaException("Negative PV Power"); } if (Slice.PVCurtailToXPercent < 1) { sumProf = sumProf.LimitPositiveToPercentageOfMax(Slice.PVCurtailToXPercent); } var prosumer = new Prosumer(entry.HouseGuid, entry.Name, HouseComponentType.Photovoltaik, entry.SourceGuid, entry.FinalIsn, entry.HausAnschlussGuid, hausanschluss.ObjectID, GenerationOrLoad.Generation, hausanschluss.Trafokreis, Name, "PV Profile") { Profile = sumProf }; if (Math.Abs(Slice.PVCurtailToXPercent - 1) < 0.01 && Math.Abs(sumProf.EnergySum() - entry.EffectiveEnergyDemand) > 0.1) { throw new FlaException("PV Energy result is wrong"); } return(prosumer); }
// ReSharper disable once FunctionComplexityOverflow private static void WriteOneLine([NotNull] ExcelWorksheet ws, int row, [NotNull] Dictionary <Column, int> columnNumbers, [NotNull] House house, [ItemNotNull][NotNull] List <GwrData> gwr, [ItemNotNull][NotNull] List <EnergiebedarfsdatenBern> kanton, [ItemNotNull][NotNull] List <MonthlyElectricityUsePerStandort> complexEnergy, [NotNull] BuildingComplex mycomplex, [NotNull] HeatingSystemEntry heatingSystem, [NotNull][ItemNotNull] List <Occupant> occupants, [NotNull][ItemNotNull] List <BusinessEntry> businessEntries, [CanBeNull] PvSystemEntry pvsystem, [NotNull][ItemNotNull] List <Household> households, [NotNull][ItemNotNull] List <CarDistanceEntry> carDistances, [NotNull] HouseComponentRepository hcr) { ws.Cells[row, columnNumbers[Column.ComplexName]].Value = house.ComplexName; ws.Cells[row, columnNumbers[Column.Adressen]].Value = mycomplex.AdressesAsJson; ws.Cells[row, columnNumbers[Column.EGids]].Value = CleanJson(mycomplex.EGIDsAsJson); ws.Cells[row, columnNumbers[Column.LocalnetISNIds]].Value = CleanJson(mycomplex.GebäudeObjectIDsAsJson); ws.Cells[row, columnNumbers[Column.GeoKoordinaten]].Value = CleanJson(mycomplex.GeoCoordsAsJson); var gwrs = gwr.Where(x => { if (x.EidgGebaeudeidentifikator_EGID == null) { throw new FlaException("x.EidgGebaeudeidentifikator_EGID != null"); } return(mycomplex.EGids.Contains((long)x.EidgGebaeudeidentifikator_EGID)); }).ToList(); ws.Cells[row, columnNumbers[Column.WG_GWR_GebäudeAnzahl]].Value = gwrs.Count; var ebbes = kanton.Where(x => mycomplex.EGids.Contains(x.egid)).ToList(); ws.Cells[row, columnNumbers[Column.WG_GEAK_Anzahl]].Value = ebbes.Sum(x => x.has_geak); ws.Cells[row, columnNumbers[Column.EBBE_GebäudeTyp]].Value = CollapseList(ebbes.Select(x => x.upd_gtyp)); ws.Cells[row, columnNumbers[Column.EBBE_GebäudeTyp]].Value = ws.Cells[row, columnNumbers[Column.GWR_WG]].Value = gwrs.Sum(x => x.AnzahlWohnungen_GANZWHG); ws.Cells[row, columnNumbers[Column.EBBE_GArea]].Value = ebbes.Sum(x => x.garea); ws.Cells[row, columnNumbers[Column.EBBE_EBF_HZ_Updated]].Value = ebbes.Sum(x => x.upd_ebf); ws.Cells[row, columnNumbers[Column.EBBE_calc_ehzww]].Value = ebbes.Sum(x => x.calc_ehzww); ws.Cells[row, columnNumbers[Column.EBBE_calc_ehz]].Value = ebbes.Sum(x => x.calc_ehz); ws.Cells[row, columnNumbers[Column.EBBE_calc_eww]].Value = ebbes.Sum(x => x.calc_eww); //energieträger aus ebbe var heizträgerlst = ebbes.Select(x => x.upd_genhz).ToList(); long heizträger = 0; if (heizträgerlst.Count > 0) { heizträger = heizträgerlst[0]; } switch (heizträger) { case 0: break; case 7200: break; case 7201: ws.Cells[row, columnNumbers[Column.EBHZ_OL]].Value = ebbes.Sum(x => x.calc_ehz); break; case 7202: ws.Cells[row, columnNumbers[Column.EBHZ_KO]].Value = ebbes.Sum(x => x.calc_ehz); break; case 7203: ws.Cells[row, columnNumbers[Column.EBHZ_GZ]].Value = ebbes.Sum(x => x.calc_ehz); break; case 7204: ws.Cells[row, columnNumbers[Column.EBHZ_EL]].Value = ebbes.Sum(x => x.calc_ehz); break; case 7205: ws.Cells[row, columnNumbers[Column.EBHZ_HO]].Value = ebbes.Sum(x => x.calc_ehz); break; case 7206: ws.Cells[row, columnNumbers[Column.EBHZ_WP]].Value = ebbes.Sum(x => x.calc_ehz); break; case 7207: ws.Cells[row, columnNumbers[Column.EBHZ_SO]].Value = ebbes.Sum(x => x.calc_ehz); break; case 7208: ws.Cells[row, columnNumbers[Column.EBHZ_FW]].Value = ebbes.Sum(x => x.calc_ehz); break; case 7209: ws.Cells[row, columnNumbers[Column.EBHZ_A]].Value = ebbes.Sum(x => x.calc_ehz); break; default: throw new Exception("Unknown Heizungsträger: " + heizträger); } //warmwasser aus Ebbe var wwträgerlst = ebbes.Select(x => x.upd_genww).ToList(); long wwträger = 0; if (wwträgerlst.Count > 0) { wwträger = wwträgerlst[0]; } switch (wwträger) { case 0: break; case 7200: break; case 7201: ws.Cells[row, columnNumbers[Column.EBWW_OL]].Value = ebbes.Sum(x => x.calc_eww); break; case 7202: ws.Cells[row, columnNumbers[Column.EBWW_KO]].Value = ebbes.Sum(x => x.calc_eww); break; case 7203: ws.Cells[row, columnNumbers[Column.EBWW_GZ]].Value = ebbes.Sum(x => x.calc_eww); break; case 7204: ws.Cells[row, columnNumbers[Column.EBWW_EL]].Value = ebbes.Sum(x => x.calc_eww); break; case 7205: ws.Cells[row, columnNumbers[Column.EBWW_HO]].Value = ebbes.Sum(x => x.calc_eww); break; case 7206: ws.Cells[row, columnNumbers[Column.EBWW_WP]].Value = ebbes.Sum(x => x.calc_eww); break; case 7207: ws.Cells[row, columnNumbers[Column.EBWW_SO]].Value = ebbes.Sum(x => x.calc_eww); break; case 7208: ws.Cells[row, columnNumbers[Column.EBWW_FW]].Value = ebbes.Sum(x => x.calc_eww); break; case 7209: ws.Cells[row, columnNumbers[Column.EBWW_A]].Value = ebbes.Sum(x => x.calc_eww); break; default: throw new Exception("Unknown Heizungsträger: " + heizträger); } ws.Cells[row, columnNumbers[Column.EBBE_EnergieträgerHz]].Value = CollapseList(ebbes.Select(x => x.upd_genhz.ToString())); ws.Cells[row, columnNumbers[Column.EBBE_EnergieträgerWW]].Value = CollapseList(ebbes.Select(x => x.upd_genww.ToString())); //entries from localnet var monthlies = complexEnergy.Where(x => mycomplex.CleanedStandorte.Contains(x.CleanedStandort)).ToList(); ws.Cells[row, columnNumbers[Column.Localnet_Strom]].Value = monthlies.Sum(x => x.YearlyElectricityUseNetz); ws.Cells[row, columnNumbers[Column.Localnet_Gas]].Value = monthlies.Sum(x => x.YearlyGasUse); ws.Cells[row, columnNumbers[Column.Localnet_Wärme]].Value = monthlies.Sum(x => x.YearlyFernwaermeUse); ws.Cells[row, columnNumbers[Column.BFH_EnergieträgerHeizung]].Value = heatingSystem.SynthesizedHeatingSystemType.ToString(); ws.Cells[row, columnNumbers[Column.BFH_EnergieBedarfHeizung]].Value = heatingSystem.EffectiveEnergyDemand; ws.Cells[row, columnNumbers[Column.BFH_Einwohner]].Value = occupants.Count; var businessTypes = businessEntries.Select(x => x.BusinessType.ToString()).Distinct().ToList(); var businessTypeStr = string.Join(",", businessTypes); ws.Cells[row, columnNumbers[Column.BFH_Geschäfte]].Value = businessTypeStr; if (pvsystem != null) { ws.Cells[row, columnNumbers[Column.BFH_PVSystemGrösseInKWh]].Value = pvsystem.EffectiveEnergyDemand; } ws.Cells[row, columnNumbers[Column.BFH_Geschäfte]].Value = businessTypeStr; ws.Cells[row, columnNumbers[Column.BFH_StromHaushalteLow]].Value = households.Sum(x => x.LocalnetLowVoltageYearlyTotalElectricityUse); ws.Cells[row, columnNumbers[Column.BFH_StromHaushalteLow]].Value = households.Sum(x => x.LocalnetHighVoltageYearlyTotalElectricityUse); ws.Cells[row, columnNumbers[Column.BFH_StromGewerbeLow]].Value = businessEntries.Sum(x => x.LocalnetLowVoltageYearlyTotalElectricityUse); ws.Cells[row, columnNumbers[Column.BFH_StromGewerbeHigh]].Value = businessEntries.Sum(x => x.LocalnetHighVoltageYearlyTotalElectricityUse); ws.Cells[row, columnNumbers[Column.FeuerungsstättenArt]].Value = heatingSystem.FeuerungsstättenType; ws.Cells[row, columnNumbers[Column.FeuerungsstättenKesselLeistung]].Value = heatingSystem.FeuerungsstättenPower; if (heatingSystem.FeuerungsstättenType == "Gas") { ws.Cells[row, columnNumbers[Column.FeuerungsstättenJahresEnergie1500hGas]].Value = heatingSystem.EstimatedMinimumEnergyFromFeuerungsStätten; ws.Cells[row, columnNumbers[Column.FeuerungsstättenJahresEnergie2200hGas]].Value = heatingSystem.EstimatedMaximumEnergyFromFeuerungsStätten; } if (heatingSystem.FeuerungsstättenType == "Oel") { ws.Cells[row, columnNumbers[Column.FeuerungsstättenJahresEnergie1500hOel]].Value = heatingSystem.EstimatedMinimumEnergyFromFeuerungsStätten; ws.Cells[row, columnNumbers[Column.FeuerungsstättenJahresEnergie2200hOel]].Value = heatingSystem.EstimatedMaximumEnergyFromFeuerungsStätten; } ws.Cells[row, columnNumbers[Column.BFH_AnzahlFahrzeuge]].Value = carDistances.Count; ws.Cells[row, columnNumbers[Column.BFH_SummeAutoPendlerdistanz]].Value = carDistances.Sum(x => x.CommutingDistance) * 365; ws.Cells[row, columnNumbers[Column.BFH_SummeAutoGesamtdistanz]].Value = carDistances.Sum(x => x.TotalDistance) * 365; ws.Cells[row, columnNumbers[Column.BFH_SonnendachPotential]].Value = heatingSystem.FeuerungsstättenPower; ws.Cells[row, columnNumbers[Column.TrafoKreis]].Value = string.Join(";", house.Hausanschluss.Select(x => x.Trafokreis)); var houseComponents = house.CollectHouseComponents(hcr); Dictionary <HouseComponentType, double> houseComponentSums = new Dictionary <HouseComponentType, double>(); foreach (var hc in houseComponents) { if (!houseComponentSums.ContainsKey(hc.HouseComponentType)) { houseComponentSums.Add(hc.HouseComponentType, 0); } houseComponentSums[hc.HouseComponentType] += hc.EffectiveEnergyDemand; } foreach (var entry in houseComponentSums) { Column mycol = GetColumn(entry.Key); ws.Cells[row, columnNumbers[mycol]].Value = entry.Value; } }
protected override void RunActualProcess([NotNull] ScenarioSliceParameters parameters) { Services.SqlConnection.RecreateTable <PvSystemEntry>(Stage.Houses, parameters); Services.SqlConnection.RecreateTable <PVPotential>(Stage.Houses, parameters); var dbSrcHouses = Services.SqlConnection.GetDatabaseConnection(Stage.Houses, parameters.PreviousScenarioNotNull).Database; var dbDstHouses = Services.SqlConnection.GetDatabaseConnection(Stage.Houses, parameters).Database; var srcHouses = dbSrcHouses.Fetch <House>(); var srcPVPotentials = dbSrcHouses.Fetch <PVPotential>(); var srcPvSystemEntries = dbSrcHouses.Fetch <PvSystemEntry>(); 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.HouseGuid)).ToList(); foreach (var entry in srcPvSystemEntries) { var toremove = potentialhousesForPvSystems.FirstOrDefault(x => x.HouseGuid == entry.HouseGuid); if (toremove != null) { potentialhousesForPvSystems.Remove(toremove); } if (entry.PVAreas.Count == 0) { throw new FlaException("No PV System areas defined."); } entry.Pvid = 0; dbDstHouses.Save(entry); } var pvToInstallInkWh = parameters.PvPowerToInstallInGwh * 1_000_000; while (pvToInstallInkWh > 0) { //make ranges var rangeEntries = SetRanges(potentialhousesForPvSystems, pvPotentialByHouseGuid); //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.HouseGuid]; var hausanschlsusGuid = rangeEntry.House.Hausanschluss[0].HausanschlussGuid; var pvSystemEntry = new PvSystemEntry(rangeEntry.House.HouseGuid, Guid.NewGuid().ToString(), hausanschlsusGuid, rangeEntry.House.ComplexName) { YearlyPotential = pvPotenial }; var areas = srcPVPotentials.Where(x => x.HouseGuid == rangeEntry.House.HouseGuid).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.YearlyPotential; pvSystemEntry.BuildYear = parameters.DstYear; int dstIdx = Services.Rnd.Next(rangeEntry.House.Hausanschluss.Count); pvSystemEntry.HausAnschlussGuid = rangeEntry.House.Hausanschluss[dstIdx].HausanschlussGuid; dbDstHouses.Save(pvSystemEntry); //deduct from pvtoinstall } dbDstHouses.CompleteTransaction(); }
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); }
protected override void RunActualProcess() { var dbRaw = Services.SqlConnectionPreparer.GetDatabaseConnection(Stage.Raw, Constants.PresentSlice); var dbHouses = Services.SqlConnectionPreparer.GetDatabaseConnection(Stage.Houses, Constants.PresentSlice); dbHouses.RecreateTable <PvSystemEntry>(); var houses = dbHouses.Fetch <House>(); var localnetPVAnlagen = dbRaw.Fetch <LocalnetPVAnlage>(); var pvPotentials = dbHouses.Fetch <PVPotential>(); var hausanschlusses = dbHouses.Fetch <Hausanschluss>(); dbHouses.BeginTransaction(); double totalEnergyOfFakeSystems = 0; double totalEnergyOfSonnendachSystems = 0; foreach (var house in houses) { if (house.ErzeugerIDs.Count == 0) { continue; } foreach (var houseErzeugerID in house.ErzeugerIDs) { if (houseErzeugerID.StartsWith("PV")) { var pvl = localnetPVAnlagen.FirstOrDefault(x => x.Anlagenummer == houseErzeugerID); if (pvl == null) { continue; } var hausanschluss = house.GetHausanschlussByIsn(new List <int>(), null, hausanschlusses, MyLogger) ?? throw new FlaException("no hausanschluss"); if (hausanschluss.ObjectID.ToLower().Contains("leuchte")) { throw new FlaException("PV anlage an einer leuchte!"); } var pse = new PvSystemEntry(house.Guid, Guid.NewGuid().ToString(), hausanschluss.Guid, house.ComplexName, houseErzeugerID, Constants.PresentSlice.DstYear); var areas = pvPotentials.Where(x => x.HouseGuid == house.Guid).ToList(); foreach (var area in areas) { pse.PVAreas.Add(new PVSystemArea(area.Ausrichtung, area.Neigung, area.SonnendachStromErtrag)); } double localnetTargetEnergy = pvl.Leistungkwp * 1100; if (pse.PVAreas.Count == 0) { pse.PVAreas.Add(new PVSystemArea(0, 30, localnetTargetEnergy)); Debug("No PV System areas defined: " + house.ComplexName + ", setting 30°/south system with power: " + pvl.Leistungkwp); totalEnergyOfFakeSystems += pse.PVAreas.Sum(x => x.Energy); } else { double sonnendachEnergy = pse.PVAreas.Sum(x => x.Energy); if (sonnendachEnergy > localnetTargetEnergy) { //need to var potentialAreas = pse.PVAreas.ToList(); if (potentialAreas.Count == 0) { throw new FlaException("No area?"); } potentialAreas.Sort((x, y) => y.Energy.CompareTo(x.Energy)); pse.PVAreas.Clear(); double sumSoFar = 0; while (potentialAreas[0].Energy + sumSoFar < localnetTargetEnergy) { pse.PVAreas.Add(potentialAreas[0]); sumSoFar += potentialAreas[0].Energy; potentialAreas.RemoveAt(0); } double missingEnergy = localnetTargetEnergy - pse.PVAreas.Sum(x => x.Energy); pse.PVAreas.Add(new PVSystemArea(0, 30, missingEnergy)); totalEnergyOfSonnendachSystems += pse.PVAreas.Sum(x => x.Energy); } else { //ignore the sonnendach stuff, since it seems to be wrong pse.PVAreas.Clear(); pse.PVAreas.Add(new PVSystemArea(0, 30, localnetTargetEnergy)); totalEnergyOfFakeSystems += pse.PVAreas.Sum(x => x.Energy); } } dbHouses.Save(pse); } } } double totalpower = localnetPVAnlagen.Sum(x => x.Leistungkwp) * 1100; Info("Total arbitrary south energy because no Sonnendach data is available:" + totalEnergyOfFakeSystems / 1000 + "mwh"); Info("Total Sonnendach data is available:" + totalEnergyOfSonnendachSystems / 1000 + "mwh"); Info("Total energy target: " + totalpower / 1000); dbHouses.CompleteTransaction(); }