Skip to content

Commit

Permalink
Merge pull request #162 from grid-parity-exchange/additional_callbacks
Browse files Browse the repository at this point in the history
Additional callbacks
  • Loading branch information
darrylmelander authored Dec 15, 2022
2 parents bc71466 + 8c54323 commit be09019
Show file tree
Hide file tree
Showing 9 changed files with 49 additions and 64 deletions.
13 changes: 0 additions & 13 deletions prescient/data/simulation_state/mutable_simulation_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from types import Iterable, Tuple
from prescient.engine.abstract_types import G, S

from collections import deque
Expand Down Expand Up @@ -70,26 +69,14 @@ def get_initial_generator_state(self, g:G) -> float:
''' Get the generator's state in the previous time period '''
return self._init_gen_state[g]

def get_all_initial_generator_state(self) -> Iterable[Tuple[G,float]]:
''' Get the generator's state in the previous time period for each generator '''
yield from self._init_gen_state.items()

def get_initial_power_generated(self, g:G) -> float:
''' Get how much power was generated in the previous time period '''
return self._init_power_gen[g]

def get_all_initial_power_generated(self) -> Iterable[Tuple[G,float]]:
''' Get how much power was generated in the previous time period for each generator '''
yield from self._init_power_gen.items()

def get_initial_state_of_charge(self, s:S) -> float:
''' Get state of charge in the previous time period '''
return self._init_soc[s]

def get_all_initial_state_of_charge(self) -> Iterable[Tuple[S,float]]:
''' Get state of charge in the previous time period for each storage device '''
yield from self._init_soc.items()

def get_current_actuals(self, forecastable:str) -> float:
''' Get the current actual value for forecastable
Expand Down
15 changes: 0 additions & 15 deletions prescient/data/simulation_state/simulation_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,31 +36,16 @@ def get_initial_generator_state(self, g:G):
''' Get the generator's state in the previous time period '''
pass

@abstractmethod
def get_all_initial_generator_state(self):
''' Get the generator's state in the previous time period for each generator '''
pass

@abstractmethod
def get_initial_power_generated(self, g:G):
''' Get how much power was generated in the previous time period '''
pass

@abstractmethod
def get_all_initial_power_generated(self):
''' Get how much power was generated in the previous time period for each generator '''
pass

@abstractmethod
def get_initial_state_of_charge(self, s:S):
''' Get state of charge in the previous time period '''
pass

@abstractmethod
def get_all_initial_state_of_charge(self):
''' Get state of charge in the previous time period for each storage device '''
pass

@abstractmethod
def get_current_actuals(self, forecastable:str) -> float:
''' Get the current actual value for a forecastable data item
Expand Down
13 changes: 0 additions & 13 deletions prescient/data/simulation_state/state_with_offset.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from types import Iterable, Tuple
from prescient.engine.abstract_types import G, S, EgretModel
from prescient.data.simulation_state.simulation_state import SimulationState

Expand Down Expand Up @@ -75,26 +74,14 @@ def get_initial_generator_state(self, g:G):
''' Get the generator's state in the previous time period '''
return self._init_gen_state[g]

def get_all_initial_generator_state(self) -> Iterable[Tuple[G,float]]:
''' Get the generator's state in the previous time period for each generator '''
yield from self._init_gen_state.items()

def get_initial_power_generated(self, g:G):
''' Get how much power was generated in the previous time period '''
return self._init_power_gen[g]

def get_all_initial_power_generated(self) -> Iterable[Tuple[G,float]]:
''' Get how much power was generated in the previous time period for each generator '''
yield from self._init_power_gen.items()

def get_initial_state_of_charge(self, s:S):
''' Get state of charge in the previous time period '''
return self._init_soc[s]

def get_all_initial_state_of_charge(self) -> Iterable[Tuple[S,float]]:
''' Get state of charge in the previous time period for each storage device '''
yield from self._init_soc.items()

def get_current_actuals(self, forecastable:str) -> float:
''' Get the current actual value for a forecastable data item
Expand Down
13 changes: 0 additions & 13 deletions prescient/data/simulation_state/time_interpolated_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from types import Iterable, Tuple
from prescient.engine.abstract_types import G, S

import math
Expand Down Expand Up @@ -123,26 +122,14 @@ def get_initial_generator_state(self, g:G):
''' Get the generator's state in the previous time period '''
return self._inner_state.get_initial_generator_state(g)

def get_all_initial_generator_state(self) -> Iterable[Tuple[G,float]]:
''' Get the generator's state in the previous time period for each generator '''
yield from self._inner_state.get_all_initial_generator_state()

def get_initial_power_generated(self, g:G):
''' Get how much power was generated in the previous time period '''
return self._inner_state.get_initial_power_generated(g)

def get_all_initial_power_generated(self) -> Iterable[Tuple[G,float]]:
''' Get how much power was generated in the previous time period for each generator '''
yield from self._inner_state.get_all_initial_power_generated()

def get_initial_state_of_charge(self, s:S):
''' Get state of charge in the previous time period '''
return self._inner_state.get_initial_state_of_charge(s)

def get_all_initial_state_of_charge(self) -> Iterable[Tuple[S,float]]:
''' Get state of charge in the previous time period for each storage device '''
yield from self._inner_state.get_all_initial_state_of_charge()

def get_current_actuals(self, forecastable:str) -> float:
''' Get the current actual value for a forecastable data item
Expand Down
5 changes: 4 additions & 1 deletion prescient/engine/egret/data_extractors.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,10 @@ def get_generator_bus(sced: OperationsModel, g: G) -> B:
def is_generator_on(sced: OperationsModel, g: G) -> bool:
g_dict = sced.data['elements']['generator'][g]
if 'fixed_commitment' in g_dict:
return g_dict['fixed_commitment']['values'][0] > 0
if isinstance(g_dict['fixed_commitment'], dict):
return g_dict['fixed_commitment']['values'][0] > 0
else:
return g_dict['fixed_commitment'] > 0
elif 'commitment' in g_dict:
return g_dict['commitment']['values'][0] > 0
else:
Expand Down
17 changes: 11 additions & 6 deletions prescient/engine/egret/egret_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ def create_sced_instance(data_provider:DataProvider,
assert current_state is not None

sced_md = data_provider.get_initial_actuals_model(options, sced_horizon, current_state.minutes_per_step)
options.plugin_context.callback_manager.invoke_after_get_initial_actuals_model_for_sced_callbacks(
options, sced_md)

# Set initial state
_copy_initial_state_into_model(options, current_state, sced_md)
Expand Down Expand Up @@ -382,6 +384,8 @@ def create_deterministic_ruc(options,

# Create a new model
md = data_provider.get_initial_forecast_model(options, ruc_horizon, 60)
options.plugin_context.callback_manager.invoke_after_get_initial_forecast_model_for_ruc_callbacks(
options, md)

initial_ruc = current_state is None or current_state.timestep_count == 0

Expand Down Expand Up @@ -627,6 +631,8 @@ def create_simulation_actuals(
# Get a new model
total_step_count = options.ruc_horizon * 60 // step_size_minutes
md = data_provider.get_initial_actuals_model(options, total_step_count, step_size_minutes)
options.plugin_context.callback_manager.invoke_after_get_initial_actuals_model_for_simulation_actuals_callbacks(
options, md)

# Fill it in with data
if this_hour == 0:
Expand Down Expand Up @@ -706,12 +712,11 @@ def _ensure_contingencies_monitored(options:Options, md:EgretModel, initial_ruc:
def _copy_initial_state_into_model(options:Options,
current_state:SimulationState,
md:EgretModel):
for g, initial_status in current_state.get_all_initial_generator_state():
md.data['elements']['generator'][g]['initial_status'] = initial_status
for g, initial_p_output in current_state.get_all_initial_power_generated():
md.data['elements']['generator'][g]['initial_p_output'] = initial_p_output
for s, initial_state_of_charge in current_state.get_all_initial_state_of_charge():
md.data['elements']['storage'][s]['initial_state_of_charge'] = initial_state_of_charge
for g, g_dict in md.elements('generator', generator_type='thermal'):
g_dict['initial_status'] = current_state.get_initial_generator_state(g)
g_dict['initial_p_output'] = current_state.get_initial_power_generated(g)
for s,s_dict in md.elements('storage'):
s_dict['initial_state_of_charge'] = current_state.get_initial_state_of_charge(s)

def get_attrs_to_price_option(options:Options):
'''
Expand Down
6 changes: 5 additions & 1 deletion prescient/plugins/internal.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@ class _StatisticsSubscribers(NamedTuple):

callbacks = ['options_preview',
'update_operations_stats',
'after_get_initial_actuals_model_for_sced',
'after_get_initial_forecast_model_for_ruc',
'after_get_initial_actuals_model_for_simulation_actuals',
'after_ruc_generation',
'after_ruc_activation',
'before_operations_solve',
'before_ruc_solve',
'after_operations',
'finalization',]
'finalization',
]

class PluginCallbackManager():
'''
Expand Down
27 changes: 27 additions & 0 deletions prescient/plugins/plugin_registration.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,33 @@ def register_initialization_callback(
'''
self.callback_manager.register_initialization_callback(callback)

def register_after_get_initial_actuals_model_for_sced_callback(
self,
callback: Callable[[Options, OperationsModel], None]
) -> None:
''' Request a method to be called immediately after an actuals model for the sced has
been generated, but before any data is loaded into it.
'''
self.callback_manager.register_after_get_initial_actuals_model_for_sced_callback(callback)

def register_after_get_initial_forecast_model_for_ruc_callback(
self,
callback: Callable[[Options, RucModel], None]
) -> None:
''' Request a method to be called immediately after an forecast model for the ruc has
been generated, but before any data is loaded into it.
'''
self.callback_manager.register_after_get_initial_forecast_model_for_ruc_callback(callback)

def register_after_get_initial_actuals_model_for_simulation_actuals_callback(
self,
callback: Callable[[Options, RucModel], None]
) -> None:
''' Request a method to be called immediately after an actuals model for the simulation_actuals has
been generated, but before any data is loaded into it.
'''
self.callback_manager.register_after_get_initial_actuals_model_for_simulation_actuals_callback(callback)

def register_finalization_callback(
self,
callback: Callable[[Options, Simulator], None]
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
packages = find_namespace_packages(include=['prescient.*'])

setup(name='gridx-prescient',
version='2.2.1.dev0',
version='2.2.1',
description='Power Generation Scenario creation and simulation utilities',
url='https://github.com/grid-parity-exchange/Prescient',
author='Jean-Paul Watson, David Woodruff, Andrea Staid, Dominic Yang',
Expand All @@ -40,6 +40,6 @@
'prescient.simulator.tests':['regression_tests_data/**/*'],
},
install_requires=['numpy','matplotlib','pandas','scipy','pyomo>=6.1.2',
'python-dateutil','networkx','jupyter', 'gridx-egret>=0.5.4.dev0',
'python-dateutil','networkx','jupyter', 'gridx-egret==0.5.3',
],
)

0 comments on commit be09019

Please sign in to comment.