def __init__(self, job_id, initial_params, area, should_export_plots): self.job_id = job_id self.result_area_uuids = set() self.current_market = "" self.current_market_unix = None self.random_seed = initial_params["seed"] if initial_params[ "seed"] is not None else '' self.status = {} self.area_result_dict = self._create_area_tree_dict(area) self.flattened_area_core_stats_dict = {} self.simulation_progress = { "eta_seconds": 0, "elapsed_time_seconds": 0, "percentage_completed": 0 } self.should_export_plots = should_export_plots self.market_unmatched_loads = MarketUnmatchedLoads(area) self.price_energy_day = MarketPriceEnergyDay(should_export_plots) self.market_bills = MarketEnergyBills() self.cumulative_bills = CumulativeBills() if ConstSettings.BalancingSettings.ENABLE_BALANCING_MARKET: self.balancing_bills = MarketEnergyBills(is_spot_market=False) self.cumulative_grid_trades = CumulativeGridTrades() self.device_statistics = DeviceStatistics(should_export_plots) self.trade_profile = EnergyTradeProfile(should_export_plots) self.kpi = KPI(should_export_plots) self.area_throughput_stats = AreaThroughputStats() self.bids_offers_trades = {} self.last_energy_trades_high_resolution = {} if ConstSettings.GeneralSettings.EXPORT_OFFER_BID_TRADE_HR or \ ConstSettings.GeneralSettings.EXPORT_ENERGY_TRADE_PROFILE_HR: self.area_market_stocks_stats = OfferBidTradeGraphStats()
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 __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 = {}
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)
class SimulationEndpointBuffer: def __init__(self, job_id, initial_params, area, should_export_plots): self.job_id = job_id self.result_area_uuids = set() self.current_market = "" self.current_market_unix = None self.random_seed = initial_params["seed"] if initial_params[ "seed"] is not None else '' self.status = {} self.area_result_dict = self._create_area_tree_dict(area) self.flattened_area_core_stats_dict = {} self.simulation_progress = { "eta_seconds": 0, "elapsed_time_seconds": 0, "percentage_completed": 0 } self.should_export_plots = should_export_plots self.market_unmatched_loads = MarketUnmatchedLoads(area) self.price_energy_day = MarketPriceEnergyDay(should_export_plots) self.market_bills = MarketEnergyBills() self.cumulative_bills = CumulativeBills() if ConstSettings.BalancingSettings.ENABLE_BALANCING_MARKET: self.balancing_bills = MarketEnergyBills(is_spot_market=False) self.cumulative_grid_trades = CumulativeGridTrades() self.device_statistics = DeviceStatistics(should_export_plots) self.trade_profile = EnergyTradeProfile(should_export_plots) self.kpi = KPI(should_export_plots) self.area_throughput_stats = AreaThroughputStats() self.bids_offers_trades = {} self.last_energy_trades_high_resolution = {} if ConstSettings.GeneralSettings.EXPORT_OFFER_BID_TRADE_HR or \ ConstSettings.GeneralSettings.EXPORT_ENERGY_TRADE_PROFILE_HR: self.area_market_stocks_stats = OfferBidTradeGraphStats() @staticmethod def _structure_results_from_area_object(target_area): area_dict = dict() area_dict['name'] = target_area.name area_dict['uuid'] = target_area.uuid area_dict['type'] = str(target_area.strategy.__class__.__name__) \ if target_area.strategy is not None else "Area" area_dict['children'] = [] return area_dict def _create_area_tree_dict(self, area): area_result_dict = self._structure_results_from_area_object(area) for child in area.children: area_result_dict["children"].append( self._create_area_tree_dict(child)) return area_result_dict def update_results_area_uuids(self, area): if area.strategy is not None or (area.strategy is None and area.children): self.result_area_uuids.update({area.uuid}) for child in area.children: self.update_results_area_uuids(child) 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, "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.trade_profile.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.last_energy_trades_high_resolution, {}), "bids_offers_trades": self.bids_offers_trades, "results_area_uuids": list(self.result_area_uuids), } 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, "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.trade_profile.traded_energy_profile, {}, ui_format=True), "kpi": self.kpi.performance_indices, "area_throughput": self.area_throughput_stats.results, } def _populate_core_stats(self, area): if area.uuid not in self.flattened_area_core_stats_dict: self.flattened_area_core_stats_dict[area.uuid] = {} if self.current_market_unix is not None and \ self.current_market_unix not in self.flattened_area_core_stats_dict[area.uuid]: core_stats_dict = {'bids': [], 'offers': [], 'trades': []} if hasattr(area.current_market, 'offer_history'): for offer in area.current_market.offer_history: core_stats_dict['offers'].append(offer.serializable_dict()) if hasattr(area.current_market, 'bid_history'): for bid in area.current_market.bid_history: core_stats_dict['bids'].append(bid.serializable_dict()) if hasattr(area.current_market, 'trades'): for trade in area.current_market.trades: core_stats_dict['trades'].append(trade.serializable_dict()) self.flattened_area_core_stats_dict[area.uuid] = {} self.flattened_area_core_stats_dict[area.uuid][self.current_market_unix] = \ core_stats_dict for child in area.children: self._populate_core_stats(child) 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.current_market_unix = area.current_market.time_slot.timestamp( ) self._populate_core_stats(area) 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.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.trade_profile.update(area) self.update_area_aggregated_stats(area) if ConstSettings.GeneralSettings.EXPORT_OFFER_BID_TRADE_HR or \ ConstSettings.GeneralSettings.EXPORT_ENERGY_TRADE_PROFILE_HR: self.area_market_stocks_stats.update(area) self.result_area_uuids = set() self.update_results_area_uuids(area) def update_area_aggregated_stats(self, area): self._update_bids_offer_trades(area) self._merge_cumulative_bills_into_bills_for_market_info(area) for child in area.children: self.update_area_aggregated_stats(child) def _update_bids_offer_trades(self, area): if area.current_market is not None: self.bids_offers_trades[ area.uuid] = area.current_market.get_bids_offers_trades() def _merge_cumulative_bills_into_bills_for_market_info(self, area): 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}) area.stats.kpi.update( self.kpi.performance_indices_redis.get(area.uuid, {}))
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})