diff --git a/idaes/apps/grid_integration/coordinator.py b/idaes/apps/grid_integration/coordinator.py index 4536965f24..b7c4375ecd 100644 --- a/idaes/apps/grid_integration/coordinator.py +++ b/idaes/apps/grid_integration/coordinator.py @@ -1,5 +1,6 @@ -from optparse import Option -import prescient.plugins +import prescient.plugins as pplugins +from prescient.simulator.config import PrescientConfig +from pyomo.common.config import ConfigDict, ConfigValue class DoubleLoopCoordinator: @@ -23,9 +24,11 @@ def __init__(self, bidder, tracker, projection_tracker): self.bidder = bidder self.tracker = tracker self.projection_tracker = projection_tracker - self.register_callbacks() - def register_callbacks(self): + def register_plugins(self, \ + context: pplugins.PluginRegistrationContext,\ + options: PrescientConfig,\ + plugin_config: ConfigDict): ''' Register functionalities in Prescient's plugin system. @@ -37,18 +40,19 @@ def register_callbacks(self): None ''' - # self._register_custom_commandline_options() - self._register_initialization_callbacks() - self._register_before_ruc_solve_callbacks() - self._register_before_operations_solve_callbacks() - self._register_after_operations_callbacks() - self._register_update_operations_stats_callbacks() - self._register_after_ruc_activation_callbacks() - self._register_finalization_callbacks() + self.plugin_config = plugin_config + + self._register_initialization_callbacks(context, options, plugin_config) + self._register_before_ruc_solve_callbacks(context, options, plugin_config) + self._register_before_operations_solve_callbacks(context, options, plugin_config) + self._register_after_operations_callbacks(context, options, plugin_config) + self._register_update_operations_stats_callbacks(context, options, plugin_config) + self._register_after_ruc_activation_callbacks(context, options, plugin_config) + self._register_finalization_callbacks(context, options, plugin_config) return - def _register_custom_commandline_options(self): + def get_configuration(self, key): ''' Register customized commandline options. @@ -60,95 +64,22 @@ def _register_custom_commandline_options(self): None ''' + config = ConfigDict() + # Add command line options - opt = Option('--track-ruc-signal', - help='When tracking the market signal, RUC signals are used instead of the SCED signal.', - action='store_true', - dest='track_ruc_signal', - default=False) - prescient.plugins.add_custom_commandline_option(opt) - - opt = Option('--track-sced-signal', - help='When tracking the market signal, SCED signals are used instead of the RUC signal.', - action='store_true', - dest='track_sced_signal', - default=False) - prescient.plugins.add_custom_commandline_option(opt) - - opt = Option('--hybrid-tracking', - help='When tracking the market signal, hybrid model is used.', - action='store_true', - dest='hybrid_tracking', - default=False) - prescient.plugins.add_custom_commandline_option(opt) - - opt = Option('--track-horizon', - help="Specifies the number of hours in the look-ahead horizon " - "when each tracking process is executed.", - action='store', - dest='track_horizon', - type='int', - default=48) - prescient.plugins.add_custom_commandline_option(opt) - - opt = Option('--bidding-generator', - help="Specifies the generator we derive bidding strategis for.", - action='store', - dest='bidding_generator', - type='string', - default='102_STEAM_3') - prescient.plugins.add_custom_commandline_option(opt) - - opt = Option('--bidding', - help="Invoke generator strategic bidding when simulate.", - action='store_true', - dest='bidding', - default=False) - prescient.plugins.add_custom_commandline_option(opt) - - opt = Option('--deviation-weight', - help="Set the weight for deviation term when tracking", - action='store', - dest='deviation_weight', - type='float', - default=30) - prescient.plugins.add_custom_commandline_option(opt) - - opt = Option('--ramping-weight', - help="Set the weight for ramping term when tracking", - action='store', - dest='ramping_weight', - type='float', - default=20) - prescient.plugins.add_custom_commandline_option(opt) - - opt = Option('--cost-weight', - help="Set the weight for cost term when tracking", - action='store', - dest='cost_weight', - type='float', - default=1) - prescient.plugins.add_custom_commandline_option(opt) - - opt = Option('--rts_gmlc_data_dir', - help="the relative path to rts gmlc data set", - action='store', - dest='rts_gmlc_data_dir', - type='str', - default='./RTS-GMLC/RTS_Data/SourceData/') - prescient.plugins.add_custom_commandline_option(opt) - - opt = Option('--price_forecast_file', - help="the relative path to price forecasts", - action='store', - dest='price_forecast_file', - type='str', - default='../../prescient/plugins/price_forecasts/lmp_forecasts_concat.csv') - prescient.plugins.add_custom_commandline_option(opt) + config.declare('bidding_generator', + ConfigValue(domain = str, + description = 'Specifies the generator we derive bidding strategis for.', + default = None)).declare_as_argument('--bidding-generator') + ## How to access this option? + # options.plugin.{key}.bidding_generator - return + return config - def _register_initialization_callbacks(self): + def _register_initialization_callbacks(self, \ + context: pplugins.PluginRegistrationContext,\ + options: PrescientConfig,\ + plugin_config: ConfigDict): ''' Register initialization plugins, which run before Prescient simulation @@ -161,9 +92,12 @@ def _register_initialization_callbacks(self): None ''' - prescient.plugins.register_initialization_callback(self.initialize_customized_results) + context.register_initialization_callback(self.initialize_customized_results) - def _register_before_ruc_solve_callbacks(self): + def _register_before_ruc_solve_callbacks(self, \ + context: pplugins.PluginRegistrationContext,\ + options: PrescientConfig,\ + plugin_config: ConfigDict): ''' Register plugins that run before Prescient solves Reliability Unit @@ -176,9 +110,12 @@ def _register_before_ruc_solve_callbacks(self): None ''' - prescient.plugins.register_before_ruc_solve_callback(self.bid_into_DAM) + context.register_before_ruc_solve_callback(self.bid_into_DAM) - def _register_before_operations_solve_callbacks(self): + def _register_before_operations_solve_callbacks(self, \ + context: pplugins.PluginRegistrationContext,\ + options: PrescientConfig,\ + plugin_config: ConfigDict): ''' Register plugins that run before Prescient solves Securitiy Constrained @@ -191,9 +128,12 @@ def _register_before_operations_solve_callbacks(self): None ''' - prescient.plugins.register_before_operations_solve_callback(self.bid_into_RTM) + context.register_before_operations_solve_callback(self.bid_into_RTM) - def _register_after_operations_callbacks(self): + def _register_after_operations_callbacks(self, \ + context: pplugins.PluginRegistrationContext,\ + options: PrescientConfig,\ + plugin_config: ConfigDict): ''' Register plugins that run after Prescient solves Securitiy Constrained @@ -206,9 +146,12 @@ def _register_after_operations_callbacks(self): None ''' - prescient.plugins.register_after_operations_callback(self.track_sced_signal) + context.register_after_operations_callback(self.track_sced_signal) - def _register_update_operations_stats_callbacks(self): + def _register_update_operations_stats_callbacks(self, \ + context: pplugins.PluginRegistrationContext,\ + options: PrescientConfig,\ + plugin_config: ConfigDict): ''' Register plugins that update stats of Securitiy Constrained Economic @@ -221,9 +164,12 @@ def _register_update_operations_stats_callbacks(self): None ''' - prescient.plugins.register_update_operations_stats_callback(self.update_observed_thermal_dispatch) + context.register_update_operations_stats_callback(self.update_observed_thermal_dispatch) - def _register_after_ruc_activation_callbacks(self): + def _register_after_ruc_activation_callbacks(self, \ + context: pplugins.PluginRegistrationContext,\ + options: PrescientConfig,\ + plugin_config: ConfigDict): ''' Register plugins that update stats of Securitiy Constrained Economic @@ -236,9 +182,12 @@ def _register_after_ruc_activation_callbacks(self): None ''' - prescient.plugins.register_after_ruc_activation_callback(self.activate_DA_bids) + context.register_after_ruc_activation_callback(self.activate_DA_bids) - def _register_finalization_callbacks(self): + def _register_finalization_callbacks(self, \ + context: pplugins.PluginRegistrationContext,\ + options: PrescientConfig,\ + plugin_config: ConfigDict): ''' Register finalization plugins, which run after Prescient simulation @@ -251,7 +200,7 @@ def _register_finalization_callbacks(self): None ''' - prescient.plugins.register_finalization_callback(self.write_plugin_results) + context.register_finalization_callback(self.write_plugin_results) def initialize_customized_results(self, options, simulator): diff --git a/idaes/apps/grid_integration/examples/test_new_plugin.txt b/idaes/apps/grid_integration/examples/test_new_plugin.txt deleted file mode 100644 index 8f90f394cd..0000000000 --- a/idaes/apps/grid_integration/examples/test_new_plugin.txt +++ /dev/null @@ -1,34 +0,0 @@ -command/exec simulator.py ---data-directory=..|..|..|..|..|..|doubleloop|Prescient|downloads|rts_gmlc|deterministic_with_network_scenarios ---simulate-out-of-sample ---run-sced-with-persistent-forecast-errors -#--model-directory=..|..|..|..|..|..|doubleloop|Prescient|prescient|models|tight ---output-directory=bidding_plugin_test_output_new_forecasts -#--output-directory=repeat_old_results_output ---run-deterministic-ruc ---start-date=07-10-2020 ---num-days=1 ---sced-horizon=4 ---traceback -#--random-seed=10 ---compute-market-settlements ---day-ahead-pricing=LMP -#--output-sced-initial-conditions -#--output-sced-demands -#--output-sced-solutions -#--output-ruc-initial-conditions -#--output-ruc-solutions -#--output-ruc-dispatches -#--output-solver-logs ---ruc-mipgap=0.01 ---symbolic-solver-labels ---reserve-factor=0.0 ---deterministic-ruc-solver=cbc ---sced-solver=cbc ---plugin=thermal_generator_prescient_plugin -#--rts_gmlc_data_dir=..|..|..|..|..|..|doubleloop|Prescient|downloads|rts_gmlc|RTS-GMLC|RTS_Data|SourceData| -#--price_forecast_file=price_forecasts|102_std1_lmp_forecasts.csv -#--bidding -#--bidding-generator=102_STEAM_3 -#--track-sced-signal -#--hybrid-tracking diff --git a/idaes/apps/grid_integration/examples/thermal_generator.py b/idaes/apps/grid_integration/examples/thermal_generator.py index c705cdb2b2..edb9bd3cd6 100644 --- a/idaes/apps/grid_integration/examples/thermal_generator.py +++ b/idaes/apps/grid_integration/examples/thermal_generator.py @@ -7,6 +7,7 @@ from tracker import Tracker from bidder import Bidder from forecaster import PlaceHolderForecaster +from prescient.simulator import Prescient class ThermalGenerator: @@ -520,8 +521,9 @@ def pmin(self): rts_gmlc_dataframe = pd.read_csv('gen.csv') solver = pyo.SolverFactory('cbc') - run_tracker = True - run_bidder = True + run_tracker = False + run_bidder = False + run_prescient = True if run_tracker: @@ -561,3 +563,25 @@ def pmin(self): hour = "13:00" bids = thermal_bidder.compute_bids(date, hour) thermal_bidder.write_results(path = './') + + if run_prescient: + + options = {'data_directory': '../../../../../../doubleloop/Prescient/downloads/rts_gmlc/deterministic_with_network_scenarios',\ + 'simulate_out_of_sample': True,\ + 'run_sced_with_persistent_forecast_errors': True,\ + 'output_directory': 'bidding_plugin_test_thermal_generator',\ + 'start_date':'07-10-2020',\ + 'num_days': 1,\ + 'sced_horizon':4,\ + 'compute_market_settlements': True,\ + 'day_ahead_pricing': 'LMP',\ + 'ruc_mipgap':0.01,\ + 'symbolic_solver_labels': True,\ + 'reserve_factor':0.0,\ + 'deterministic_ruc_solver':'cbc',\ + 'sced_solver':'cbc',\ + 'plugin': {'doubleloop': {'module': 'thermal_generator_prescient_plugin.py',\ + 'bidding_generator': '102_STEAM_3'}}\ + } + + Prescient().simulate(**options) diff --git a/idaes/apps/grid_integration/examples/thermal_generator_prescient_plugin.py b/idaes/apps/grid_integration/examples/thermal_generator_prescient_plugin.py index d6d20459be..ee02e5821c 100644 --- a/idaes/apps/grid_integration/examples/thermal_generator_prescient_plugin.py +++ b/idaes/apps/grid_integration/examples/thermal_generator_prescient_plugin.py @@ -1,11 +1,12 @@ import pandas as pd import pyomo.environ as pyo +from pyomo.common.config import ConfigDict, ConfigValue import sys sys.path.append('../') from tracker import Tracker from bidder import Bidder from forecaster import PlaceHolderForecaster -from prescient_plugin import DoubleLoopCoordinator +from coordinator import DoubleLoopCoordinator from thermal_generator import ThermalGenerator generator = "102_STEAM_3" @@ -55,3 +56,7 @@ coordinator = DoubleLoopCoordinator(bidder = thermal_bidder,\ tracker = thermal_tracker,\ projection_tracker = thermal_projection_tracker) + +## Prescient requires the following functions in this module +get_configuration = coordinator.get_configuration +register_plugins = coordinator.register_plugins