def set_grid_fees_callback(self, payload):
     grid_fees_response_channel = f"{self.channel_prefix}/response/grid_fees"
     payload_data = json.loads(payload["data"])
     validate_area(grid_fee_percentage=payload_data.get(
         "fee_percent", None),
                   grid_fee_constant=payload_data.get("fee_const", None))
     if "fee_const" in payload_data and payload_data["fee_const"] is not None and \
             self.area.config.grid_fee_type == 1:
         self.area.grid_fee_constant = payload_data["fee_const"]
         self.redis_db.publish_json(
             grid_fees_response_channel, {
                 "status": "ready",
                 "command": "grid_fees",
                 "market_fee_const": str(self.area.grid_fee_constant),
                 "transaction_id": payload_data.get("transaction_id", None)
             })
     elif "fee_percent" in payload_data and payload_data["fee_percent"] is not None and \
             self.area.config.grid_fee_type == 2:
         self.area.grid_fee_percentage = payload_data["fee_percent"]
         self.redis_db.publish_json(
             grid_fees_response_channel, {
                 "status": "ready",
                 "command": "grid_fees",
                 "market_fee_percent": str(self.area.grid_fee_percentage),
                 "transaction_id": payload_data.get("transaction_id", None)
             })
     else:
         self.redis_db.publish_json(
             grid_fees_response_channel, {
                 "command": "grid_fees",
                 "status": "error",
                 "error_message":
                 "GridFee parameter conflicting with GlobalConfigFeeType",
                 "transaction_id": payload_data.get("transaction_id", None)
             })
Пример #2
0
    def area_reconfigure_event(self, **kwargs):
        """Reconfigure the device properties at runtime using the provided arguments."""
        if self.strategy is not None:
            self.strategy.area_reconfigure_event(**kwargs)
            return True

        grid_fee_constant = (
            kwargs["grid_fee_constant"]
            if key_in_dict_and_not_none(kwargs, "grid_fee_constant")
            else self.grid_fee_constant)
        grid_fee_percentage = (
            kwargs["grid_fee_percentage"]
            if key_in_dict_and_not_none(kwargs, "grid_fee_percentage")
            else self.grid_fee_percentage)

        baseline_peak_energy_import_kWh = (
            kwargs["baseline_peak_energy_import_kWh"]
            if key_in_dict_and_not_none(
                kwargs, "baseline_peak_energy_import_kWh")
            else self.throughput.baseline_peak_energy_import_kWh)

        baseline_peak_energy_export_kWh = (
            kwargs["baseline_peak_energy_export_kWh"]
            if key_in_dict_and_not_none(
                kwargs, "baseline_peak_energy_export_kWh")
            else self.throughput.baseline_peak_energy_export_kWh)

        import_capacity_kVA = (
            kwargs["import_capacity_kVA"]
            if key_in_dict_and_not_none(kwargs, "import_capacity_kVA")
            else self.throughput.import_capacity_kVA)

        export_capacity_kVA = (
            kwargs["export_capacity_kVA"]
            if key_in_dict_and_not_none(kwargs, "export_capacity_kVA")
            else self.throughput.import_capacity_kVA)

        try:
            validate_area(grid_fee_constant=grid_fee_constant,
                          grid_fee_percentage=grid_fee_percentage)
            throughput = ThroughputParameters(
                            baseline_peak_energy_import_kWh=baseline_peak_energy_import_kWh,
                            baseline_peak_energy_export_kWh=baseline_peak_energy_export_kWh,
                            import_capacity_kVA=import_capacity_kVA,
                            export_capacity_kVA=export_capacity_kVA
                        )

        except Exception as ex:
            log.error(ex)
            return

        self._set_grid_fees(grid_fee_constant, grid_fee_percentage)
        self.throughput = throughput
        self._update_descendants_strategy_prices()
Пример #3
0
    def area_reconfigure_event(self, **kwargs):
        if self.strategy is not None:
            self.strategy.area_reconfigure_event(**kwargs)
            return
        if key_in_dict_and_not_none(kwargs, 'transfer_fee_const') or \
                key_in_dict_and_not_none(kwargs, 'grid_fee_percentage'):
            transfer_fee_const = kwargs["transfer_fee_const"] \
                if key_in_dict_and_not_none(kwargs, 'transfer_fee_const') else None
            grid_fee_percentage = kwargs["grid_fee_percentage"] \
                if key_in_dict_and_not_none(kwargs, 'grid_fee_percentage') else None
            validate_area(grid_fee_percentage=grid_fee_percentage,
                          grid_fee_constant=transfer_fee_const)
            self._set_grid_fees(transfer_fee_const, grid_fee_percentage)

        if key_in_dict_and_not_none(kwargs, 'baseline_peak_energy_import_kWh'):
            self.baseline_peak_energy_import_kWh = kwargs[
                'baseline_peak_energy_import_kWh']
            validate_area(baseline_peak_energy_import_kWh=self.
                          baseline_peak_energy_import_kWh)
        if key_in_dict_and_not_none(kwargs, 'baseline_peak_energy_export_kWh'):
            self.baseline_peak_energy_export_kWh = kwargs[
                'baseline_peak_energy_export_kWh']
            validate_area(baseline_peak_energy_export_kWh=self.
                          baseline_peak_energy_export_kWh)

        if key_in_dict_and_not_none(kwargs, 'import_capacity_kVA') or \
                key_in_dict_and_not_none(kwargs, 'export_capacity_kVA'):
            import_capacity_kVA = kwargs["import_capacity_kVA"] \
                if key_in_dict_and_not_none(kwargs, 'import_capacity_kVA') else None
            export_capacity_kVA = kwargs["export_capacity_kVA"] \
                if key_in_dict_and_not_none(kwargs, 'export_capacity_kVA') else None
            validate_area(import_capacity_kVA=import_capacity_kVA,
                          export_capacity_kVA=export_capacity_kVA)
            self._convert_area_throughput_kva_to_kwh(import_capacity_kVA,
                                                     export_capacity_kVA)
Пример #4
0
    def __init__(self, name: str = None, children: List["Area"] = None,
                 uuid: str = None,
                 strategy: BaseStrategy = None,
                 config: SimulationConfig = None,
                 budget_keeper=None,
                 balancing_spot_trade_ratio=ConstSettings.BalancingSettings.SPOT_TRADE_RATIO,
                 event_list=[],
                 grid_fee_percentage: float = None,
                 grid_fee_constant: float = None,
                 external_connection_available: bool = False,
                 throughput: ThroughputParameters = ThroughputParameters()
                 ):
        validate_area(grid_fee_constant=grid_fee_constant,
                      grid_fee_percentage=grid_fee_percentage)
        self.balancing_spot_trade_ratio = balancing_spot_trade_ratio
        self.active = False
        self.log = TaggedLogWrapper(log, name)
        self.current_tick = 0
        self.__name = name
        self.throughput = throughput
        self.uuid = uuid if uuid is not None else str(uuid4())
        self.slug = slugify(name, to_lower=True)
        self.parent = None
        self.children = AreaChildrenList(self, children) if children is not None\
            else AreaChildrenList(self)
        for child in self.children:
            child.parent = self

        if (len(self.children) > 0) and (strategy is not None):
            raise AreaException("A leaf area can not have children.")
        self.strategy = strategy
        self._config = config
        self.events = Events(event_list, self)
        self.budget_keeper = budget_keeper
        if budget_keeper:
            self.budget_keeper.area = self
        self._bc = None
        self._markets = None
        self.dispatcher = DispatcherFactory(self)()
        self._set_grid_fees(grid_fee_constant, grid_fee_percentage)
        self.display_type = "Area" if self.strategy is None else self.strategy.__class__.__name__
        self._markets = AreaMarkets(self.log)
        self.stats = AreaStats(self._markets, self)
        log.debug("External connection %s for area %s", external_connection_available, self.name)
        self.redis_ext_conn = RedisMarketExternalConnection(self) \
            if external_connection_available and self.strategy is None else None
        self.should_update_child_strategies = False
        self.external_connection_available = external_connection_available
Пример #5
0
    def set_grid_fees_callback(self, payload):
        # TODO: This function should reuse the area_reconfigure_event function
        # since they share the same functionality.
        grid_fees_response_channel = f"{self.channel_prefix}/response/grid_fees"
        payload_data = payload["data"] \
            if isinstance(payload["data"], dict) else json.loads(payload["data"])
        try:
            validate_area(
                grid_fee_percentage=payload_data.get("fee_percent", None),
                grid_fee_constant=payload_data.get("fee_const", None))
        except Exception as e:
            log.error(str(e))
            return

        base_dict = {"area_uuid": self.area.uuid, "command": "grid_fees"}
        if "fee_const" in payload_data and payload_data["fee_const"] is not None and \
                self.area.config.grid_fee_type == 1:
            self.area.grid_fee_constant = payload_data["fee_const"]
            ret_val = {
                "status": "ready",
                "market_fee_const": str(self.area.grid_fee_constant),
                **base_dict
            }
        elif "fee_percent" in payload_data and payload_data["fee_percent"] is not None and \
                self.area.config.grid_fee_type == 2:
            self.area.grid_fee_percentage = payload_data["fee_percent"]
            ret_val = {
                "status": "ready",
                "market_fee_percent": str(self.area.grid_fee_percentage),
                **base_dict
            }
        else:
            ret_val = {
                "status": "error",
                "error_message":
                "GridFee parameter conflicting with GlobalConfigFeeType",
                **base_dict
            }

        self.area.should_update_child_strategies = True

        if self.is_aggregator_controlled:
            return ret_val
        else:
            ret_val["transaction_id"] = payload_data.get(
                "transaction_id", None)
            self.redis_com.publish_json(grid_fees_response_channel, ret_val)
Пример #6
0
    def __init__(self,
                 name: str = None,
                 children: List["Area"] = None,
                 uuid: str = None,
                 strategy: BaseStrategy = None,
                 appliance: BaseAppliance = None,
                 config: SimulationConfig = None,
                 budget_keeper=None,
                 balancing_spot_trade_ratio=ConstSettings.BalancingSettings.
                 SPOT_TRADE_RATIO,
                 event_list=[],
                 grid_fee_percentage: float = None,
                 transfer_fee_const: float = None,
                 external_connection_available=False):
        validate_area(grid_fee_percentage=grid_fee_percentage)
        self.balancing_spot_trade_ratio = balancing_spot_trade_ratio
        self.active = False
        self.log = TaggedLogWrapper(log, name)
        self.current_tick = 0
        self.name = name
        self.uuid = uuid if uuid is not None else str(uuid4())
        self.slug = slugify(name, to_lower=True)
        self.parent = None
        self.children = children if children is not None else []
        for child in self.children:
            child.parent = self

        if (len(self.children) > 0) and (strategy is not None):
            raise AreaException("A leaf area can not have children.")
        self.strategy = strategy
        self.appliance = appliance
        self._config = config
        self.events = Events(event_list, self)
        self.budget_keeper = budget_keeper
        if budget_keeper:
            self.budget_keeper.area = self
        self._bc = None
        self._markets = None
        self.dispatcher = DispatcherFactory(self)()
        self.grid_fee_percentage = grid_fee_percentage
        self.transfer_fee_const = transfer_fee_const
        self.display_type = "Area" if self.strategy is None else self.strategy.__class__.__name__
        self._markets = AreaMarkets(self.log)
        self.stats = AreaStats(self._markets)
        self.redis_ext_conn = RedisAreaExternalConnection(self) \
            if external_connection_available is True else None
Пример #7
0
 def test_area_setting(self):
     self.assertIsNone(validate_area())
     self.assertIsNone(validate_area(grid_fee_percentage=None))
     self.assertIsNone(validate_area(grid_fee_percentage=1))
     with self.assertRaises(D3ADeviceException):
         validate_area(grid_fee_percentage=-1)
     with self.assertRaises(D3ADeviceException):
         validate_area(grid_fee_percentage=101)
Пример #8
0
    def __init__(self,
                 baseline_peak_energy_import_kWh: float = None,
                 baseline_peak_energy_export_kWh: float = None,
                 import_capacity_kVA: float = None,
                 export_capacity_kVA: float = None):

        validate_area(
            baseline_peak_energy_import_kWh=baseline_peak_energy_import_kWh,
            baseline_peak_energy_export_kWh=baseline_peak_energy_export_kWh,
            import_capacity_kVA=import_capacity_kVA,
            export_capacity_kVA=export_capacity_kVA)

        self.import_capacity_kVA = import_capacity_kVA
        self.export_capacity_kVA = export_capacity_kVA
        self.import_capacity_kWh = convert_area_throughput_kVA_to_kWh(
            import_capacity_kVA, GlobalConfig.slot_length)
        self.export_capacity_kWh = convert_area_throughput_kVA_to_kWh(
            export_capacity_kVA, GlobalConfig.slot_length)
        self.baseline_peak_energy_import_kWh = baseline_peak_energy_import_kWh
        self.baseline_peak_energy_export_kWh = baseline_peak_energy_export_kWh
 def test_area_setting(self):
     self.assertIsNone(validate_area())
     self.assertIsNone(validate_area(grid_fee_percentage=None))
     self.assertIsNone(validate_area(grid_fee_percentage=1))
     self.assertIsNone(
         validate_area(grid_fee_percentage=1, grid_fee_constant=0))
     self.assertIsNone(
         validate_area(grid_fee_percentage=0, grid_fee_constant=1))
     with self.assertRaises(D3ADeviceException):
         validate_area(grid_fee_percentage=-1)
     with self.assertRaises(D3ADeviceException):
         validate_area(grid_fee_percentage=101)
     with self.assertRaises(D3AAreaException):
         validate_area(baseline_peak_energy_import_kWh=-1.0)
     with self.assertRaises(D3AAreaException):
         validate_area(baseline_peak_energy_export_kWh=-1.0)
     with self.assertRaises(D3AAreaException):
         validate_area(import_capacity_kVA=-1.0)
     with self.assertRaises(D3AAreaException):
         validate_area(export_capacity_kVA=-1.0)
Пример #10
0
    def __init__(self,
                 name: str = None,
                 children: List["Area"] = None,
                 uuid: str = None,
                 strategy: BaseStrategy = None,
                 appliance: BaseAppliance = None,
                 config: SimulationConfig = None,
                 budget_keeper=None,
                 balancing_spot_trade_ratio=ConstSettings.BalancingSettings.
                 SPOT_TRADE_RATIO,
                 event_list=[],
                 grid_fee_percentage: float = None,
                 transfer_fee_const: float = None,
                 external_connection_available: bool = False,
                 baseline_peak_energy_import_kWh: float = None,
                 baseline_peak_energy_export_kWh: float = None,
                 import_capacity_kVA: float = None,
                 export_capacity_kVA: float = None):
        validate_area(
            grid_fee_constant=transfer_fee_const,
            grid_fee_percentage=grid_fee_percentage,
            baseline_peak_energy_import_kWh=baseline_peak_energy_import_kWh,
            baseline_peak_energy_export_kWh=baseline_peak_energy_export_kWh,
            import_capacity_kVA=import_capacity_kVA,
            export_capacity_kVA=export_capacity_kVA)
        self.balancing_spot_trade_ratio = balancing_spot_trade_ratio
        self.active = False
        self.log = TaggedLogWrapper(log, name)
        self.current_tick = 0
        self.name = name
        self.baseline_peak_energy_import_kWh = baseline_peak_energy_import_kWh
        self.baseline_peak_energy_export_kWh = baseline_peak_energy_export_kWh
        self.uuid = uuid if uuid is not None else str(uuid4())
        self.slug = slugify(name, to_lower=True)
        self.parent = None
        self.children = children if children is not None else []
        for child in self.children:
            child.parent = self

        if (len(self.children) > 0) and (strategy is not None):
            raise AreaException("A leaf area can not have children.")
        self.strategy = strategy
        self.appliance = appliance
        self._config = config
        self.events = Events(event_list, self)
        self.budget_keeper = budget_keeper
        if budget_keeper:
            self.budget_keeper.area = self
        self._bc = None
        self._markets = None
        self.dispatcher = DispatcherFactory(self)()
        self._set_grid_fees(transfer_fee_const, grid_fee_percentage)
        self._convert_area_throughput_kva_to_kwh(import_capacity_kVA,
                                                 export_capacity_kVA)
        self.display_type = "Area" if self.strategy is None else self.strategy.__class__.__name__
        self._markets = AreaMarkets(self.log)
        self.endpoint_stats = {}
        self.stats = AreaStats(self._markets)
        log.debug(
            f"External connection {external_connection_available} for area {self.name}"
        )
        self.redis_ext_conn = RedisMarketExternalConnection(self) \
            if external_connection_available is True else None