Skip to content

Commit

Permalink
Merge pull request #31 from jgrguric96/documentation/DocStrings
Browse files Browse the repository at this point in the history
Merging pull request for the following changes:

1. Documentation of the Controllers folder 
2. Documentation of the Games folder
3. Minor spelling mistakes and fixes
  • Loading branch information
jgrguric96 authored Sep 9, 2024
2 parents 307bda5 + dc510ac commit ad84bd5
Show file tree
Hide file tree
Showing 17 changed files with 1,477 additions and 131 deletions.
2 changes: 1 addition & 1 deletion Agents/prosumer_S_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def prosumer(self, start:pd.Timestamp, time:pd.Timestamp, generators:pd.DataFram


class prosumer_S2(prosumer_python):
def prosumer(self, start, time, generators, demands, storages, em_accepted_bids, ft_transactions):
def prosumer(self, start:pd.Timestamp, time:pd.Timestamp, generators:pd.DataFrame, demands:pd.DataFrame, storages:pd.DataFrame, em_accepted_bids:list, ft_transactions:list) -> dict:
"""
Initializes all given parameters and returns
Expand Down
7 changes: 4 additions & 3 deletions Agents/prosumer_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,12 @@ def average(self:list, dates:list) -> list:

return hourly_average


# NOTE: Mosaik avoids using ABC to prevent python version issues.
class prosumer_python(ABC):
def __init__(self, eid, forecasted_data, metrics):
def __init__(self, eid:list, forecasted_data:list, metrics:list) -> None:
"""
prosumer_python class constructor
Used in Python based Mosaik simulations as an addition to the prosumer_mosaik.prosumerSim class.
...
Expand Down
120 changes: 97 additions & 23 deletions Agents/prosumer_mosaik.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,24 @@
incremental_attributes = ['generator', 'demand', 'storage']

class prosumerSim(mosaik_api.Simulator):
def __init__(self):
def __init__(self) -> None:
"""
Inherits the Mosaik API Simulator class and is used for python based simulations.
For more information properly inheriting the Mosaik API Simulator class please read their given documentation.
...
Attributes
----------
self.meta : dict
Contains metadata of the control sim such as type, models, parameters, attributes, etc.. Created via prosumerSim's parent class.
self.eid_prefix : string
The prefix with which each entity's name/eid will start
self.entities : dict
The stored model entity of the technology model
self._cache : doct
Used in the step function to store the values after running the python model of the technology
"""
super().__init__(META)
self.eid_prefix = 'prosumer_'
self.entities = {}
Expand All @@ -41,16 +58,16 @@ def init(self, sid:str, time_resolution:float, step_size:int=900) -> dict:
Parameters
----------
sid : str
The ID in string format
The String ID of the class
time_resolution : float
Sets the self.time_resolution variable
???
step_size : int
Sets the self.step_size variable
The size of the time step. The unit is arbitrary, but it has to be consistent among all simulators used in a simulation.
Returns
-------
self.meta : dict
Returns meta data
The metadata of the class
"""
self.step_size = step_size
self.sid = sid
Expand All @@ -65,25 +82,46 @@ def init(self, sid:str, time_resolution:float, step_size:int=900) -> dict:

def create(self, num:int, model:str, sim_start:str, strategy:str, **model_params) -> list:
"""
Description
Create `num` instances of `model` using the provided `model_params`.
...
Parameters
----------
num : int
Sets the loop range for prosumer
The number of model instances to create.
model : str
The name of the model
`model` needs to be a public entry in the simulator's ``meta['models']``.
sim_start : str
The start date of the simulation
Date and time (YYYY-MM-DD hh:mm:ss) of the start of the simulation in string format
strategy : str
A two character string that sets the strategy as one of the following: [s1, s2, s3].
Returns
-------
self._entities : list | dict
Returns an empty list if no model is created. Otherwise returns a list of dictionaries of model instances with their EIDs as keys.
self._entities : list
Return a list of dictionaries describing the created model instances (entities).
The root list must contain exactly `num` elements. The number of objects in sub-lists is not constrained::
[
{
'eid': 'eid_1',
'type': 'model_name',
'rel': ['eid_2', ...],
'children': [
{'eid': 'child_1', 'type': 'child'},
...
],
},
...
]
See Also
--------
The entity ID (*eid*) of an object must be unique within a simulator instance. For entities in the root list, `type` must be the same as the
`model` parameter. The type for objects in sub-lists may be anything that can be found in ``meta['models']``. *rel* is an optional list of
related entities; "related" means that two entities are somehow connect within the simulator, either logically or via a real data-flow (e.g.,
grid nodes are related to their adjacent branches). The *children* entry is optional and may contain a sub-list of entities.
"""
self.start = pd.to_datetime(sim_start)
self._entities = []
Expand All @@ -106,23 +144,37 @@ def create(self, num:int, model:str, sim_start:str, strategy:str, **model_params

def step(self, time:int, inputs:dict, max_advance:int) -> int:
"""
Description
Perform the next simulation step from time `time` using input values from `inputs`
...
Parameters
----------
time : int
Time in seconds
A representation of time with the unit being arbitrary. Has to be consistent among
all simulators used in a simulation.
inputs : dict
A dictionary containing parameters (???)
max_advance : int
INVALID: Unused in this method
Dict of dicts mapping entity IDs to attributes and dicts of values (each simulator has to decide on its own how to reduce
the values (e.g., as its sum, average or maximum)::
{
'dest_eid': {
'attr': {'src_fullid': val, ...},
...
},
...
}
max_advance : int
Tells the simulator how far it can advance its time without risking any causality error, i.e. it is guaranteed that no
external step will be triggered before max_advance + 1, unless the simulator activates an output loop earlier than that. For time-based
simulators (or hybrid ones without any triggering input) *max_advance* is always equal to the end of the simulation (*until*).
Returns
-------
step : int
A sum of time + step size returned as an integer
new_step : int
Return the new simulation time, i.e. the time at which ``step()`` should be called again.
"""
current_time = (self.start +
pd.Timedelta(time * self.time_resolution,
Expand Down Expand Up @@ -193,19 +245,41 @@ def step(self, time:int, inputs:dict, max_advance:int) -> int:

def get_data(self, outputs:dict) -> dict: # to be implemented
"""
Extracts data from outputs and cached data into a combined dictionary object
Return the data for the requested attributes in `outputs`
...
Parameters
----------
outputs : dict
Contains specific output actions such as buy or sell (???)
outputs : dict
Maps entity IDs to lists of attribute names whose values are requested::
{
'eid_1': ['attr_1', 'attr_2', ...],
...
}
Returns
-------
data : dict
The values related to the previously given actions
The return value is a dict of dicts mapping entity IDs and attribute names to their values::
{
'eid_1: {
'attr_1': 'val_1',
'attr_2': 'val_2',
...
},
...
'time': output_time (for event-based sims, optional)
}
See Also
--------
Time-based simulators have set an entry for all requested attributes, whereas for event-based and hybrid simulators this is optional (e.g.
if there's no new event). Event-based and hybrid simulators can optionally set a timing of their non-persistent output attributes via a *time* entry, which is valid
for all given (non-persistent) attributes. If not given, it defaults to the current time of the step. Thus only one output time is possible
per step. For further output times the simulator has to schedule another self-step (via the step's return value).
"""
data = {}
for eid, attrs in outputs.items():
Expand Down
77 changes: 39 additions & 38 deletions Controllers/GPController/gpcontroller_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@


class gpcontroller_python:
def __init__(self, soc_min:int, soc_max:int, h2_soc_min:int, h2_soc_max:int, fc_eff:float):
def __init__(self, soc_min:int, soc_max:int, h2_soc_min:int, h2_soc_max:int, fc_eff:float) -> None:
"""
Constructor for the gpcontroller_python class
Used in Python based Mosaik simulations as an addition to the gpcontroller_mosaik.gpcontrolSim class.
...
Parameters
----------
soc_min : int
???
The minimum state of charge (SOC)
soc_max : int
???
The maximum state of charge (SOC)
h2_soc_min : int
???
h2_soc_max : int
Expand All @@ -23,48 +24,48 @@ def __init__(self, soc_min:int, soc_max:int, h2_soc_min:int, h2_soc_max:int, fc_
Attributes
----------
soc_max_b : int
self.soc_max_b : int
Uses parameter soc_max
soc_min_b : int
self.soc_min_b : int
Uses parameter soc_min
soc_max_h2 : int
self.soc_max_h2 : int
Uses parameter h2_soc_max
soc_min_h2 : int
self.soc_min_h2 : int
Uses parameter h2_soc_min
fc_eff : float
self.fc_eff : float
Uses parameter fc_eff
net : int
= 0
deficit : int
= 0
excess : int
= 0
flow_b : list
self.net : int
Net Power calculated as Generated - Demand
self.deficit : int
Power that cannot be provided by batteries
self.excess : int
Power that cannot be stored in batteries
self.flow_b : list
= []
flow_e : int
self.flow_e : int
= 0
fc_out : int
self.fc_out : int
= 0
h_out : int
self.h_out : int
= 0
generators : pd.DataFrame()
Empty Dataframe (???)
demands : pd.DataFrame()
Empty Dataframe (???)
batteries : pd.DataFrame()
Empty Dataframe (???)
h2_soc : list
self.generators : pd.DataFrame
The ammount of power generated by a type of generator
self.demands : pd.DataFrame
The amount of power demanded
self.batteries : pd.DataFrame
Battery type and it's corresponding state of charge (SOC)
self.h2_soc : list
Empty list (???)
p_gen : list
self.p_gen : list
Empty list (???)
p_dem : list
self.p_dem : list
Empty list (???)
soc : list
Empty list (???)
curtailment : Boolean
False bool (???)
self.soc : list
State of Charge for every battery.
self.curtailment : Boolean
Should the reduction of power production be performed
"""
self.soc_max_b = soc_max
self.soc_min_b = soc_min
Expand Down Expand Up @@ -92,25 +93,25 @@ def __init__(self, soc_min:int, soc_max:int, h2_soc_min:int, h2_soc_max:int, fc_

def gpcontrol(self, generators:pd.DataFrame, demands:pd.DataFrame, batteries:pd.DataFrame, curtail:int) -> dict:#, fc_gen):
"""
Constructor for the gpcontroller_python class
Performs calculations of deficit and excess power generation based on the given generators, the demand of power, batteries and curtailment
...
Parameters
----------
generators : pd.DataFrame
???
The ammount of power generated by a type of generator
demands : pd.DataFrame
???
The amount of power demanded
batteries : pd.DataFrame
???
Battery type and it's corresponding state of charge (SOC)
curtail : int
???
The value of curtailment
Returns
-------
re_params : dict
???
Collection of parameters and their respective values
"""
self.generators = generators
self.demands = demands
Expand Down
Loading

0 comments on commit ad84bd5

Please sign in to comment.