예제 #1
0
파일: pv.py 프로젝트: insignal-ai/d3a
    def _area_reconfigure_prices(self, validate=True, **kwargs):
        if validate:
            validate_pv_device_price(**kwargs)

        if key_in_dict_and_not_none(kwargs, 'initial_selling_rate'):
            self.offer_update.initial_rate = read_arbitrary_profile(
                InputProfileTypes.IDENTITY, kwargs['initial_selling_rate'])
        if key_in_dict_and_not_none(kwargs, 'final_selling_rate'):
            self.offer_update.final_rate = read_arbitrary_profile(
                InputProfileTypes.IDENTITY, kwargs['final_selling_rate'])
        if key_in_dict_and_not_none(kwargs, 'energy_rate_decrease_per_update'):
            self.offer_update.energy_rate_change_per_update = \
                read_arbitrary_profile(InputProfileTypes.IDENTITY,
                                       kwargs['energy_rate_decrease_per_update'])
        if key_in_dict_and_not_none(kwargs, 'fit_to_limit'):
            self.offer_update.fit_to_limit = kwargs['fit_to_limit']
        if key_in_dict_and_not_none(kwargs, 'update_interval'):
            if isinstance(kwargs['update_interval'], int):
                update_interval = duration(minutes=kwargs['update_interval'])
            else:
                update_interval = kwargs['update_interval']
            self.offer_update.update_interval = update_interval
        if key_in_dict_and_not_none(kwargs, 'use_market_maker_rate'):
            self.use_market_maker_rate = kwargs['use_market_maker_rate']

        self._validate_rates()
        self.offer_update.update_offer(self)
예제 #2
0
 def __init__(
         self,
         initial_rate,
         final_rate,
         fit_to_limit=True,
         energy_rate_change_per_update=None,
         update_interval=duration(
             minutes=ConstSettings.GeneralSettings.DEFAULT_UPDATE_INTERVAL),
         rate_limit_object=max):
     self.fit_to_limit = fit_to_limit
     self.initial_rate = read_arbitrary_profile(InputProfileTypes.IDENTITY,
                                                initial_rate)
     self.final_rate = read_arbitrary_profile(InputProfileTypes.IDENTITY,
                                              final_rate)
     if fit_to_limit is False:
         self.energy_rate_change_per_update = \
             read_arbitrary_profile(InputProfileTypes.IDENTITY,
                                    energy_rate_change_per_update)
     else:
         self.energy_rate_change_per_update = None
     self.update_interval = update_interval
     self.update_counter = read_arbitrary_profile(
         InputProfileTypes.IDENTITY, 0)
     self.number_of_available_updates = 0
     self.rate_limit_object = rate_limit_object
예제 #3
0
def test_if_storage_doesnt_buy_too_expensive(storage_strategy_test3, area_test3):
    from d3a.models.read_user_profile import read_arbitrary_profile, InputProfileTypes
    storage_strategy_test3.bid_update.initial_rate = \
        read_arbitrary_profile(InputProfileTypes.IDENTITY, 0)
    storage_strategy_test3.bid_update.final_rate = \
        read_arbitrary_profile(InputProfileTypes.IDENTITY, 1)
    storage_strategy_test3.event_activate()
    storage_strategy_test3.event_tick()
    assert len(storage_strategy_test3.accept_offer.calls) == 0
예제 #4
0
    def __init__(
            self,
            risk: int = GeneralSettings.DEFAULT_RISK,
            initial_capacity_kWh: float = StorageSettings.MIN_ALLOWED_SOC *
        StorageSettings.CAPACITY,
            initial_soc: float = None,
            initial_rate_option: int = StorageSettings.INITIAL_RATE_OPTION,
            energy_rate_decrease_option: int = StorageSettings.
        RATE_DECREASE_OPTION,
            energy_rate_decrease_per_update: float = GeneralSettings.
        ENERGY_RATE_DECREASE_PER_UPDATE,  # NOQA
            battery_capacity_kWh: float = StorageSettings.CAPACITY,
            max_abs_battery_power_kW: float = StorageSettings.MAX_ABS_POWER,
            break_even: Union[tuple, dict] = (StorageSettings.BREAK_EVEN_BUY,
                                              StorageSettings.BREAK_EVEN_SELL),
            balancing_energy_ratio: tuple = (
                BalancingSettings.OFFER_DEMAND_RATIO,
                BalancingSettings.OFFER_SUPPLY_RATIO),
            cap_price_strategy: bool = False,
            min_allowed_soc=None):

        if min_allowed_soc is None:
            min_allowed_soc = StorageSettings.MIN_ALLOWED_SOC
        break_even = read_arbitrary_profile(InputProfileTypes.IDENTITY,
                                            break_even)
        self._validate_constructor_arguments(risk, initial_capacity_kWh,
                                             initial_soc, battery_capacity_kWh,
                                             break_even, min_allowed_soc)
        self.break_even = break_even

        self.min_selling_rate = list(break_even.values())[0][1]
        BaseStrategy.__init__(self)
        OfferUpdateFrequencyMixin.__init__(self, initial_rate_option,
                                           energy_rate_decrease_option,
                                           energy_rate_decrease_per_update)
        # Normalize min/max buying rate profiles before passing to the bid mixin
        self.min_buying_rate_profile = read_arbitrary_profile(
            InputProfileTypes.IDENTITY, StorageSettings.MIN_BUYING_RATE)
        self.max_buying_rate_profile = {k: v[1] for k, v in break_even.items()}
        BidUpdateFrequencyMixin.__init__(
            self,
            initial_rate_profile=self.min_buying_rate_profile,
            final_rate_profile=self.max_buying_rate_profile)

        self.risk = risk
        self.state = StorageState(
            initial_capacity_kWh=initial_capacity_kWh,
            initial_soc=initial_soc,
            capacity=battery_capacity_kWh,
            max_abs_battery_power_kW=max_abs_battery_power_kW,
            loss_per_hour=0.0,
            strategy=self,
            min_allowed_soc=min_allowed_soc)
        self.cap_price_strategy = cap_price_strategy
        self.balancing_energy_ratio = BalancingRatio(*balancing_energy_ratio)
예제 #5
0
파일: pv.py 프로젝트: xg86/d3a
    def _area_reconfigure_prices(self, validate=True, **kwargs):
        if validate:
            validate_pv_device_price(**kwargs)

        if 'initial_selling_rate' in kwargs and kwargs[
                'initial_selling_rate'] is not None:
            self.offer_update.initial_rate = read_arbitrary_profile(
                InputProfileTypes.IDENTITY, kwargs['initial_selling_rate'])
        if 'final_selling_rate' in kwargs and kwargs[
                'final_selling_rate'] is not None:
            self.offer_update.final_rate = read_arbitrary_profile(
                InputProfileTypes.IDENTITY, kwargs['final_selling_rate'])

        self._validate_rates()
        self.offer_update.update_offer(self)
예제 #6
0
    def _read_predefined_profile_for_pv(self) -> Dict[DateTime, float]:
        """
        Reads profile data from the predefined power profiles. Reads config and constructor
        parameters and selects the appropriate predefined profile.
        :return: key value pairs of time to energy in kWh
        """
        if self._power_profile_index is None or self._power_profile_index == 4:
            if self.owner.config.pv_user_profile is not None:
                return self.owner.config.pv_user_profile
            else:
                self._power_profile_index = self.owner.config.cloud_coverage
        if self._power_profile_index == 0:  # 0:sunny
            profile_path = pathlib.Path(d3a_path +
                                        '/resources/Solar_Curve_W_sunny.csv')
        elif self._power_profile_index == 1:  # 1:partial
            profile_path = pathlib.Path(d3a_path +
                                        '/resources/Solar_Curve_W_partial.csv')
        elif self._power_profile_index == 2:  # 2:cloudy
            profile_path = pathlib.Path(d3a_path +
                                        '/resources/Solar_Curve_W_cloudy.csv')
        else:
            raise ValueError("Energy_profile has to be in [0,1,2]")

        # Populate energy production forecast data
        return read_arbitrary_profile(InputProfileTypes.POWER,
                                      str(profile_path))
예제 #7
0
 def _read_predefined_profile_for_pv(self) -> Dict[DateTime, float]:
     """
     Reads profile data from the power profile. Handles csv files and dicts.
     :return: key value pairs of time to energy in kWh
     """
     return read_arbitrary_profile(InputProfileTypes.POWER,
                                   self._power_profile_W)
예제 #8
0
def test_correct_time_expansion_read_arbitrary_profile():
    market_maker_rate = 30
    GlobalConfig.sim_duration = duration(hours=3)
    mmr = read_arbitrary_profile(InputProfileTypes.IDENTITY, market_maker_rate)
    assert (list(mmr.keys())[-1] - today(tz=TIME_ZONE)).days == 0
    GlobalConfig.sim_duration = duration(hours=36)
    mmr = read_arbitrary_profile(InputProfileTypes.IDENTITY, market_maker_rate)
    assert (list(mmr.keys())[-1] - today(tz=TIME_ZONE)).days == 1
    GlobalConfig.sim_duration = duration(hours=48)
    mmr = read_arbitrary_profile(InputProfileTypes.IDENTITY, market_maker_rate)
    assert (list(mmr.keys())[-1] - today(tz=TIME_ZONE)).days == 2
    GlobalConfig.sim_duration = duration(hours=49)
    mmr = read_arbitrary_profile(InputProfileTypes.IDENTITY, market_maker_rate)
    # read_arbitrary_profile expands until 01:00 after the last day in sim_duration
    # because of the future markets
    assert (sorted(list(mmr.keys()))[-1] == today(tz=TIME_ZONE).add(hours=49))
예제 #9
0
    def __init__(self, avg_power_W, hrs_per_day=None, hrs_of_day=None, daily_budget=None,
                 min_energy_rate: Union[float, dict, str] =
                 ConstSettings.LoadSettings.MIN_ENERGY_RATE,
                 max_energy_rate: Union[float, dict, str] =
                 ConstSettings.LoadSettings.MAX_ENERGY_RATE,
                 balancing_energy_ratio: tuple =
                 (ConstSettings.BalancingSettings.OFFER_DEMAND_RATIO,
                  ConstSettings.BalancingSettings.OFFER_SUPPLY_RATIO)):

        BaseStrategy.__init__(self)
        self.min_energy_rate = read_arbitrary_profile(InputProfileTypes.IDENTITY,
                                                      min_energy_rate)
        self.max_energy_rate = read_arbitrary_profile(InputProfileTypes.IDENTITY,
                                                      max_energy_rate)
        BidUpdateFrequencyMixin.__init__(self,
                                         initial_rate_profile=self.min_energy_rate,
                                         final_rate_profile=self.max_energy_rate)
        self.state = LoadState()
        self.avg_power_W = avg_power_W

        # consolidated_cycle is KWh energy consumed for the entire year
        self.daily_energy_required = None
        # Budget for a single day in eur
        self.daily_budget = daily_budget * 100 if daily_budget is not None else None
        # Energy consumed during the day ideally should not exceed daily_energy_required
        self.energy_per_slot_Wh = None
        self.energy_requirement_Wh = {}  # type: Dict[Time, float]
        self.hrs_per_day = {}  # type: Dict[int, int]

        if hrs_of_day is None:
            hrs_of_day = list(range(24))

        # be a parameter on the constructor or if we want to deal in percentages
        if hrs_per_day is None:
            hrs_per_day = len(hrs_of_day)
        if hrs_of_day is None:
            hrs_of_day = list(range(24))

        self.hrs_of_day = hrs_of_day
        self._initial_hrs_per_day = hrs_per_day
        self.balancing_energy_ratio = BalancingRatio(*balancing_energy_ratio)

        if not all([0 <= h <= 23 for h in hrs_of_day]):
            raise ValueError("Hrs_of_day list should contain integers between 0 and 23.")

        if len(hrs_of_day) < hrs_per_day:
            raise ValueError("Length of list 'hrs_of_day' must be greater equal 'hrs_per_day'")
예제 #10
0
    def event_activate(self):
        super().event_activate()

        load_profile_raw_kg = read_arbitrary_profile(
            InputProfileTypes.IDENTITY, self.discharge_profile)

        for key, value in load_profile_raw_kg.items():
            self.load_profile_kWh[key] = value * self.conversion_factor_kWh_kg
예제 #11
0
 def _event_activate_energy(self, daily_load_profile):
     """
     Reads the power profile data and calculates the required energy
     for each slot.
     """
     load_profile = read_arbitrary_profile(InputProfileTypes.POWER,
                                           daily_load_profile)
     self._update_energy_requirement(load_profile)
예제 #12
0
def test_correct_interpolation_power_profile():
    slot_length = 20
    GlobalConfig.slot_length = duration(minutes=slot_length)
    profile_path = pathlib.Path(d3a_path + '/resources/Solar_Curve_W_sunny.csv')
    profile = read_arbitrary_profile(InputProfileTypes.POWER, str(profile_path))
    times = list(profile)
    for ii in range(len(times)-1):
        assert abs((times[ii]-times[ii+1]).in_seconds()) == slot_length * 60
예제 #13
0
def hour_profile_of_market_maker_rate(context, scenario):
    import importlib
    from d3a.models.read_user_profile import InputProfileTypes
    setup_file_module = importlib.import_module(
        "d3a.setup.{}".format(scenario))
    context._market_maker_rate = \
        read_arbitrary_profile(InputProfileTypes.IDENTITY, setup_file_module.market_maker_rate)
    assert context._market_maker_rate is not None
예제 #14
0
 def event_activate(self):
     """
     Runs on activate event. Reads the power profile data and calculates the required energy
     for each slot.
     :return: None
     """
     self.bid_update.update_on_activate()
     self.load_profile = read_arbitrary_profile(InputProfileTypes.POWER,
                                                self.daily_load_profile)
     self._update_energy_requirement()
예제 #15
0
    def area_reconfigure_event(self, validate=True, **kwargs):
        assert all(k in self.parameters for k in kwargs.keys())
        if validate:
            validate_pv_device(**kwargs)
        for name, value in kwargs.items():
            setattr(self, name, value)

        if 'initial_selling_rate' in kwargs and kwargs[
                'initial_selling_rate'] is not None:
            self.offer_update.initial_rate = read_arbitrary_profile(
                InputProfileTypes.IDENTITY, kwargs['initial_selling_rate'])
        if 'final_selling_rate' in kwargs and kwargs[
                'final_selling_rate'] is not None:
            self.offer_update.final_rate = read_arbitrary_profile(
                InputProfileTypes.IDENTITY, kwargs['final_selling_rate'])

        self._validate_rates()
        self.produced_energy_forecast_kWh()
        self.offer_update.update_offer(self)
예제 #16
0
 def read_market_maker_rate(self, market_maker_rate):
     """
     Reads market_maker_rate from arbitrary input types
     """
     market_maker_rate_parsed = ast.literal_eval(str(market_maker_rate))
     self.market_maker_rate = read_arbitrary_profile(
         InputProfileTypes.IDENTITY, market_maker_rate_parsed)
     self.market_maker_rate = {
         k: float(v)
         for k, v in self.market_maker_rate.items()
     }
예제 #17
0
def check_pv_csv_profile(context):
    house1 = list(
        filter(lambda x: x.name == "House 1",
               context.simulation.area.children))[0]
    pv = list(filter(lambda x: x.name == "H1 PV", house1.children))[0]
    from d3a.setup.strategy_tests.user_profile_pv_csv import user_profile_path
    profile_data = read_arbitrary_profile(InputProfileTypes.POWER,
                                          user_profile_path)
    for timepoint, energy in pv.strategy.energy_production_forecast_kWh.items(
    ):
        if timepoint in profile_data.keys():
            assert energy == profile_data[timepoint]
        else:
            assert energy == 0
예제 #18
0
파일: predefined_load.py 프로젝트: xg86/d3a
 def event_activate(self):
     """
     Runs on activate event. Reads the power profile data and calculates the required energy
     for each slot.
     :return: None
     """
     # If use_market_maker_rate is true, overwrite final_buying_rate to market maker rate
     if self.use_market_maker_rate:
         self.area_reconfigure_event(final_buying_rate=GlobalConfig.market_maker_rate)
     self._validate_rates()
     self.bid_update.update_on_activate()
     self.load_profile = read_arbitrary_profile(
         InputProfileTypes.POWER,
         self.daily_load_profile)
     self._update_energy_requirement()
예제 #19
0
def check_pv_profile_csv(context):
    house1 = list(
        filter(lambda x: x.name == "House 1",
               context.simulation.area.children))[0]
    pv = list(filter(lambda x: x.name == "H1 PV", house1.children))[0]
    input_profile = read_arbitrary_profile(InputProfileTypes.POWER,
                                           context._device_profile)
    produced_energy = {
        from_format(f'{TODAY_STR}T{k.hour:02}:{k.minute:02}',
                    DATE_TIME_FORMAT): v
        for k, v in pv.strategy.energy_production_forecast_kWh.items()
    }
    for timepoint, energy in produced_energy.items():
        if timepoint in input_profile:
            assert energy == input_profile[timepoint]
        else:
            assert False
예제 #20
0
def check_pv_profile(context):
    house1 = list(
        filter(lambda x: x.name == "House 1",
               context.simulation.area.children))[0]
    pv = list(filter(lambda x: x.name == "H1 PV", house1.children))[0]
    if pv.strategy._power_profile_index == 0:
        path = os.path.join(d3a_path, "resources/Solar_Curve_W_sunny.csv")
    if pv.strategy._power_profile_index == 1:
        path = os.path.join(d3a_path, "resources/Solar_Curve_W_partial.csv")
    if pv.strategy._power_profile_index == 2:
        path = os.path.join(d3a_path, "resources/Solar_Curve_W_cloudy.csv")
    profile_data = read_arbitrary_profile(InputProfileTypes.POWER, str(path))
    for timepoint, energy in pv.strategy.energy_production_forecast_kWh.items(
    ):
        if timepoint in profile_data.keys():
            assert energy == profile_data[timepoint]
        else:
            assert energy == 0
예제 #21
0
    def area_reconfigure_event(self,
                               avg_power_W=None,
                               hrs_per_day=None,
                               hrs_of_day=None,
                               final_buying_rate=None):
        if hrs_per_day is not None or hrs_of_day is not None:
            self.assign_hours_of_per_day(hrs_of_day, hrs_per_day)
            self.hrs_per_day = {
                day: self._initial_hrs_per_day
                for day in range(self.area.config.sim_duration.days + 1)
            }

        if avg_power_W is not None:
            self.avg_power_W = avg_power_W
            self.assign_energy_requirement(avg_power_W)

        if final_buying_rate is not None:
            self.bid_update.final_rate = read_arbitrary_profile(
                InputProfileTypes.IDENTITY, final_buying_rate)
예제 #22
0
    def __init__(self,
                 duration: duration,
                 slot_length: duration,
                 tick_length: duration,
                 market_count: int,
                 cloud_coverage: int,
                 market_maker_rate,
                 iaa_fee: int,
                 pv_user_profile=None):
        self.duration = duration
        self.slot_length = slot_length
        self.tick_length = tick_length
        self.market_count = market_count
        self.ticks_per_slot = self.slot_length / self.tick_length
        if self.ticks_per_slot != int(self.ticks_per_slot):
            raise D3AException(
                "Non integer ticks per slot ({}) are not supported. "
                "Adjust simulation parameters.".format(self.ticks_per_slot))
        self.ticks_per_slot = int(self.ticks_per_slot)
        if self.ticks_per_slot < 10:
            raise D3AException(
                "Too few ticks per slot ({}). Adjust simulation parameters".
                format(self.ticks_per_slot))
        self.total_ticks = self.duration // self.slot_length * self.ticks_per_slot
        # TODO: Once the d3a uses a common API to the d3a-web, this should be removed
        # since this limitation already exists on d3a-web
        if 0 <= cloud_coverage <= 2:
            self.cloud_coverage = cloud_coverage
        else:
            raise D3AException(
                "Invalid cloud coverage value ({}).".format(cloud_coverage))

        self.pv_user_profile = None \
            if pv_user_profile is None \
            else read_arbitrary_profile(InputProfileTypes.POWER,
                                        ast.literal_eval(pv_user_profile),
                                        self.slot_length)
        self.read_market_maker_rate(market_maker_rate)

        if iaa_fee is None:
            self.iaa_fee = ConstSettings.IAASettings.FEE_PERCENTAGE
        else:
            self.iaa_fee = iaa_fee
예제 #23
0
 def _update_rate_parameters(self, initial_selling_rate, final_selling_rate,
                             initial_buying_rate, final_buying_rate,
                             energy_rate_change_per_update):
     if initial_selling_rate is not None:
         self.offer_update.initial_rate = read_arbitrary_profile(
             InputProfileTypes.IDENTITY, initial_selling_rate)
     if final_selling_rate is not None:
         self.offer_update.final_rate = read_arbitrary_profile(
             InputProfileTypes.IDENTITY, final_selling_rate)
     if initial_buying_rate is not None:
         self.bid_update.initial_rate = read_arbitrary_profile(
             InputProfileTypes.IDENTITY, initial_buying_rate)
     if final_buying_rate is not None:
         self.bid_update.final_rate = read_arbitrary_profile(
             InputProfileTypes.IDENTITY, final_buying_rate)
     if energy_rate_change_per_update is not None:
         self.offer_update.energy_rate_change_per_update = \
             read_arbitrary_profile(InputProfileTypes.IDENTITY,
                                    energy_rate_change_per_update)
         self.bid_update.energy_rate_change_per_update = \
             read_arbitrary_profile(InputProfileTypes.IDENTITY,
                                    energy_rate_change_per_update)
예제 #24
0
def _read_solar_profile(profile_path):
    return read_arbitrary_profile(InputProfileTypes.POWER, str(profile_path))
예제 #25
0
 def _validate_constructor_arguments(initial_soc=None,
                                     min_allowed_soc=None,
                                     battery_capacity_kWh=None,
                                     max_abs_battery_power_kW=None,
                                     initial_selling_rate=None,
                                     final_selling_rate=None,
                                     initial_buying_rate=None,
                                     final_buying_rate=None,
                                     energy_rate_change_per_update=None):
     if battery_capacity_kWh is not None and battery_capacity_kWh < 0:
         raise ValueError("Battery capacity should be a positive integer")
     if max_abs_battery_power_kW is not None and max_abs_battery_power_kW < 0:
         raise ValueError(
             "Battery Power rating must be a positive integer.")
     if initial_soc is not None and 0 < initial_soc > 100:
         raise ValueError("initial SOC must be in between 0-100 %")
     if min_allowed_soc is not None and 0 < min_allowed_soc > 100:
         raise ValueError("initial SOC must be in between 0-100 %")
     if initial_soc is not None and min_allowed_soc is not None and \
             initial_soc < min_allowed_soc:
         raise ValueError(
             "Initial charge must be more than the minimum allowed soc.")
     if initial_selling_rate is not None and initial_selling_rate < 0:
         raise ValueError("Initial selling rate must be greater equal 0.")
     if final_selling_rate is not None:
         if type(final_selling_rate) is float and final_selling_rate < 0:
             raise ValueError("Final selling rate must be greater equal 0.")
         elif type(final_selling_rate) is dict and \
                 any(rate < 0 for _, rate in final_selling_rate.items()):
             raise ValueError("Final selling rate must be greater equal 0.")
     if initial_selling_rate is not None and final_selling_rate is not None:
         initial_selling_rate = read_arbitrary_profile(
             InputProfileTypes.IDENTITY, initial_selling_rate)
         final_selling_rate = read_arbitrary_profile(
             InputProfileTypes.IDENTITY, final_selling_rate)
         if any(initial_selling_rate[hour] < final_selling_rate[hour]
                for hour, _ in initial_selling_rate.items()):
             raise ValueError(
                 "Initial selling rate must be greater than final selling rate."
             )
     if initial_buying_rate is not None and initial_buying_rate < 0:
         raise ValueError("Initial buying rate must be greater equal 0.")
     if final_buying_rate is not None:
         final_buying_rate = read_arbitrary_profile(
             InputProfileTypes.IDENTITY, final_buying_rate)
         if any(rate < 0 for _, rate in final_buying_rate.items()):
             raise ValueError("Final buying rate must be greater equal 0.")
     if initial_buying_rate is not None and final_buying_rate is not None:
         initial_buying_rate = read_arbitrary_profile(
             InputProfileTypes.IDENTITY, initial_buying_rate)
         final_buying_rate = read_arbitrary_profile(
             InputProfileTypes.IDENTITY, final_buying_rate)
         if any(initial_buying_rate[hour] > final_buying_rate[hour]
                for hour, _ in initial_buying_rate.items()):
             raise ValueError(
                 "Initial buying rate must be less than final buying rate.")
     if final_selling_rate is not None and final_buying_rate is not None:
         final_selling_rate = read_arbitrary_profile(
             InputProfileTypes.IDENTITY, final_selling_rate)
         final_buying_rate = read_arbitrary_profile(
             InputProfileTypes.IDENTITY, final_buying_rate)
         if any(final_buying_rate[hour] >= final_selling_rate[hour]
                for hour, _ in final_selling_rate.items()):
             raise ValueError(
                 "final_buying_rate should be higher than final_selling_rate."
             )
     if energy_rate_change_per_update is not None and energy_rate_change_per_update < 0:
         raise ValueError(
             "energy_rate_change_per_update should be a non-negative value."
         )
예제 #26
0
 def _area_reconfigure_prices(self, final_buying_rate):
     if final_buying_rate is not None:
         self.bid_update.final_rate = read_arbitrary_profile(
             InputProfileTypes.IDENTITY, final_buying_rate)
     self._validate_rates()
예제 #27
0
 def event_activate(self):
     super().event_activate()
     self.max_available_power_kW = \
         read_arbitrary_profile(InputProfileTypes.IDENTITY, self.max_available_power_kW)
예제 #28
0
 def read_pv_user_profile(self, pv_user_profile=None):
     self.pv_user_profile = None \
         if pv_user_profile is None \
         else read_arbitrary_profile(InputProfileTypes.POWER,
                                     ast.literal_eval(pv_user_profile))
예제 #29
0
 def event_activate(self):
     self.energy_rate = self.area.config.market_maker_rate if self.energy_rate is None \
         else read_arbitrary_profile(InputProfileTypes.IDENTITY, self.energy_rate)