public static HeatpumpCalculationParameters MakeDefaults()
        {
            HeatpumpCalculationParameters h = new HeatpumpCalculationParameters(HeatPumpTimingMode.OnlyAtNight,
                                                                                6 * 4, 21 * 4, 6, 0.75, 1);

            return(h);
        }
 public HeatPumpStateEngine(double maxPower, double maxHouseEnergy, [NotNull] Random rnd, [NotNull] HeatpumpCalculationParameters hpPars)
 {
     _maxPower           = maxPower / 4.0; //for 15 minutes
     _maxHouseEnergy     = maxHouseEnergy;
     _rnd                = rnd;
     _hpPars             = hpPars;
     _triggerHouseEnergy = maxHouseEnergy * _hpPars.HouseMinimumEnergyTriggerinPercent;
 }
        public HeatPumpResult Run([NotNull] HeatpumpCalculationParameters hpPar, double yearlyConsumption, [NotNull] Random rnd)
        {
            var hpr = new HeatPumpResult();

            _hdp.InitializeDailyAmounts(yearlyConsumption);
            //calculate required power
            if (hpPar.HouseMinimumEnergyTriggerinPercent > 1)
            {
                throw new FlaException("More than 100% trigger is not possible");
            }

            var maxDailyNeed = _hdp.HeatingDegreeDays.Select(x => x.DailyEnergyConsumption).Max();
            var power        = maxDailyNeed / hpPar.TargetMaximumRuntimePerDay; //only target running for 12h

            power = Math.Max(power, 5);                                         // minimum 5kw
            power = ((int)power / 5) * 5;                                       // round to the neared 5kw
            double houseEnergy       = maxDailyNeed * hpPar.StartLevelPercent;
            int    idx               = 0;
            HeatPumpStateEngine hpse = new HeatPumpStateEngine(power, maxDailyNeed, rnd, hpPar);
            int    prepSteps         = 1000 + rnd.Next(1000);
            double dailyEnergyLoss   = _hdp.HeatingDegreeDays[0].DailyEnergyConsumption / 96;

            for (int i = 0; i < prepSteps; i++)
            {
                houseEnergy -= dailyEnergyLoss;
                houseEnergy += hpse.ProvideEnergyForTimestep(houseEnergy, 1);
            }

            for (int i = 0; i < 365; i++)
            {
                double daily = _hdp.HeatingDegreeDays[i].DailyEnergyConsumption;
                double energyLostPerTimestep = daily / 96;
                for (int dayTimeStep = 0; dayTimeStep < 96; dayTimeStep++)
                {
                    hpr.DailyAvgTemperatures15Min[idx] = _hdp.HeatingDegreeDays[i].DailyAverageTemperature;
                    hpr.HouseEnergyTracker[idx]        = houseEnergy;
                    houseEnergy -= energyLostPerTimestep;
                    double heatPumpSuppliedEnergy = hpse.ProvideEnergyForTimestep(houseEnergy, dayTimeStep);
                    //      totalEnergy += heatPumpSuppliedEnergy;
                    houseEnergy += heatPumpSuppliedEnergy;
                    hpr.HeatpumpEnergySupply[idx] = heatPumpSuppliedEnergy;
                    idx++;
                }
            }

            CalculateEnergyConsumption(hpr, hpPar.HeatPumpCop);
            return(hpr);
        }
        public void RunSingleHpTest()
        {
            ServiceRepository services = new ServiceRepository(null, null, Logger, Config, new Random());
            var dbRaw        = services.SqlConnectionPreparer.GetDatabaseConnection(Stage.Raw, Constants.PresentSlice);
            var temperatures = dbRaw.Fetch <TemperatureProfileImport>();

            Profile temperaturProfileHourly = new Profile(temperatures[0].Profile ?? throw new FlaException("was null"));
            //make heatpumpprofile
            HeatpumpProfileGenerator chp = new HeatpumpProfileGenerator(temperaturProfileHourly, 15, 20, Logger);
            Random       rnd             = new Random();
            var          hpcp            = HeatpumpCalculationParameters.MakeDefaults();
            const double energyuse       = 20000;
            var          hpr             = chp.Run(hpcp, energyuse, rnd);

            hpr.GetEnergyDemandProfile().Values.Sum().Should().BeApproximately(energyuse * 0.333, 100);
            Profile      houseEnergy             = new Profile("House Energy", hpr.HouseEnergyTracker.AsReadOnly(), EnergyOrPower.Energy);
            Profile      heatPumpEnergysupply    = new Profile("Heat pump Energy supply", hpr.HeatpumpEnergySupply.AsReadOnly(), EnergyOrPower.Energy);
            Profile      temperatureProfile15Min = new Profile("Temperatures", hpr.DailyAvgTemperatures15Min.ToList().AsReadOnly(), EnergyOrPower.Energy);
            const string file = "heatpumprofile_Single.xlsx";

            WriteProfilesToExcel(temperatureProfile15Min, houseEnergy, heatPumpEnergysupply, file);
        }
        public void RunMultiHpTest()
        {
            PrepareUnitTest();
            // ReSharper disable twice AssignNullToNotNullAttribute
            ServiceRepository services = new ServiceRepository(null, null, Logger, Config, new Random());
            var dbRaw   = services.SqlConnectionPreparer.GetDatabaseConnection(Stage.Raw, Constants.PresentSlice);
            var dbHouse = services.SqlConnectionPreparer.GetDatabaseConnection(Stage.Houses,
                                                                               new ScenarioSliceParameters(Scenario.FromEnum(ScenarioEnum.Utopia), 2050, null));
            var     temperatures            = dbRaw.Fetch <TemperatureProfileImport>();
            var     heatPumpEntries         = dbHouse.Fetch <HeatingSystemEntry>();
            Profile temperaturProfileHourly = new Profile(temperatures[0].Profile ?? throw new FlaException("was null"));
            Random  rnd = new Random();
            //make heatpumpprofile
            Profile        houseEnergy             = Profile.MakeConstantProfile(0, "House Energy", Profile.ProfileResolution.QuarterHour);
            Profile        heatPumpEnergysupply    = Profile.MakeConstantProfile(0, "Heat pump Energy supply", Profile.ProfileResolution.QuarterHour);
            Profile        heatPumpEnergyDemand    = Profile.MakeConstantProfile(0, "Heat pump Energy Demand", Profile.ProfileResolution.QuarterHour);
            Profile        temperatureProfile15Min = null;
            List <Profile> allHouseDemandProfiles  = new List <Profile>();

            foreach (var entry in heatPumpEntries)
            {
                HeatpumpProfileGenerator chp = new HeatpumpProfileGenerator(temperaturProfileHourly, 15, 20, Logger);
                var hpcp = HeatpumpCalculationParameters.MakeDefaults();
                hpcp.StartingTimeStepEvenings           = (21 * 4) + rnd.Next(12);
                hpcp.StoppingTimeStepMorning            = (4 * 4) + rnd.Next(12);
                hpcp.HouseMinimumEnergyTriggerinPercent = 0.70 - rnd.NextDouble() * 0.2;
                hpcp.TargetMaximumRuntimePerDay         = 16 + rnd.NextDouble() * 4;
                hpcp.TimingMode        = HeatPumpTimingMode.OverTheEntireDay;
                hpcp.StartLevelPercent = 1 - rnd.NextDouble() * .5;
                HeatPumpResult hpr    = chp.Run(hpcp, entry.EffectiveEnergyDemand, rnd);
                var            result = hpr.GetEnergyDemandProfile();
                result.Name += entry.Standort;
                allHouseDemandProfiles.Add(result);
                result.Values.Sum().Should().BeApproximately(entry.EffectiveEnergyDemand * .333, entry.EffectiveEnergyDemand * 0.1);
                heatPumpEnergyDemand = heatPumpEnergyDemand.Add(result, heatPumpEnergyDemand.Name);
                houseEnergy          = houseEnergy.Add(hpr.HouseEnergyTracker.AsReadOnly());
                heatPumpEnergysupply = heatPumpEnergysupply.Add(hpr.HeatpumpEnergySupply.AsReadOnly());
                if (temperatureProfile15Min == null)
                {
                    temperatureProfile15Min = new Profile("Temperatures", hpr.DailyAvgTemperatures15Min.ToList().AsReadOnly(), EnergyOrPower.Energy);
                }
            }

            allHouseDemandProfiles.Sort((x, y) => y.EnergySum().CompareTo(x.EnergySum()));
            var profilesToShow  = allHouseDemandProfiles.Take(5).ToList();
            var profilesToMerge = allHouseDemandProfiles.Skip(6).ToList();
            var mergedProfiles  = allHouseDemandProfiles[5].Add(profilesToMerge, "MergedProfiles");

            if (temperatureProfile15Min == null)
            {
                throw new FlaException("no temperatures");
            }

            ProfileWorksheetContent biggestConsumers = new ProfileWorksheetContent("Biggest Consumers", "Last", profilesToShow);

            biggestConsumers.Profiles.Add(mergedProfiles);
            string fullFileName = WorkingDirectory.Combine("heatpump_profiles_multi-WithChart.xlsx");

            XlsxDumper.DumpProfilesToExcel(fullFileName,
                                           2017,
                                           15,
                                           new ProfileWorksheetContent("Energy Demand", "Last", 240, heatPumpEnergyDemand),
                                           new ProfileWorksheetContent("Energy Supply", "Energieversorgung", 240, heatPumpEnergysupply),
                                           new ProfileWorksheetContent("Temperatures", "Temperatur", 240, temperatureProfile15Min),
                                           new ProfileWorksheetContent("House Energy", "Haus Energiegehalt", 240, houseEnergy),
                                           biggestConsumers);
            //WriteProfilesToExcel(temperatureProfile15Min, houseEnergy, heatPumpEnergysupply,file);
        }
        protected override Prosumer ProvidePrivateProfile([NotNull] ProviderParameterDto ppdto)
        {
            HeatingSystemEntry hse = (HeatingSystemEntry)ppdto.HouseComponent;

            if (hse.HouseComponentType != HouseComponentType.Heating)
            {
                throw new FlaException("Wrong type");
            }

            ppdto.HouseComponentResultObject.HeatingSystemType = hse.SynthesizedHeatingSystemType;
            if (hse.SynthesizedHeatingSystemType != HeatingSystemType.Heatpump && hse.SynthesizedHeatingSystemType != HeatingSystemType.Electricity)
            {
                ppdto.HouseComponentResultObject.HeatingSystemMessage = "Not electric heating";
                return(null);
            }

            if (!hse.ProvideProfile)
            {
                return(null);
            }

            if (hse.HausAnschlussGuid == null)
            {
                return(null);
            }

            Hausanschluss ha = _dbDto.Hausanschlusse.Single(x => x.Guid == hse.HausAnschlussGuid);

            if (ha.ObjectID.ToLower().Contains("kleinanschluss"))
            {
                throw new FlaException("Heizung am kleinanschluss?");
            }

            var pa = new Prosumer(hse.HouseGuid,
                                  hse.Standort,
                                  hse.HouseComponentType,
                                  hse.SourceGuid,
                                  hse.FinalIsn,
                                  hse.HausAnschlussGuid,
                                  ha.ObjectID,
                                  GenerationOrLoad.Load,
                                  ha.Trafokreis,
                                  Name,
                                  "Heatpump Profile Generator");
            //todo: randomize this with buckets and/or simulate a central control
            int    morningTime                = 4 * 4 + Services.Rnd.Next(8);
            int    eveningTime                = 20 * 4 + Services.Rnd.Next(8);
            double targetRuntimePerDay        = 16 + Services.Rnd.NextDouble() * 4;
            double trigger                    = 1 - Services.Rnd.NextDouble() * 0.1;
            HeatpumpCalculationParameters hpc = new HeatpumpCalculationParameters(HeatPumpTimingMode.OverTheEntireDay,
                                                                                  morningTime,
                                                                                  eveningTime,
                                                                                  targetRuntimePerDay,
                                                                                  trigger,
                                                                                  1);

            hpc.StartLevelPercent = 1 - Services.Rnd.NextDouble() * .5;
            var hpr = _hpg.Run(hpc, hse.EffectiveEnergyDemand, Services.Rnd);

            pa.Profile = hpr.GetEnergyDemandProfile();
            return(pa);
        }