def energy_bills(self, area, past_market_types): """ Return a bill for each of area's children with total energy bought and sold (in kWh) and total money earned and spent (in cents). Compute bills recursively for children of children etc. """ if not area.children: return None result = self._get_child_data(area) for market in self._get_past_markets_from_area(area, past_market_types): for trade in market.trades: buyer = area_name_from_area_or_iaa_name(trade.buyer) seller = area_name_from_area_or_iaa_name(trade.seller) if buyer in result: self._store_bought_trade(result[buyer], trade.offer) if seller in result: self._store_sold_trade(result[seller], trade.offer) for child in area.children: child_result = self.energy_bills(child, past_market_types) if child_result is not None: result[child.name]['children'] = child_result result[child.name]['market_fee'] = self.market_fees[child.name] return result
def energy_bills(area, past_market_types, from_slot=None, to_slot=None): """ Return a bill for each of area's children with total energy bought and sold (in kWh) and total money earned and spent (in cents). Compute bills recursively for children of children etc. """ if not area.children: return None result = { child.name: dict(bought=0.0, sold=0.0, spent=0.0, earned=0.0, type=get_area_type_string(child)) for child in area.children } for market in getattr(area, past_market_types): slot = market.time_slot if (from_slot is None or slot >= from_slot) and (to_slot is None or slot < to_slot): for trade in market.trades: buyer = area_name_from_area_or_iaa_name(trade.buyer) seller = area_name_from_area_or_iaa_name(trade.offer.seller) if buyer in result: result[buyer]['bought'] += trade.offer.energy result[buyer]['spent'] += trade.offer.price if seller in result: result[seller]['sold'] += trade.offer.energy result[seller]['earned'] += trade.offer.price for child in area.children: child_result = energy_bills(child, past_market_types, from_slot, to_slot) if child_result is not None: result[child.name]['children'] = child_result return result
def calculate_devices_sold_bought_energy(res_dict, market): if market is None: return for trade in market.trades: trade_seller = area_name_from_area_or_iaa_name(trade.seller) trade_buyer = area_name_from_area_or_iaa_name(trade.buyer) if trade_seller not in res_dict["sold_energy"]: res_dict["sold_energy"][trade_seller] = {"accumulated": {}} if trade_buyer not in res_dict["sold_energy"][trade_seller]: res_dict["sold_energy"][trade_seller][trade_buyer] = {} if trade.offer.energy > FLOATING_POINT_TOLERANCE: add_or_create_key(res_dict["sold_energy"][trade_seller]["accumulated"], market.time_slot, trade.offer.energy) add_or_create_key(res_dict["sold_energy"][trade_seller][trade_buyer], market.time_slot, trade.offer.energy) if trade_buyer not in res_dict["bought_energy"]: res_dict["bought_energy"][trade_buyer] = {"accumulated": {}} if trade_seller not in res_dict["bought_energy"][trade_buyer]: res_dict["bought_energy"][trade_buyer][trade_seller] = {} if trade.offer.energy > FLOATING_POINT_TOLERANCE: add_or_create_key(res_dict["bought_energy"][trade_buyer]["accumulated"], market.time_slot, trade.offer.energy) add_or_create_key(res_dict["bought_energy"][trade_buyer][trade_seller], market.time_slot, trade.offer.energy)
def aggregate_market_trades(self): """ Adds entry for each trade with exact time of trade. As multiple trades can happen in the same tick, a list of dict is returned. """ return [{ "trade_time": trade.time.timestamp(), "energy": trade.offer.energy, "seller": area_name_from_area_or_iaa_name(trade.seller), "buyer": area_name_from_area_or_iaa_name(trade.buyer) } for trade in self.current_market.trades]
def aggregate_exported_imported_energy(self, area): if area.uuid not in self.imported_energy: self.imported_energy[area.uuid] = {} if area.uuid not in self.exported_energy: self.exported_energy[area.uuid] = {} past_markets = list(area._markets.past_markets.values()) if len(past_markets) > 0: current_market = past_markets[-1] else: return child_names = [ area_name_from_area_or_iaa_name(c.name) for c in area.children ] for trade in current_market.trades: if child_buys_from_area(trade, area.name, child_names): add_or_create_key(self.exported_energy[area.uuid], current_market.time_slot_str, trade.offer.energy) if area_sells_to_child(trade, area.name, child_names): add_or_create_key(self.imported_energy[area.uuid], current_market.time_slot_str, trade.offer.energy) if current_market.time_slot_str not in self.imported_energy[area.uuid]: self.imported_energy[area.uuid][current_market.time_slot_str] = 0. if current_market.time_slot_str not in self.exported_energy[area.uuid]: self.exported_energy[area.uuid][current_market.time_slot_str] = 0.
def _aggregate_exported_imported_energy(self): if self._area.current_market is None: return None self.imported_traded_energy_kwh = {} self.exported_traded_energy_kwh = {} child_names = [ area_name_from_area_or_iaa_name(c.name) for c in self._area.children ] if getattr(self.current_market, 'trades', None) is not None: for trade in self.current_market.trades: if child_buys_from_area(trade, self._area.name, child_names): add_or_create_key(self.exported_traded_energy_kwh, self.current_market.time_slot, trade.offer_bid.energy) if area_sells_to_child(trade, self._area.name, child_names): add_or_create_key(self.imported_traded_energy_kwh, self.current_market.time_slot, trade.offer_bid.energy) if self.current_market.time_slot not in self.imported_traded_energy_kwh: self.imported_traded_energy_kwh[self.current_market.time_slot] = 0. if self.current_market.time_slot not in self.exported_traded_energy_kwh: self.exported_traded_energy_kwh[self.current_market.time_slot] = 0.
def _accumulate_storage_trade(storage, area, accumulated_trades, past_market_types): if storage.name not in accumulated_trades: accumulated_trades[storage.name] = { "type": "Storage", "produced": 0.0, "earned": 0.0, "consumedFrom": {}, "spentTo": {}, } markets = getattr(area, past_market_types) if markets is None: return accumulated_trades else: if type(markets) != list: markets = [markets] for market in markets: for trade in market.trades: if trade.buyer == storage.name: sell_id = area_name_from_area_or_iaa_name(trade.seller) accumulated_trades[ storage.name]["consumedFrom"] = add_or_create_key( accumulated_trades[storage.name]["consumedFrom"], sell_id, trade.offer.energy) accumulated_trades[ storage.name]["spentTo"] = add_or_create_key( accumulated_trades[storage.name]["spentTo"], sell_id, trade.offer.price) elif trade.offer.seller == storage.name: accumulated_trades[ storage.name]["produced"] -= trade.offer.energy accumulated_trades[ storage.name]["earned"] += trade.offer.price return accumulated_trades
def _accumulate_load_trades(load, grid, accumulated_trades, is_cell_tower, past_market_types): if load.name not in accumulated_trades: accumulated_trades[load.name] = { "type": "cell_tower" if is_cell_tower else "load", "produced": 0.0, "earned": 0.0, "consumedFrom": {}, "spentTo": {}, } markets = getattr(grid, past_market_types) if markets is None: return accumulated_trades else: if type(markets) != list: markets = [markets] for market in markets: for trade in market.trades: if trade.buyer == load.name: sell_id = area_name_from_area_or_iaa_name(trade.seller) accumulated_trades[ load.name]["consumedFrom"] = add_or_create_key( accumulated_trades[load.name]["consumedFrom"], sell_id, trade.offer.energy) accumulated_trades[ load.name]["spentTo"] = add_or_create_key( accumulated_trades[load.name]["spentTo"], sell_id, trade.offer.price) return accumulated_trades
def _track_energy_bought_type(self, trade): if area_name_from_area_or_iaa_name(trade.seller) == self.area.name: self.state.update_used_storage_share(trade.offer.energy, ESSEnergyOrigin.EXTERNAL) elif self._is_local(trade): self.state.update_used_storage_share(trade.offer.energy, ESSEnergyOrigin.LOCAL) else: self.state.update_used_storage_share(trade.offer.energy, ESSEnergyOrigin.UNKNOWN)
def _energy_bills(self, area, past_market_types): """ Return a bill for each of area's children with total energy bought and sold (in kWh) and total money earned and spent (in cents). Compute bills recursively for children of children etc. """ if not area.children: return None if area.name not in self.external_trades or \ ConstSettings.GeneralSettings.KEEP_PAST_MARKETS is True: self.external_trades[area.name] = dict(bought=0.0, sold=0.0, spent=0.0, earned=0.0, total_energy=0.0, total_cost=0.0, market_fee=0.0) result = self._get_child_data(area) for market in _get_past_markets_from_area(area, past_market_types): for trade in market.trades: buyer = area_name_from_area_or_iaa_name(trade.buyer) seller = area_name_from_area_or_iaa_name(trade.seller) if buyer in result: self._store_bought_trade(result[buyer], trade) if seller in result: self._store_sold_trade(result[seller], trade) # Outgoing external trades if buyer == area_name_from_area_or_iaa_name( area.name) and seller in result: self._store_outgoing_external_trade(trade, area) # Incoming external trades if seller == area_name_from_area_or_iaa_name( area.name) and buyer in result: self._store_incoming_external_trade(trade, area) for child in area.children: child_result = self._energy_bills(child, past_market_types) if child_result is not None: result[child.name]['children'] = child_result return result
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 _calculate_devices_sold_bought_energy_past_markets( self, area, past_markets): out_dict = {"sold_energy": {}, "bought_energy": {}} for market in past_markets: for trade in market.trades: trade_seller = area_name_from_area_or_iaa_name(trade.seller) trade_buyer = area_name_from_area_or_iaa_name(trade.buyer) if trade_seller not in out_dict["sold_energy"]: out_dict["sold_energy"][trade_seller] = {} out_dict["sold_energy"][trade_seller][ "accumulated"] = dict( (m.time_slot, 0) for m in area.past_markets) if trade_buyer not in out_dict["sold_energy"][trade_seller]: out_dict["sold_energy"][trade_seller][trade_buyer] = dict( (m.time_slot, 0) for m in area.past_markets) if trade.offer.energy > FLOATING_POINT_TOLERANCE: out_dict["sold_energy"][trade_seller]["accumulated"][market.time_slot] += \ trade.offer.energy out_dict["sold_energy"][trade_seller][trade_buyer][market.time_slot] += \ trade.offer.energy if trade_buyer not in out_dict["bought_energy"]: out_dict["bought_energy"][trade_buyer] = {} out_dict["bought_energy"][trade_buyer][ "accumulated"] = dict( (m.time_slot, 0) for m in area.past_markets) if trade_seller not in out_dict["bought_energy"][trade_buyer]: out_dict["bought_energy"][trade_buyer][ trade_seller] = dict( (m.time_slot, 0) for m in area.past_markets) if trade.offer.energy > FLOATING_POINT_TOLERANCE: out_dict["bought_energy"][trade_buyer]["accumulated"][market.time_slot] += \ trade.offer.energy out_dict["bought_energy"][trade_buyer][trade_seller][market.time_slot] += \ trade.offer.energy self._add_sold_bought_lists(out_dict) return out_dict
def _accumulate_load_trades(load, grid, accumulated_trades, is_cell_tower): accumulated_trades[load.name] = { "type": "cell_tower" if is_cell_tower else "load", "id": load.area_id, "produced": 0.0, "earned": 0.0, "consumedFrom": defaultdict(int), "spentTo": defaultdict(int), } for market in grid.past_markets: for trade in market.trades: if trade.buyer == load.name: sell_id = area_name_from_area_or_iaa_name(trade.seller) accumulated_trades[ load.name]["consumedFrom"][sell_id] += trade.offer.energy accumulated_trades[ load.name]["spentTo"][sell_id] += trade.offer.price return accumulated_trades
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_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