Beispiel #1
0
 def _validate_rates(initial_rate, final_rate,
                     energy_rate_change_per_update, fit_to_limit):
     # all parameters have to be validated for each time slot here
     for time_slot in initial_rate.keys():
         rate_change = None if fit_to_limit else \
             find_object_of_same_weekday_and_time(energy_rate_change_per_update, time_slot)
         PVValidator.validate_rate(
             initial_selling_rate=initial_rate[time_slot],
             final_selling_rate=find_object_of_same_weekday_and_time(
                 final_rate, time_slot),
             energy_rate_decrease_per_update=rate_change,
             fit_to_limit=fit_to_limit)
Beispiel #2
0
 def _populate_profiles(self, area):
     for market in area.all_markets:
         time_slot = market.time_slot
         if self.fit_to_limit is False:
             self.energy_rate_change_per_update[time_slot] = \
                 find_object_of_same_weekday_and_time(
                     self.energy_rate_change_per_update_profile_buffer, time_slot)
         self.initial_rate[time_slot] = \
             find_object_of_same_weekday_and_time(self.initial_rate_profile_buffer,
                                                  time_slot)
         self.final_rate[time_slot] = \
             find_object_of_same_weekday_and_time(self.final_rate_profile_buffer,
                                                  time_slot)
         self._set_or_update_energy_rate_change_per_update(market.time_slot)
         write_default_to_dict(self.update_counter, market.time_slot, 0)
Beispiel #3
0
def _fill_gaps_in_profile(input_profile: Dict = None,
                          out_profile: Dict = None) -> Dict:
    """
    Fills time steps, where no value is provided, with the value value of the
    last available time step.
    :param input_profile: Dict[Datetime: float, int, tuple]
    :param out_profile: dict with the same format as the input_profile that can be used
                        to provide a default zero-value profile dict with the expected timestamps
                        that need to be populated in the profile
    :return: continuous profile Dict[Datetime: float, int, tuple]
    """

    if isinstance(list(input_profile.values())[0], tuple):
        current_val = (0, 0)
    else:
        current_val = 0

    for time in out_profile.keys():
        if GlobalConfig.IS_CANARY_NETWORK:
            temp_val = find_object_of_same_weekday_and_time(
                input_profile, time, ignore_not_found=True)
            if temp_val is not None:
                current_val = temp_val
        else:
            if time in input_profile:
                current_val = input_profile[time]
        out_profile[time] = current_val

    return out_profile
Beispiel #4
0
def get_market_maker_rate_from_config(next_market, default_value=None):
    if next_market is None:
        return default_value
    if isinstance(GlobalConfig.market_maker_rate, dict):
        return find_object_of_same_weekday_and_time(
            GlobalConfig.market_maker_rate, next_market.time_slot)
    else:
        return GlobalConfig.market_maker_rate
def test_global_market_maker_rate_set_at_instantiation(area_test1):
    strategy = InfiniteBusStrategy(energy_sell_rate=35)
    assert strategy.energy_rate == GlobalConfig.market_maker_rate
    strategy = InfiniteBusStrategy(energy_rate_profile={"01:15": 40})
    timestamp_key = pendulum.today("utc").set(hour=1, minute=15)
    rate = find_object_of_same_weekday_and_time(GlobalConfig.market_maker_rate,
                                                timestamp_key)
    assert rate == 40
Beispiel #6
0
 def event_market_cycle(self):
     power_from_profile = \
         find_object_of_same_weekday_and_time(self.max_available_power_kW,
                                              self.area.next_market.time_slot)
     self.energy_per_slot_kWh = convert_kW_to_kWh(
         power_from_profile, self.area.config.slot_length)
     if self.energy_per_slot_kWh <= 0.0:
         return
     super().event_market_cycle()
Beispiel #7
0
def check_load_profile_csv(context, single_or_multi):
    house1 = next(filter(lambda x: x.name == "House 1", context.simulation.area.children))
    load = next(filter(lambda x: x.name == "H1 DefinedLoad", house1.children))
    if single_or_multi == "single":
        path = user_profile_load_csv.profile_path
    else:
        path = user_profile_load_csv_multiday.profile_path
    input_profile = read_arbitrary_profile(InputProfileTypes.POWER, path)
    for timepoint, energy in load.strategy.state._desired_energy_Wh.items():
        assert energy == find_object_of_same_weekday_and_time(input_profile, timepoint) * 1000
Beispiel #8
0
 def _set_or_update_energy_rate_change_per_update(self, time_slot):
     energy_rate_change_per_update = {}
     if self.fit_to_limit:
         energy_rate_change_per_update[time_slot] = \
             (find_object_of_same_weekday_and_time(
                 self.initial_rate_profile_buffer, time_slot) -
              find_object_of_same_weekday_and_time(
                  self.final_rate_profile_buffer, time_slot)) / \
             self.number_of_available_updates
     else:
         if self.rate_limit_object is min:
             energy_rate_change_per_update[time_slot] = \
                 -1 * find_object_of_same_weekday_and_time(
                     self.energy_rate_change_per_update_profile_buffer, time_slot)
         elif self.rate_limit_object is max:
             energy_rate_change_per_update[time_slot] = \
                 find_object_of_same_weekday_and_time(
                     self.energy_rate_change_per_update_profile_buffer, time_slot)
     self.energy_rate_change_per_update.update(
         energy_rate_change_per_update)
Beispiel #9
0
    def _validate_rates(initial_selling_rate, final_selling_rate,
                        initial_buying_rate, final_buying_rate,
                        energy_rate_increase_per_update,
                        energy_rate_decrease_per_update, bid_fit_to_limit,
                        offer_fit_to_limit):

        for time_slot in initial_selling_rate.keys():
            bid_rate_change = None if bid_fit_to_limit else \
                find_object_of_same_weekday_and_time(energy_rate_increase_per_update, time_slot)
            offer_rate_change = None if offer_fit_to_limit else \
                find_object_of_same_weekday_and_time(energy_rate_decrease_per_update, time_slot)
            StorageValidator.validate(
                initial_selling_rate=initial_selling_rate[time_slot],
                final_selling_rate=find_object_of_same_weekday_and_time(
                    final_selling_rate, time_slot),
                initial_buying_rate=find_object_of_same_weekday_and_time(
                    initial_buying_rate, time_slot),
                final_buying_rate=find_object_of_same_weekday_and_time(
                    final_buying_rate, time_slot),
                energy_rate_increase_per_update=bid_rate_change,
                energy_rate_decrease_per_update=offer_rate_change)
Beispiel #10
0
 def event_market_cycle(self):
     super().event_market_cycle()
     if ConstSettings.IAASettings.MARKET_TYPE == 2:
         for market in self.area.all_markets:
             try:
                 buy_rate = find_object_of_same_weekday_and_time(self.energy_buy_rate,
                                                                 market.time_slot)
                 self.post_bid(market,
                               buy_rate * INF_ENERGY,
                               INF_ENERGY)
             except MarketException:
                 pass
Beispiel #11
0
 def buy_energy(self, market):
     for offer in market.sorted_offers:
         if offer.seller == self.owner.name:
             # Don't buy our own offer
             continue
         if offer.energy_rate <= find_object_of_same_weekday_and_time(self.energy_buy_rate,
                                                                      market.time_slot):
             try:
                 self.accept_offer(market, offer, buyer_origin=self.owner.name,
                                   buyer_origin_id=self.owner.uuid,
                                   buyer_id=self.owner.uuid)
             except MarketException:
                 # Offer already gone etc., try next one.
                 continue
Beispiel #12
0
 def set_produced_energy_forecast_kWh_future_markets(
         self, reconfigure=True):
     self._power_profile_index = self.cloud_coverage \
         if self.cloud_coverage is not None else self.area.config.cloud_coverage
     if reconfigure:
         self._read_predefined_profile_for_pv()
     for market in self.area.all_markets:
         slot_time = market.time_slot
         if not self.power_profile:
             raise D3AException(
                 f"PV {self.owner.name} tries to set its available energy forecast without a "
                 f"power profile.")
         available_energy_kWh = find_object_of_same_weekday_and_time(
             self.power_profile, slot_time) * self.panel_count
         self.state.set_available_energy(available_energy_kWh, slot_time,
                                         reconfigure)
Beispiel #13
0
 def _update_energy_requirement_future_markets(self):
     """
     Update required energy values for each market slot.
     :return: None
     """
     for market in self.area.all_markets:
         slot_time = market.time_slot
         if not self.load_profile:
             raise D3AException(
                 f"Load {self.owner.name} tries to set its energy forecasted requirement "
                 f"without a profile.")
         load_energy_kWh = \
             find_object_of_same_weekday_and_time(self.load_profile, slot_time)
         self.state.set_desired_energy(load_energy_kWh * 1000,
                                       slot_time,
                                       overwrite=False)
         self.state.update_total_demanded_energy(slot_time)
Beispiel #14
0
    def offer_energy(self, market):
        energy_rate = find_object_of_same_weekday_and_time(
            self.energy_rate, market.time_slot)
        try:
            offer = market.offer(
                self.energy_per_slot_kWh * energy_rate,
                self.energy_per_slot_kWh,
                self.owner.name,
                original_offer_price=self.energy_per_slot_kWh * energy_rate,
                seller_origin=self.owner.name,
                seller_origin_id=self.owner.uuid,
                seller_id=self.owner.uuid)

            self.offers.post(offer, market.id)
        except MarketException:
            logging.error(
                f"Offer posted with negative energy rate {energy_rate}."
                f"Posting offer with zero energy rate instead.")
Beispiel #15
0
    def __init__(
        self,
        initial_soc: float = StorageSettings.MIN_ALLOWED_SOC,
        min_allowed_soc=StorageSettings.MIN_ALLOWED_SOC,
        battery_capacity_kWh: float = StorageSettings.CAPACITY,
        max_abs_battery_power_kW: float = StorageSettings.MAX_ABS_POWER,
        cap_price_strategy: bool = False,
        initial_selling_rate: Union[
            float, dict] = StorageSettings.SELLING_RATE_RANGE.initial,
        final_selling_rate: Union[
            float, dict] = StorageSettings.SELLING_RATE_RANGE.final,
        initial_buying_rate: Union[
            float, dict] = StorageSettings.BUYING_RATE_RANGE.initial,
        final_buying_rate: Union[
            float, dict] = StorageSettings.BUYING_RATE_RANGE.final,
        loss_per_hour=StorageSettings.LOSS_PER_HOUR,
        loss_function=StorageSettings.LOSS_FUNCTION,
        fit_to_limit=True,
        energy_rate_increase_per_update=None,
        energy_rate_decrease_per_update=None,
        update_interval=None,
        initial_energy_origin: Enum = ESSEnergyOrigin.EXTERNAL,
        balancing_energy_ratio: tuple = (
            BalancingSettings.OFFER_DEMAND_RATIO,
            BalancingSettings.OFFER_SUPPLY_RATIO)):

        if update_interval is None:
            update_interval = \
                duration(minutes=ConstSettings.GeneralSettings.DEFAULT_UPDATE_INTERVAL)

        if min_allowed_soc is None:
            min_allowed_soc = StorageSettings.MIN_ALLOWED_SOC
        self.initial_soc = initial_soc

        StorageValidator.validate(
            initial_soc=initial_soc,
            min_allowed_soc=min_allowed_soc,
            battery_capacity_kWh=battery_capacity_kWh,
            max_abs_battery_power_kW=max_abs_battery_power_kW,
            loss_per_hour=loss_per_hour,
            loss_function=loss_function,
            fit_to_limit=fit_to_limit,
            energy_rate_increase_per_update=energy_rate_increase_per_update,
            energy_rate_decrease_per_update=energy_rate_decrease_per_update)

        if isinstance(update_interval, int):
            update_interval = duration(minutes=update_interval)

        BidEnabledStrategy.__init__(self)

        self.offer_update = \
            TemplateStrategyOfferUpdater(
                initial_rate=initial_selling_rate,
                final_rate=final_selling_rate,
                fit_to_limit=fit_to_limit,
                energy_rate_change_per_update=energy_rate_decrease_per_update,
                update_interval=update_interval)
        for time_slot in self.offer_update.initial_rate_profile_buffer.keys():
            StorageValidator.validate(
                initial_selling_rate=self.offer_update.
                initial_rate_profile_buffer[time_slot],
                final_selling_rate=find_object_of_same_weekday_and_time(
                    self.offer_update.final_rate_profile_buffer, time_slot))
        self.bid_update = \
            TemplateStrategyBidUpdater(
                initial_rate=initial_buying_rate,
                final_rate=final_buying_rate,
                fit_to_limit=fit_to_limit,
                energy_rate_change_per_update=energy_rate_increase_per_update,
                update_interval=update_interval,
                rate_limit_object=min
            )
        for time_slot in self.bid_update.initial_rate_profile_buffer.keys():
            StorageValidator.validate(
                initial_buying_rate=self.bid_update.
                initial_rate_profile_buffer[time_slot],
                final_buying_rate=find_object_of_same_weekday_and_time(
                    self.bid_update.final_rate_profile_buffer, time_slot))
        self.state = \
            StorageState(initial_soc=initial_soc,
                         initial_energy_origin=initial_energy_origin,
                         capacity=battery_capacity_kWh,
                         max_abs_battery_power_kW=max_abs_battery_power_kW,
                         loss_per_hour=loss_per_hour,
                         loss_function=loss_function,
                         min_allowed_soc=min_allowed_soc)
        self.cap_price_strategy = cap_price_strategy
        self.balancing_energy_ratio = BalancingRatio(*balancing_energy_ratio)