def grid2(): house1 = FakeArea('house1') house2 = FakeArea('house2') return FakeArea('street', children=[house1, house2], past_markets=[ FakeMarket((_trade(2, make_iaa_name(house1), 3, make_iaa_name(house2)), )) ])
def grid2(): house1 = FakeArea('house1') house2 = FakeArea('house2') house1.display_type = "House 1 type" house2.display_type = "House 2 type" return FakeArea( 'street', children=[house1, house2], past_markets=[FakeMarket( (_trade(2, make_iaa_name(house1), 3, make_iaa_name(house2)),), 'street' )] )
def grid2(): house1 = FakeArea('house1') house2 = FakeArea('house2') grid = FakeArea( 'street', children=[house1, house2], past_markets=[FakeMarket( (_trade(2, make_iaa_name(house1), 3, make_iaa_name(house2)),), 'street' )] ) house1.parent = grid house2.parent = grid return grid
def __init__(self, offer_price, buyer='FakeChild', seller=make_iaa_name(FakeArea())): self.offer_price = offer_price self.seller = seller self.buyer = buyer
def __init__(self, area, owner): super().__init__() self.area = area self.owner = owner self.own_name = make_iaa_name(self.owner) self.own_market = None self.area_market = None
def grid_fees(): house1 = FakeArea('house1', children=[FakeArea("testPV")], past_markets=[FakeMarket([], name='house1', fees=2.0), FakeMarket([], name='house1', fees=6.0)]) house2 = FakeArea('house2', children=[FakeArea("testLoad")], past_markets=[FakeMarket([], name='house2', fees=3.0)]) house1.display_type = "House 1 type" house2.display_type = "House 2 type" return FakeArea( 'street', children=[house1, house2], past_markets=[FakeMarket( (_trade(2, make_iaa_name(house1), 3, make_iaa_name(house2)),), 'street', fees=4.0 )] )
def __init__(self, *, owner, higher_market, lower_market, min_offer_age=ConstSettings.IAASettings.MIN_OFFER_AGE, engine_type=IAAEngine): super().__init__(engine_type=engine_type, owner=owner, higher_market=higher_market, lower_market=lower_market, min_offer_age=min_offer_age) self.name = make_iaa_name(owner)
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_traded_energy_rate(context): def has_one_of_clearing_rates(trade, market): return any(isclose((trade.offer.price / trade.offer.energy), clearing_rate) for clearing_rate in market.state.clearing[trade.time]) assert all(has_one_of_clearing_rates(trade, market) for child in context.simulation.area.children for market in child.past_markets for trade in market.trades if trade.time in market.state.clearing and market.state.clearing[trade.time] != 0 and trade.buyer == make_iaa_name(child))
def _calculate_and_buy_balancing_energy(self, market, trade): if trade.buyer != make_iaa_name(self.owner) or \ market.time_slot != self.lower_market.time_slot: return positive_balancing_energy = \ trade.offer.energy * self.balancing_spot_trade_ratio + \ self.lower_market.unmatched_energy_upward negative_balancing_energy = \ trade.offer.energy * self.balancing_spot_trade_ratio + \ self.lower_market.unmatched_energy_downward self._trigger_balancing_trades(positive_balancing_energy, negative_balancing_energy)
def device_partially_fulfill_bid(context, device): grid = context.simulation.area house1 = next( filter(lambda x: x.name == "House 1", context.simulation.area.children)) device_name = "H1 General Load" if device == "load" else "H1 Storage" load_or_storage = next( filter(lambda x: device_name in x.name, house1.children)) house2 = next( filter(lambda x: x.name == "House 2", context.simulation.area.children)) pvs = list(filter(lambda x: "H2 PV" in x.name, house2.children)) for market in house1.past_markets: slot = market.time_slot if len(market.trades) == 0: continue for trade in market.trades: assert load_or_storage.strategy.bid_update.initial_rate[market.time_slot] <= \ round(trade.offer.price / trade.offer.energy, DEFAULT_PRECISION) <= \ load_or_storage.strategy.bid_update.final_rate[market.time_slot] # Assert one trade for each PV assert len(market.trades) == 5 assert all(trade.buyer == load_or_storage.name for trade in market.trades) assert all(trade.seller == make_iaa_name(house1) for trade in house1.get_past_market(slot).trades) assert len(grid.get_past_market(slot).trades) == 5 assert all(trade.buyer == make_iaa_name(house1) for trade in grid.get_past_market(slot).trades) assert all(trade.seller == make_iaa_name(house2) for trade in grid.get_past_market(slot).trades) pv_names = [pv.name for pv in pvs] assert len(grid.get_past_market(slot).trades) == 5 assert all(trade.buyer == make_iaa_name(house2) for trade in house2.get_past_market(slot).trades) assert all(trade.seller in pv_names for trade in house2.get_past_market(slot).trades)
def __init__(self, *, owner, higher_market, lower_market, min_offer_age=ConstSettings.IAASettings.MIN_OFFER_AGE, do_create_engine=True): super().__init__(owner=owner, higher_market=higher_market, lower_market=lower_market, min_offer_age=min_offer_age) if do_create_engine: self.engines = [ IAAEngine('High -> Low', higher_market, lower_market, min_offer_age, self), IAAEngine('Low -> High', lower_market, higher_market, min_offer_age, self), ] self.name = make_iaa_name(owner)
def device_partially_fulfill_bid(context, device): grid = context.simulation.area house1 = next( filter(lambda x: x.name == "House 1", context.simulation.area.children)) device_name = "H1 General Load" if device == "load" else "H1 Storage" load_or_storage = next( filter(lambda x: device_name in x.name, house1.children)) house2 = next( filter(lambda x: x.name == "House 2", context.simulation.area.children)) pvs = list(filter(lambda x: "H2 PV" in x.name, house2.children)) for market in house1.past_markets: slot = market.time_slot if len(market.trades) == 0: continue # Assert one trade for each PV assert len(market.trades) == 5 assert all(trade.buyer == load_or_storage.name for trade in market.trades) assert all(trade.seller == make_iaa_name(house1) for trade in house1.get_past_market(slot).trades) assert len(grid.get_past_market(slot).trades) == 5 assert all(trade.buyer == make_iaa_name(house1) for trade in grid.get_past_market(slot).trades) assert all(trade.seller == make_iaa_name(house2) for trade in grid.get_past_market(slot).trades) pv_names = [pv.name for pv in pvs] assert len(grid.get_past_market(slot).trades) == 5 assert all(trade.buyer == make_iaa_name(house2) for trade in house2.get_past_market(slot).trades) assert all(trade.seller in pv_names for trade in house2.get_past_market(slot).trades) assert all(RATE_LOWER_THRESHOLD < trade.offer.price / trade.offer.energy < RATE_UPPER_THRESHOLD for trade in market.trades)
def test_traded_energy_rate(context): def has_one_of_clearing_rates(trade, market): return any( isclose(trade.offer_bid.energy_rate, clearing_rate) for clearing_rate in market.state.clearing.values()) for child in context.simulation.area.children: match_algo = bid_offer_matcher.matcher.match_algorithm assert all( has_one_of_clearing_rates(trade, match_algo) for market in child.past_markets for trade in market.trades if trade.buyer == make_iaa_name(child) and trade.time in match_algo .state.clearing and match_algo.state.clearing[trade.time] != 0)
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 grid_fees(): house1 = FakeArea('house1', children=[FakeArea("testPV")], past_markets=[FakeMarket([], name='house1', fees=6.0)]) house2 = FakeArea('house2', children=[FakeArea("testLoad")], past_markets=[FakeMarket((_trade(2, "testload", 3, "IAA house2", fee_price=3.0),), name='house2', fees=3.0)]) house1.display_type = "House 1 type" house2.display_type = "House 2 type" grid = FakeArea( 'street', children=[house1, house2], past_markets=[FakeMarket((_trade(2, make_iaa_name(house2), 3, make_iaa_name(house1), fee_price=1.0),), 'street', fees=1.0) ]) house1.parent = grid house2.parent = grid grid.name_uuid_mapping = { "street": grid.uuid, "house1": house1.uuid, "house2": house2.uuid, } return grid
def _area_trade_from_parent(area, parent, accumulated_trades, past_market_types): area_IAA_name = make_iaa_name(area) parent_markets = getattr(parent, past_market_types) if parent_markets is not None: if type(parent_markets) != list: parent_markets = [parent_markets] for market in parent_markets: for trade in market.trades: if trade.buyer == area_IAA_name: seller_id = area_name_from_area_or_iaa_name(trade.seller) accumulated_trades[area.name]["consumedFrom"] = \ add_or_create_key(accumulated_trades[area.name]["consumedFrom"], seller_id, trade.offer.energy) accumulated_trades[area.name]["spentTo"] = \ add_or_create_key(accumulated_trades[area.name]["spentTo"], seller_id, trade.offer.price) return accumulated_trades
def _accumulate_house_trades(house, grid, accumulated_trades, past_market_types): if house.name not in accumulated_trades: accumulated_trades[house.name] = { "type": "house", "id": house.area_id, "produced": 0.0, "earned": 0.0, "consumedFrom": defaultdict(int), "spentTo": defaultdict(int), } house_IAA_name = make_iaa_name(house) child_names = [c.name for c in house.children] for market in getattr(house, past_market_types): for trade in market.trades: if area_name_from_area_or_iaa_name(trade.seller) in child_names and \ area_name_from_area_or_iaa_name(trade.buyer) in child_names: # House self-consumption trade accumulated_trades[ house.name]["produced"] -= trade.offer.energy accumulated_trades[house.name]["earned"] += trade.offer.price accumulated_trades[house.name]["consumedFrom"][ house.name] += trade.offer.energy accumulated_trades[house.name]["spentTo"][ house.name] += trade.offer.price elif trade.buyer == house_IAA_name: accumulated_trades[house.name]["earned"] += trade.offer.price accumulated_trades[ house.name]["produced"] -= trade.offer.energy for market in getattr(grid, past_market_types): for trade in market.trades: if trade.buyer == house_IAA_name and trade.buyer != trade.offer.seller: seller_id = area_name_from_area_or_iaa_name(trade.seller) accumulated_trades[house.name]["consumedFrom"][ seller_id] += trade.offer.energy accumulated_trades[ house.name]["spentTo"][seller_id] += trade.offer.price return accumulated_trades
def _accumulate_area_trades(area, parent, accumulated_trades, past_market_types): if area.name not in accumulated_trades: accumulated_trades[area.name] = { "type": "house", "produced": 0.0, "earned": 0.0, "consumedFrom": {}, "spentTo": {}, "producedForExternal": {}, "earnedFromExternal": {}, "consumedFromExternal": {}, "spentToExternal": {}, } area_IAA_name = make_iaa_name(area) child_names = [ area_name_from_area_or_iaa_name(c.name) for c in area.children ] area_markets = getattr(area, past_market_types) if area_markets is not None: if type(area_markets) != list: area_markets = [area_markets] for market in area_markets: for trade in market.trades: if area_name_from_area_or_iaa_name(trade.seller) in child_names and \ area_name_from_area_or_iaa_name(trade.buyer) in child_names: # House self-consumption trade accumulated_trades[ area.name]["produced"] -= trade.offer.energy accumulated_trades[ area.name]["earned"] += trade.offer.price accumulated_trades[area.name]["consumedFrom"] = \ add_or_create_key(accumulated_trades[area.name]["consumedFrom"], area.name, trade.offer.energy) accumulated_trades[area.name]["spentTo"] = \ add_or_create_key(accumulated_trades[area.name]["spentTo"], area.name, trade.offer.price) elif trade.buyer == area_IAA_name: accumulated_trades[ area.name]["earned"] += trade.offer.price accumulated_trades[ area.name]["produced"] -= trade.offer.energy for market in area_markets: for trade in market.trades: if area_name_from_area_or_iaa_name(trade.seller) == \ area.name and area_name_from_area_or_iaa_name(trade.buyer) in child_names: accumulated_trades[area.name]["consumedFromExternal"] = \ subtract_or_create_key(accumulated_trades[area.name] ["consumedFromExternal"], area_name_from_area_or_iaa_name(trade.buyer), trade.offer.energy) accumulated_trades[area.name]["spentToExternal"] = \ add_or_create_key(accumulated_trades[area.name]["spentToExternal"], area_name_from_area_or_iaa_name(trade.buyer), trade.offer.price) elif area_name_from_area_or_iaa_name(trade.buyer) == \ area.name and area_name_from_area_or_iaa_name(trade.seller) in child_names: accumulated_trades[area.name]["producedForExternal"] = \ add_or_create_key(accumulated_trades[area.name]["producedForExternal"], area_name_from_area_or_iaa_name(trade.seller), trade.offer.energy) accumulated_trades[area.name]["earnedFromExternal"] = \ add_or_create_key(accumulated_trades[area.name]["earnedFromExternal"], area_name_from_area_or_iaa_name(trade.seller), trade.offer.price) accumulated_trades = \ _area_trade_from_parent(area, parent, accumulated_trades, past_market_types) return accumulated_trades
def area(self, new_area): self._area = new_area self._iaa = make_iaa_name(new_area)
def __init__(self, *, owner, higher_market, lower_market, transfer_fee_pct=1, min_offer_age=1, engine_type=IAAEngine): super().__init__(engine_type=engine_type, owner=owner, higher_market=higher_market, lower_market=lower_market, transfer_fee_pct=transfer_fee_pct, min_offer_age=min_offer_age) self.name = make_iaa_name(owner)
def _get_child_traded_energy(market, child): return market.traded_energy.get( child.name, market.traded_energy.get(make_iaa_name(child), '-'))