def test_energy_bills_finds_iaas(grid2): epb = SimulationEndpointBuffer("1", {"seed": 0}, grid2, True) epb.current_market_time_slot_str = grid2.current_market.time_slot_str epb._populate_core_stats_and_sim_state(grid2) m_bills = MarketEnergyBills(should_export_plots=True) m_bills.update(epb.area_result_dict, epb.flattened_area_core_stats_dict, epb.current_market_time_slot_str) result = m_bills.bills_results assert result['house1']['bought'] == result['house2']['sold'] == 3
def test_energy_bills_ensure_device_types_are_populated(grid2): epb = SimulationEndpointBuffer("1", {"seed": 0}, grid2, True) epb.current_market_time_slot_str = grid2.current_market.time_slot_str epb._populate_core_stats_and_sim_state(grid2) m_bills = MarketEnergyBills(should_export_plots=True) m_bills.update(epb.area_result_dict, epb.flattened_area_core_stats_dict, epb.current_market_time_slot_str) result = m_bills.bills_results assert result["house1"]["type"] == "Area" assert result["house2"]["type"] == "Area"
def test_energy_bills_use_only_last_market_if_not_keep_past_markets(grid_fees): constants.RETAIN_PAST_MARKET_STRATEGIES_STATE = False epb = SimulationEndpointBuffer("1", {"seed": 0}, grid_fees, True) epb.current_market_time_slot_str = grid_fees.current_market.time_slot_str epb._populate_core_stats_and_sim_state(grid_fees) m_bills = MarketEnergyBills(should_export_plots=True) m_bills._update_market_fees(epb.area_result_dict, epb.flattened_area_core_stats_dict) assert m_bills.market_fees[grid_fees.name_uuid_mapping['house2']] == 0.03 assert m_bills.market_fees[grid_fees.name_uuid_mapping['street']] == 0.01 assert m_bills.market_fees[grid_fees.name_uuid_mapping['house1']] == 0.06
def test_energy_bills_redis(grid): epb = SimulationEndpointBuffer("1", {"seed": 0}, grid, True) epb.current_market_time_slot_str = grid.current_market.time_slot_str epb._populate_core_stats_and_sim_state(grid) m_bills = MarketEnergyBills(should_export_plots=True) m_bills.update(epb.area_result_dict, epb.flattened_area_core_stats_dict, epb.current_market_time_slot_str) result = m_bills.bills_results result_redis = m_bills.bills_redis_results for house in grid.children: assert_dicts_identical(result[house.name], result_redis[house.uuid]) for device in house.children: assert_dicts_identical(result[device.name], result_redis[device.uuid])
def test_flatten_energy_bills(grid): epb = SimulationEndpointBuffer("1", {"seed": 0}, grid, True) epb.current_market_time_slot_str = grid.current_market.time_slot_str epb._populate_core_stats_and_sim_state(grid) m_bills = MarketEnergyBills(should_export_plots=True) m_bills._update_market_fees(epb.area_result_dict, epb.flattened_area_core_stats_dict) bills = m_bills._energy_bills(epb.area_result_dict, epb.flattened_area_core_stats_dict) flattened = {} m_bills._flatten_energy_bills(bills, flattened) assert all("children" not in v for _, v in flattened.items()) name_list = ['house1', 'house2', 'pv', 'fridge', 'e-car', 'commercial'] uuid_list = [grid.name_uuid_mapping[k] for k in name_list] assert_lists_contain_same_elements(uuid_list, flattened.keys()) house1_uuid = grid.name_uuid_mapping["house1"] _compare_bills(flattened[house1_uuid], bills[house1_uuid]) house2_uuid = grid.name_uuid_mapping["house2"] _compare_bills(flattened[house2_uuid], bills[house2_uuid]) commercial_uuid = grid.name_uuid_mapping["commercial"] _compare_bills(flattened[commercial_uuid], bills[commercial_uuid]) pv_uuid = grid.name_uuid_mapping["pv"] pv = [v for k, v in bills[house1_uuid]["children"].items() if k == pv_uuid][0] _compare_bills(flattened[pv_uuid], pv) fridge_uuid = grid.name_uuid_mapping["fridge"] fridge = [v for k, v in bills[house1_uuid]["children"].items() if k == fridge_uuid][0] _compare_bills(flattened[fridge_uuid], fridge) ecar_uuid = grid.name_uuid_mapping["e-car"] ecar = [v for k, v in bills[house2_uuid]["children"].items() if k == ecar_uuid][0] _compare_bills(flattened[ecar_uuid], ecar)
def test_calculate_raw_energy_bills(grid): epb = SimulationEndpointBuffer("1", {"seed": 0}, grid, True) epb.current_market_time_slot_str = grid.current_market.time_slot_str epb._populate_core_stats_and_sim_state(grid) m_bills = MarketEnergyBills(should_export_plots=True) m_bills._update_market_fees(epb.area_result_dict, epb.flattened_area_core_stats_dict) bills = m_bills._energy_bills(epb.area_result_dict, epb.flattened_area_core_stats_dict) grid_children_uuids = [c.uuid for c in grid.children] assert all(h in bills for h in grid_children_uuids) commercial_uuid = grid.name_uuid_mapping["commercial"] assert 'children' not in bills[commercial_uuid] house1_uuid = grid.name_uuid_mapping["house1"] assert grid.name_uuid_mapping["pv"] in bills[house1_uuid]["children"] pv_bills = [v for k, v in bills[house1_uuid]["children"].items() if k == grid.name_uuid_mapping["pv"]][0] assert pv_bills['sold'] == 2.0 and isclose(pv_bills['earned'], 0.01) assert grid.name_uuid_mapping["fridge"] in bills[house1_uuid]["children"] house2_uuid = grid.name_uuid_mapping["house2"] assert grid.name_uuid_mapping["e-car"] in bills[house2_uuid]["children"]
def test_energy_bills_last_past_market(grid): epb = SimulationEndpointBuffer("1", {"seed": 0}, grid, True) epb.current_market_time_slot_str = grid.current_market.time_slot_str epb._populate_core_stats_and_sim_state(grid) m_bills = MarketEnergyBills(should_export_plots=True) m_bills.update(epb.area_result_dict, epb.flattened_area_core_stats_dict, epb.current_market_time_slot_str) 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 external_trades = result['house2']['External Trades'] assert external_trades['total_energy'] == external_trades['bought'] - external_trades['sold'] assert external_trades['total_cost'] == external_trades['spent'] - external_trades['earned'] 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
def __init__(self, should_export_plots: bool = False): self.should_export_plots = should_export_plots self.bids_offers_trades = {} self.results_mapping = { 'bills': MarketEnergyBills(should_export_plots), 'kpi': KPI(), 'cumulative_net_energy_flow': CumulativeNetEnergyFlow(), 'price_energy_day': MarketPriceEnergyDay(should_export_plots), 'cumulative_bills': CumulativeBills(), 'cumulative_grid_trades': CumulativeGridTrades(), 'device_statistics': DeviceStatistics(should_export_plots), 'trade_profile': EnergyTradeProfile(should_export_plots), 'area_throughput': AreaThroughputStats(), 'market_summary': MarketSummaryInfo(should_export_plots), 'assets_info': SimulationAssetsInfo() } self._total_memory_utilization_kb = 0.0
def test_energy_bills_accumulate_fees(grid_fees): constants.RETAIN_PAST_MARKET_STRATEGIES_STATE = True epb = SimulationEndpointBuffer("1", {"seed": 0}, grid_fees, True) epb.current_market_time_slot_str = grid_fees.current_market.time_slot_str epb._populate_core_stats_and_sim_state(grid_fees) m_bills = MarketEnergyBills(should_export_plots=True) m_bills._update_market_fees(epb.area_result_dict, epb.flattened_area_core_stats_dict) grid_fees.children[0].past_markets = [FakeMarket([], name='house1', fees=2.0)] grid_fees.children[1].past_markets = [] grid_fees.past_markets = [FakeMarket((_trade(2, make_iaa_name(grid_fees.children[0]), 3, make_iaa_name(grid_fees.children[0]), fee_price=4.0),), 'street', fees=4.0)] epb.current_market_time_slot_str = grid_fees.current_market.time_slot_str epb._populate_core_stats_and_sim_state(grid_fees) m_bills._update_market_fees(epb.area_result_dict, epb.flattened_area_core_stats_dict) assert m_bills.market_fees[grid_fees.name_uuid_mapping['house2']] == 0.03 assert m_bills.market_fees[grid_fees.name_uuid_mapping['street']] == 0.05 assert m_bills.market_fees[grid_fees.name_uuid_mapping['house1']] == 0.08
def test_energy_bills_report_correctly_market_fees(grid_fees): constants.RETAIN_PAST_MARKET_STRATEGIES_STATE = True epb = SimulationEndpointBuffer("1", {"seed": 0}, grid_fees, True) epb.current_market_time_slot_str = grid_fees.current_market.time_slot_str epb._populate_core_stats_and_sim_state(grid_fees) m_bills = MarketEnergyBills(should_export_plots=True) m_bills.update(epb.area_result_dict, epb.flattened_area_core_stats_dict, epb.current_market_time_slot_str) grid_fees.children[0].past_markets = [FakeMarket([], name='house1', fees=2.0)] grid_fees.children[1].past_markets = [] grid_fees.past_markets = [FakeMarket((_trade(2, make_iaa_name(grid_fees.children[0]), 3, make_iaa_name(grid_fees.children[0]), fee_price=4.0),), 'street', fees=4.0)] epb.current_market_time_slot_str = grid_fees.current_market.time_slot_str epb._populate_core_stats_and_sim_state(grid_fees) m_bills.update(epb.area_result_dict, epb.flattened_area_core_stats_dict, epb.current_market_time_slot_str) 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
def test_energy_bills(grid): epb = SimulationEndpointBuffer("1", {"seed": 0}, grid, True) epb.current_market_time_slot_str = grid.current_market.time_slot_str epb._populate_core_stats_and_sim_state(grid) m_bills = MarketEnergyBills(should_export_plots=True) m_bills.update(epb.area_result_dict, epb.flattened_area_core_stats_dict, epb.current_market_time_slot_str) 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 grid.children[0].past_markets = [FakeMarket((_trade(2, 'fridge', 2, 'pv'), _trade(3, 'fridge', 1, 'iaa')), 'house1')] grid.children[1].past_markets = [FakeMarket((_trade(1, 'e-car', 4, 'iaa'), _trade(1, 'e-car', 8, 'iaa'), _trade(3, 'iaa', 5, 'e-car')), 'house2')] grid.past_markets = [FakeMarket((_trade(2, 'house2', 12, 'commercial'),), 'grid')] epb.current_market_time_slot_str = grid.current_market.time_slot_str epb._populate_core_stats_and_sim_state(grid) m_bills.update(epb.area_result_dict, epb.flattened_area_core_stats_dict, epb.current_market_time_slot_str) result = m_bills.bills_results assert result['house2']['Accumulated Trades']['bought'] == result['commercial']['sold'] == 13 assert result['house2']['Accumulated Trades']['spent'] == \ result['commercial']['earned'] == \ 0.03 assert result['commercial']['spent'] == result['commercial']['bought'] == 0 assert result['fridge']['bought'] == 5 and isclose(result['fridge']['spent'], 0.06) assert result['pv']['sold'] == 4 and isclose(result['pv']['earned'], 0.03) assert 'children' not in result
def setUp(self): self.bills = MarketEnergyBills()
class TestBills(unittest.TestCase): def setUp(self): self.bills = MarketEnergyBills() def tearDown(self): pass @property def _empty_bills(self): return { 'bought': 0.0, 'sold': 0.0, 'spent': 0.0, 'earned': 0.0, 'total_energy': 0.0, 'total_cost': 0.0, 'market_fee': 0.0, 'type': 'Area' } def create_empty_results_with_children(self, uuid_or_name_list): result_dict = {k: self._empty_bills for k in ACCUMULATED_KEYS_LIST} result_dict.update({u: self._empty_bills for u in uuid_or_name_list}) return result_dict def test_swap_children_uuids_to_names(self): grid_uuid = str(uuid4()) house1_uuid = str(uuid4()) house2_uuid = str(uuid4()) pv_uuid = str(uuid4()) load_uuid = str(uuid4()) pv2_uuid = str(uuid4()) area_dict = { "name": "grid", "uuid": grid_uuid, "parent_uuid": "", "children": [{ "name": "house1", "uuid": house1_uuid, "parent_uuid": grid_uuid, "children": [{ "name": "pv", "uuid": pv_uuid, "parent_uuid": house1_uuid, "children": [] }, { "name": "load", "uuid": load_uuid, "parent_uuid": house1_uuid, "children": [] }] }, { "name": "house2", "uuid": house2_uuid, "parent_uuid": grid_uuid, "children": [ { "name": "pv2", "uuid": pv2_uuid, "parent_uuid": house2_uuid, "children": [] }, ] }] } uuid_results = { grid_uuid: self.create_empty_results_with_children([house1_uuid, house2_uuid]), house1_uuid: self.create_empty_results_with_children([pv_uuid, load_uuid]), house2_uuid: self.create_empty_results_with_children([pv2_uuid]), pv_uuid: self._empty_bills, load_uuid: self._empty_bills, pv2_uuid: self._empty_bills, } results = self.bills._swap_children_uuids_to_names( area_dict, uuid_results) assert set(results.keys()) == { grid_uuid, house1_uuid, house2_uuid, pv_uuid, load_uuid, pv2_uuid } assert set(results[grid_uuid].keys()) == { "house1", "house2", *ACCUMULATED_KEYS_LIST } assert set(results[house1_uuid].keys()) == { "pv", "load", *ACCUMULATED_KEYS_LIST } assert set( results[house2_uuid].keys()) == {"pv2", *ACCUMULATED_KEYS_LIST} def test_restore_area_results_state(self): grid_uuid = str(uuid4()) house1_uuid = str(uuid4()) house2_uuid = str(uuid4()) pv_uuid = str(uuid4()) load_uuid = str(uuid4()) pv2_uuid = str(uuid4()) name_results = { grid_uuid: self.create_empty_results_with_children(["house1", "house2"]), house1_uuid: self.create_empty_results_with_children(["pv", "load"]), house2_uuid: self.create_empty_results_with_children(["pv2"]), pv_uuid: self._empty_bills, load_uuid: self._empty_bills, pv2_uuid: self._empty_bills, } area_dict = { "name": "grid", "uuid": grid_uuid, "parent_uuid": "", "children": [{ "name": "house1", "uuid": house1_uuid, "parent_uuid": grid_uuid, "children": [{ "name": "pv", "uuid": pv_uuid, "parent_uuid": house1_uuid, "children": [] }, { "name": "load", "uuid": load_uuid, "parent_uuid": house1_uuid, "children": [] }] }, { "name": "house2", "uuid": house2_uuid, "parent_uuid": grid_uuid, "children": [ { "name": "pv2", "uuid": pv2_uuid, "parent_uuid": house2_uuid, "children": [] }, ] }] } self.bills.restore_area_results_state(area_dict, name_results[grid_uuid]) assert_dicts_identical(self.bills.bills_redis_results[grid_uuid], name_results[grid_uuid]) assert_dicts_identical(self.bills.bills_results["grid"], name_results[grid_uuid]) assert_dicts_identical( self.bills.current_raw_bills[grid_uuid], self.create_empty_results_with_children([house1_uuid, house2_uuid])) self.bills.restore_area_results_state(area_dict["children"][0], name_results[house1_uuid]) assert_dicts_identical(self.bills.bills_redis_results[house1_uuid], name_results[house1_uuid]) assert_dicts_identical(self.bills.bills_results["house1"], name_results[house1_uuid]) assert_dicts_identical( self.bills.current_raw_bills[house1_uuid], self.create_empty_results_with_children([pv_uuid, load_uuid])) self.bills.restore_area_results_state( area_dict["children"][1]["children"][0], name_results[pv2_uuid]) assert_dicts_identical(self.bills.bills_redis_results[pv2_uuid], name_results[pv2_uuid]) assert_dicts_identical(self.bills.bills_results["pv2"], name_results[pv2_uuid]) assert_dicts_identical(self.bills.current_raw_bills[pv2_uuid], self._empty_bills) def test_bills_local_format(self): grid_uuid = str(uuid4()) house1_uuid = str(uuid4()) house2_uuid = str(uuid4()) pv_uuid = str(uuid4()) load_uuid = str(uuid4()) pv2_uuid = str(uuid4()) area_dict = { "name": "grid", "uuid": grid_uuid, "parent_uuid": "", "children": [{ "name": "house1", "uuid": house1_uuid, "parent_uuid": grid_uuid, "children": [{ "name": "pv", "uuid": pv_uuid, "parent_uuid": house1_uuid, "children": [] }, { "name": "load", "uuid": load_uuid, "parent_uuid": house1_uuid, "children": [] }] }, { "name": "house2", "uuid": house2_uuid, "parent_uuid": grid_uuid, "children": [ { "name": "pv2", "uuid": pv2_uuid, "parent_uuid": house2_uuid, "children": [] }, ] }] } uuid_results = { grid_uuid: self.create_empty_results_with_children(["house1", "house2"]), house1_uuid: self.create_empty_results_with_children(["pv", "load"]), house2_uuid: self.create_empty_results_with_children(["pv2"]), pv_uuid: self._empty_bills, load_uuid: self._empty_bills, pv2_uuid: self._empty_bills, } uuid_results[grid_uuid]["house1"]["bought"] = 0.987654321 results = self.bills._bills_local_format(area_dict, uuid_results) assert set(results.keys()) == { "grid", "house1", "house2", "load", "pv", "pv2" } # Validate that no rounding takes place for the local results assert results["grid"]["house1"]["bought"] == 0.987654321 def test_round_results_for_ui(self): uuid_results = { "1234": self.create_empty_results_with_children(["house1", "house2"]), "2345": self.create_empty_results_with_children(["pv", "load"]), "3456": self.create_empty_results_with_children(["pv2"]), "4567": self._empty_bills, "5678": self._empty_bills, "6789": self._empty_bills, } uuid_results["1234"]["house1"]["bought"] = 0.1234567 uuid_results["1234"]["house2"]["sold"] = 0.9876541 uuid_results["2345"]["pv"]["sold"] = 0.987 uuid_results["6789"]["earned"] = 12 results = self.bills._round_results_for_ui(uuid_results) assert results["1234"]["house1"]["bought"] == 0.123 assert results["1234"]["house2"]["sold"] == 0.988 assert results["2345"]["pv"]["sold"] == 0.987 assert results["6789"]["earned"] == 12