Beispiel #1
0
def test_energy_bills_accumulate_fees(grid_fees):
    ConstSettings.GeneralSettings.KEEP_PAST_MARKETS = True
    m_bills = MarketEnergyBills()
    m_bills._update_market_fees(grid_fees, 'past_markets')
    assert m_bills.market_fees['house2'] == 0.03
    assert m_bills.market_fees['street'] == 0.05
    assert m_bills.market_fees['house1'] == 0.08
Beispiel #2
0
 def __init__(self, job_id, initial_params, area):
     self.job_id = job_id
     self.random_seed = initial_params["seed"] if initial_params[
         "seed"] is not None else ''
     self.status = {}
     self.eta = duration(seconds=0)
     self.unmatched_loads = {}
     self.unmatched_loads_redis = {}
     self.export_unmatched_loads = ExportUnmatchedLoads(area)
     self.market_unmatched_loads = MarketUnmatchedLoads()
     self.cumulative_loads = {}
     self.price_energy_day = MarketPriceEnergyDay()
     self.cumulative_grid_trades = {}
     self.accumulated_trades = {}
     self.accumulated_trades_redis = {}
     self.accumulated_balancing_trades = {}
     self.cumulative_grid_trades_redis = {}
     self.cumulative_grid_balancing_trades = {}
     self.tree_summary = {}
     self.tree_summary_redis = {}
     self.market_bills = MarketEnergyBills()
     self.balancing_bills = MarketEnergyBills(is_spot_market=False)
     self.trade_details = {}
     self.device_statistics = DeviceStatistics()
     self.energy_trade_profile = {}
     self.energy_trade_profile_redis = {}
     self.file_export_endpoints = FileExportEndpoints()
Beispiel #3
0
def test_energy_bills_use_only_last_market_if_not_keep_past_markets(grid_fees):
    ConstSettings.GeneralSettings.KEEP_PAST_MARKETS = False
    m_bills = MarketEnergyBills()
    m_bills._update_market_fees(grid_fees, 'past_markets')
    assert m_bills.market_fees['house2'] == 0.03
    assert m_bills.market_fees['street'] == 0.01
    assert m_bills.market_fees['house1'] == 0.06
Beispiel #4
0
    def __init__(self, job_id, initial_params, area, export_plots=True):
        self.job_id = job_id
        self.current_market = ""
        self.random_seed = initial_params["seed"] if initial_params[
            "seed"] is not None else ''
        self.status = {}
        self.simulation_progress = {
            "eta_seconds": 0,
            "elapsed_time_seconds": 0,
            "percentage_completed": 0
        }
        self.market_unmatched_loads = MarketUnmatchedLoads(area)
        self.price_energy_day = MarketPriceEnergyDay()
        self.market_bills = MarketEnergyBills()
        self.cumulative_bills = CumulativeBills()
        self.balancing_bills = MarketEnergyBills(is_spot_market=False)
        self.cumulative_grid_trades = CumulativeGridTrades()
        self.device_statistics = DeviceStatistics()
        self.file_export_endpoints = FileExportEndpoints(export_plots)
        self.kpi = KPI()
        self.area_throughput_stats = AreaThroughputStats()

        self.last_unmatched_loads = {}
        self.bids_offers_trades = {}
        self.export_plots = export_plots
        if export_plots:
            self.area_market_stocks_stats = OfferBidTradeGraphStats()
Beispiel #5
0
def test_energy_bills_report_correctly_market_fees(grid_fees):
    ConstSettings.GeneralSettings.KEEP_PAST_MARKETS = True
    m_bills = MarketEnergyBills()
    m_bills.update(grid_fees)
    result = m_bills.bills_results
    assert result["street"]["house1"]["market_fee"] == 0.04
    assert result["street"]["house2"]["market_fee"] == 0.01
    assert result["street"]['Accumulated Trades']["market_fee"] == 0.05
    assert result["house1"]['External Trades']["market_fee"] == 0.0
    assert result["house2"]['External Trades']["market_fee"] == 0.0
Beispiel #6
0
def test_energy_bills_last_past_market(grid):
    ConstSettings.GeneralSettings.KEEP_PAST_MARKETS = False
    m_bills = MarketEnergyBills()
    m_bills.update(grid)
    result = m_bills.bills_results
    assert result['house2']['Accumulated Trades']['bought'] == result['commercial']['sold'] == 1
    assert result['house2']['Accumulated Trades']['spent'] == \
        result['commercial']['earned'] == \
        0.01
    assert result['commercial']['spent'] == result['commercial']['bought'] == 0
    assert result['fridge']['bought'] == 2 and isclose(result['fridge']['spent'], 0.01)
    assert result['pv']['sold'] == 2 and isclose(result['pv']['earned'], 0.01)
    assert 'children' not in result
Beispiel #7
0
class SimulationEndpointBuffer:
    def __init__(self, job_id, initial_params, area):
        self.job_id = job_id
        self.random_seed = initial_params["seed"] if initial_params[
            "seed"] is not None else ''
        self.status = {}
        self.eta = duration(seconds=0)
        self.unmatched_loads = {}
        self.unmatched_loads_redis = {}
        self.export_unmatched_loads = ExportUnmatchedLoads(area)
        self.market_unmatched_loads = MarketUnmatchedLoads()
        self.cumulative_loads = {}
        self.price_energy_day = MarketPriceEnergyDay()
        self.cumulative_grid_trades = {}
        self.accumulated_trades = {}
        self.accumulated_trades_redis = {}
        self.accumulated_balancing_trades = {}
        self.cumulative_grid_trades_redis = {}
        self.cumulative_grid_balancing_trades = {}
        self.tree_summary = {}
        self.tree_summary_redis = {}
        self.market_bills = MarketEnergyBills()
        self.balancing_bills = MarketEnergyBills(is_spot_market=False)
        self.trade_details = {}
        self.device_statistics = DeviceStatistics()
        self.energy_trade_profile = {}
        self.energy_trade_profile_redis = {}
        self.file_export_endpoints = FileExportEndpoints()

    def generate_result_report(self):
        return {
            "job_id": self.job_id,
            "random_seed": self.random_seed,
            "unmatched_loads": self.unmatched_loads_redis,
            "cumulative_loads": self.cumulative_loads,
            "price_energy_day": self.price_energy_day.redis_output,
            "cumulative_grid_trades": self.cumulative_grid_trades_redis,
            "bills": self.market_bills.bills_redis_results,
            "tree_summary": self.tree_summary_redis,
            "status": self.status,
            "eta_seconds": self.eta.seconds,
            "device_statistics": self.device_statistics.flat_results_time_str,
            "energy_trade_profile": self.energy_trade_profile_redis
        }

    def generate_json_report(self):
        return {
            "job_id": self.job_id,
            "random_seed": self.random_seed,
            "unmatched_loads": self.unmatched_loads,
            "cumulative_loads": self.cumulative_loads,
            "price_energy_day": self.price_energy_day.csv_output,
            "cumulative_grid_trades": self.cumulative_grid_trades,
            "bills": self.market_bills.bills_results,
            "tree_summary": self.tree_summary,
            "status": self.status,
            "device_statistics": self.device_statistics.device_stats_time_str,
            "energy_trade_profile": self.energy_trade_profile
        }

    def _update_unmatched_loads(self, area):
        if self.export_unmatched_loads.load_count == 0:
            self.unmatched_loads, self.unmatched_loads_redis =\
                self.market_unmatched_loads.write_none_to_unmatched_loads(area, {}, {})
        else:
            current_results, current_results_uuid = \
                self.export_unmatched_loads.get_current_market_results(
                    all_past_markets=ConstSettings.GeneralSettings.KEEP_PAST_MARKETS)

            if ConstSettings.GeneralSettings.KEEP_PAST_MARKETS:
                self.unmatched_loads = current_results
                self.unmatched_loads_redis = current_results_uuid
            else:
                self.unmatched_loads, self.unmatched_loads_redis = \
                    self.market_unmatched_loads.update_and_get_unmatched_loads(
                        current_results, current_results_uuid)

    def _update_cumulative_grid_trades(self, area):
        market_type = \
            "past_markets" if ConstSettings.GeneralSettings.KEEP_PAST_MARKETS else "current_market"
        balancing_market_type = "past_balancing_markets" \
            if ConstSettings.GeneralSettings.KEEP_PAST_MARKETS \
            else "current_balancing_market"

        if ConstSettings.GeneralSettings.KEEP_PAST_MARKETS:
            self.accumulated_trades = {}
            self.accumulated_trades_redis = {}
            self.accumulated_balancing_trades = {}

        self.accumulated_trades_redis, self.cumulative_grid_trades_redis = \
            export_cumulative_grid_trades_redis(area, self.accumulated_trades_redis,
                                                market_type)
        self.accumulated_trades, self.cumulative_grid_trades = \
            export_cumulative_grid_trades(area, self.accumulated_trades,
                                          market_type, all_devices=True)
        self.accumulated_balancing_trades, self.cumulative_grid_balancing_trades = \
            export_cumulative_grid_trades(area, self.accumulated_balancing_trades,
                                          balancing_market_type)

    def update_stats(self, area, simulation_status, eta):
        self.status = simulation_status
        self.eta = eta
        self._update_unmatched_loads(area)
        # Should always precede tree-summary update
        self.price_energy_day.update(area)
        self.cumulative_loads = {
            "price-currency": "Euros",
            "load-unit": "kWh",
            "cumulative-load-price": export_cumulative_loads(area)
        }

        self._update_cumulative_grid_trades(area)

        self.market_bills.update(area)
        self.balancing_bills.update(area)

        self._update_tree_summary(area)
        self.trade_details = generate_inter_area_trade_details(
            area, "past_markets")

        self.device_statistics.update(area)

        self.file_export_endpoints(area)
        self.energy_trade_profile = self.file_export_endpoints.traded_energy_profile
        self.energy_trade_profile_redis = self._round_energy_trade_profile(
            self.file_export_endpoints.traded_energy_profile_redis)

    def _update_tree_summary(self, area):
        price_energy_list = self.price_energy_day.csv_output

        def calculate_prices(key, functor):
            if area.name not in price_energy_list:
                return 0.
            energy_prices = [
                price_energy[key] for price_energy in price_energy_list[
                    area.name]["price-energy-day"]
            ]
            return round(functor(energy_prices),
                         2) if len(energy_prices) > 0 else 0.0

        self.tree_summary[area.slug] = {
            "min_trade_price": calculate_prices("min_price", min),
            "max_trade_price": calculate_prices("max_price", max),
            "avg_trade_price": calculate_prices("av_price", mean),
        }
        self.tree_summary_redis[area.uuid] = self.tree_summary[area.slug]
        for child in area.children:
            if child.children:
                self._update_tree_summary(child)

    @classmethod
    def _round_energy_trade_profile(cls, profile):
        for k in profile.keys():
            for sold_bought in ['sold_energy', 'bought_energy']:
                for dev in profile[k][sold_bought].keys():
                    for target in profile[k][sold_bought][dev].keys():
                        for timestamp in profile[k][sold_bought][dev][
                                target].keys():
                            profile[k][sold_bought][dev][target][
                                timestamp] = round_floats_for_ui(
                                    profile[k][sold_bought][dev][target]
                                    [timestamp])
        return profile
Beispiel #8
0
class SimulationEndpointBuffer:
    def __init__(self, job_id, initial_params, area):
        self.job_id = job_id
        self.current_market = ""
        self.random_seed = initial_params["seed"] if initial_params[
            "seed"] is not None else ''
        self.status = {}
        self.eta = duration(seconds=0)
        self.market_unmatched_loads = MarketUnmatchedLoads(area)
        self.cumulative_loads = {}
        self.price_energy_day = MarketPriceEnergyDay()
        self.tree_summary = TreeSummary()
        self.market_bills = MarketEnergyBills()
        self.balancing_bills = MarketEnergyBills(is_spot_market=False)
        self.cumulative_grid_trades = CumulativeGridTrades()
        self.trade_details = {}
        self.device_statistics = DeviceStatistics()
        self.file_export_endpoints = FileExportEndpoints()
        self.kpi = KPI()

        self.last_unmatched_loads = {}

    def generate_result_report(self):
        redis_results = {
            "job_id": self.job_id,
            "current_market": self.current_market,
            "random_seed": self.random_seed,
            "cumulative_loads": self.cumulative_loads,
            "cumulative_grid_trades":
            self.cumulative_grid_trades.current_trades_redis,
            "bills": self.market_bills.bills_redis_results,
            "tree_summary": self.tree_summary.current_results_redis,
            "status": self.status,
            "eta_seconds": self.eta.seconds,
            "kpi": self.kpi.performance_indices
        }

        if ConstSettings.GeneralSettings.REDIS_PUBLISH_FULL_RESULTS:
            redis_results.update({
                "unmatched_loads":
                self.market_unmatched_loads.unmatched_loads_uuid,
                "price_energy_day":
                self.price_energy_day.redis_output,
                "device_statistics":
                self.device_statistics.flat_stats_time_str,
                "energy_trade_profile":
                self.file_export_endpoints.traded_energy_profile_redis,
            })
        else:
            redis_results.update({
                "last_unmatched_loads":
                self.market_unmatched_loads.last_unmatched_loads,
                "last_energy_trade_profile":
                self.file_export_endpoints.traded_energy_current,
                "last_price_energy_day":
                self.price_energy_day.redis_output,
                "last_device_statistics":
                self.device_statistics.current_stats_time_str
            })

        return redis_results

    def generate_json_report(self):
        return {
            "job_id": self.job_id,
            "random_seed": self.random_seed,
            "unmatched_loads": self.market_unmatched_loads.unmatched_loads,
            "cumulative_loads": self.cumulative_loads,
            "price_energy_day": self.price_energy_day.csv_output,
            "cumulative_grid_trades":
            self.cumulative_grid_trades.current_trades_redis,
            "bills": self.market_bills.bills_results,
            "tree_summary": self.tree_summary.current_results,
            "status": self.status,
            "device_statistics": self.device_statistics.device_stats_time_str,
            "energy_trade_profile":
            self.file_export_endpoints.traded_energy_profile,
            "kpi": self.kpi.performance_indices
        }

    def update_stats(self, area, simulation_status, eta):
        self.status = simulation_status
        if area.current_market is not None:
            self.current_market = area.current_market.time_slot_str
        self.eta = eta
        self.cumulative_loads = export_cumulative_loads(area)

        self.cumulative_grid_trades.update(area)

        self.market_bills.update(area)
        self.balancing_bills.update(area)

        self.trade_details = generate_inter_area_trade_details(
            area, "past_markets")

        self.file_export_endpoints(area)
        self.market_unmatched_loads.update_unmatched_loads(area)
        self.device_statistics.update(area)

        self._update_price_energy_day_tree_summary(area)

        self.generate_result_report()

        self.kpi.update_kpis_from_area(area)

        self.update_area_aggregated_stats(area)

    def update_area_aggregated_stats(self, area):
        self._update_area_stats(area)
        for child in area.children:
            self.update_area_aggregated_stats(child)

    def _update_area_stats(self, area):
        area.stats.update_aggregated_stats({
            "simulation_id":
            self.job_id,
            "status":
            self.status,
            "bills":
            self.market_bills.bills_redis_results[area.uuid],
            "cumulative_grid_trades":
            self.cumulative_grid_trades.accumulated_trades_redis.get(
                area.uuid, None),
            "tree_summary":
            self.tree_summary.current_results.get(area.slug, None),
            "unmatched_loads":
            self.market_unmatched_loads.unmatched_loads.get(area.name, None),
            "price_energy_day":
            self.price_energy_day.csv_output.get(area.name, None),
            "device_statistics":
            self.device_statistics.device_stats_time_str.get(area.uuid, None),
            "energy_trade_profile":
            self.file_export_endpoints.traded_energy_profile.get(
                area.slug, None),
            "kpi":
            self.kpi.performance_indices.get(area.name, None)
        })

    def _update_price_energy_day_tree_summary(self, area):
        # Update of the price_energy_day endpoint should always precede tree-summary.
        # The reason is that the price_energy_day data are used when calculating the
        # tree-summary data.
        self.price_energy_day.update(area)
        self.tree_summary.update(area, self.price_energy_day.csv_output)
Beispiel #9
0
def test_energy_bills_ensure_device_types_are_populated(grid2):
    m_bills = MarketEnergyBills()
    m_bills.update(grid2)
    result = m_bills.bills_results
    assert result["house1"]["type"] == "House 1 type"
    assert result["house2"]["type"] == "House 2 type"
Beispiel #10
0
def test_energy_bills_finds_iaas(grid2):
    m_bills = MarketEnergyBills()
    m_bills.update(grid2)
    result = m_bills.bills_results
    assert result['house1']['bought'] == result['house2']['sold'] == 3
Beispiel #11
0
class SimulationEndpointBuffer:
    def __init__(self, job_id, initial_params, area, export_plots=True):
        self.job_id = job_id
        self.current_market = ""
        self.random_seed = initial_params["seed"] if initial_params[
            "seed"] is not None else ''
        self.status = {}
        self.simulation_progress = {
            "eta_seconds": 0,
            "elapsed_time_seconds": 0,
            "percentage_completed": 0
        }
        self.market_unmatched_loads = MarketUnmatchedLoads(area)
        self.price_energy_day = MarketPriceEnergyDay()
        self.market_bills = MarketEnergyBills()
        self.cumulative_bills = CumulativeBills()
        self.balancing_bills = MarketEnergyBills(is_spot_market=False)
        self.cumulative_grid_trades = CumulativeGridTrades()
        self.device_statistics = DeviceStatistics()
        self.file_export_endpoints = FileExportEndpoints(export_plots)
        self.kpi = KPI()
        self.area_throughput_stats = AreaThroughputStats()

        self.last_unmatched_loads = {}
        self.bids_offers_trades = {}
        self.export_plots = export_plots
        if export_plots:
            self.area_market_stocks_stats = OfferBidTradeGraphStats()

    def generate_result_report(self):
        # TODO: In D3ASIM-2288, add unix_time=True to convert_pendulum_to_str_in_dict
        return {
            "job_id":
            self.job_id,
            "current_market":
            self.current_market,
            "random_seed":
            self.random_seed,
            "cumulative_grid_trades":
            self.cumulative_grid_trades.current_trades_redis,
            "bills":
            self.market_bills.bills_redis_results,
            "cumulative_bills":
            self.cumulative_bills.cumulative_bills,
            "status":
            self.status,
            "progress_info":
            self.simulation_progress,
            "kpi":
            self.kpi.performance_indices_redis,
            "last_unmatched_loads":
            convert_pendulum_to_str_in_dict(
                self.market_unmatched_loads.last_unmatched_loads, {}),
            "last_energy_trade_profile":
            convert_pendulum_to_str_in_dict(
                self.file_export_endpoints.traded_energy_current, {},
                ui_format=True),
            "last_price_energy_day":
            convert_pendulum_to_str_in_dict(self.price_energy_day.redis_output,
                                            {}),
            "last_device_statistics":
            convert_pendulum_to_str_in_dict(
                self.device_statistics.current_stats_dict, {}),
            "area_throughput":
            self.area_throughput_stats.results_redis,
            "last_energy_trades_high_resolution":
            convert_pendulum_to_str_in_dict(
                self.file_export_endpoints.last_energy_trades_high_resolution,
                {}),
            "bids_offers_trades":
            self.bids_offers_trades
        }

    def generate_json_report(self):
        return {
            "job_id":
            self.job_id,
            "random_seed":
            self.random_seed,
            "unmatched_loads":
            convert_pendulum_to_str_in_dict(
                self.market_unmatched_loads.unmatched_loads, {}),
            "price_energy_day":
            convert_pendulum_to_str_in_dict(self.price_energy_day.csv_output,
                                            {}),
            "cumulative_grid_trades":
            self.cumulative_grid_trades.current_trades_redis,
            "bills":
            self.market_bills.bills_results,
            "cumulative_bills":
            self.cumulative_bills.cumulative_bills,
            "status":
            self.status,
            "progress_info":
            self.simulation_progress,
            "device_statistics":
            convert_pendulum_to_str_in_dict(
                self.device_statistics.device_stats_dict, {}),
            "energy_trade_profile":
            convert_pendulum_to_str_in_dict(
                self.file_export_endpoints.traded_energy_profile, {},
                ui_format=True),
            "kpi":
            self.kpi.performance_indices,
            "area_throughput":
            self.area_throughput_stats.results,
        }

    def update_stats(self, area, simulation_status, progress_info):
        self.status = simulation_status
        if area.current_market is not None:
            self.current_market = area.current_market.time_slot_str
        self.simulation_progress = {
            "eta_seconds": progress_info.eta.seconds,
            "elapsed_time_seconds": progress_info.elapsed_time.seconds,
            "percentage_completed": int(progress_info.percentage_completed)
        }

        self.cumulative_grid_trades.update(area)

        self.market_bills.update(area)
        if ConstSettings.BalancingSettings.ENABLE_BALANCING_MARKET:
            self.balancing_bills.update(area)

        self.cumulative_bills.update_cumulative_bills(area)

        self.file_export_endpoints(area)
        self.market_unmatched_loads.update_unmatched_loads(area)
        self.device_statistics.update(area)

        self.price_energy_day.update(area)

        self.kpi.update_kpis_from_area(area)

        self.area_throughput_stats.update(area)

        self.generate_result_report()

        self.bids_offers_trades.clear()
        self.update_area_aggregated_stats(area)

        if self.export_plots:
            self.area_market_stocks_stats.update(area)

    def _send_results_to_areas(self, area):
        stats = {
            "kpi": self.kpi.performance_indices_redis.get(area.uuid, None)
        }
        area.endpoint_stats.update(stats)

    def update_area_aggregated_stats(self, area):
        self._update_area_stats(area)
        self._send_results_to_areas(area)
        for child in area.children:
            self.update_area_aggregated_stats(child)

    def _update_area_stats(self, area):
        if area.current_market is not None:
            self.bids_offers_trades[
                area.uuid] = area.current_market.get_bids_offers_trades()
        bills = self.market_bills.bills_redis_results[area.uuid]
        bills.update({
            "penalty_cost":
            self.cumulative_bills.cumulative_bills_results[
                area.uuid]["penalties"],
            "penalty_energy":
            self.cumulative_bills.cumulative_bills_results[area.uuid]
            ["penalty_energy"]
        })
        area.stats.update_aggregated_stats({"bills": bills})