Skip to content

Commit

Permalink
Merge pull request #117 from Illuminator-team/model-dev
Browse files Browse the repository at this point in the history
Model dev
  • Loading branch information
JortGroen authored Jan 15, 2025
2 parents 1a456ad + 983c2a3 commit dc8cdbb
Show file tree
Hide file tree
Showing 12 changed files with 1,127 additions and 573 deletions.
110 changes: 98 additions & 12 deletions docs/developer/developer-docstrings.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,86 @@
# Docstrings
# Custom Model Development

The entirety of this project follows the [Numpy docstring style guide](https://numpydoc.readthedocs.io/en/latest/format.html), so for more information or questions please refer to the provided link.
The Illuminator supports and endorses the creation of custom models for your simulation needs. Templates for these models are provided in TODO LINK. Model creation can be done with basic prior programming knowledge and a basic understanding of inheritance and object oriented programming.

## Short summary
All new models must satisfy the below criteria, this is to ensure a smooth integration and contribution to the Illuminator. Any model created & submitted must fulfill the following conventions to be added to the Illuminator package.

The style guide states that all comments should start with triple quotation marks, seen below:
## Good Coding Practices

The points listed in this subsection are general good coding practices already utilised in the Illuminator. We encourage you to adopt these habits for this and any project you are a part of. Such practices directly improve the readability and maintainability of the project.

```python
def add(a, b):
"""
The sum of two numbers.
"""
return a + b
# Bad Example

def func(x, y):
return x + y

temp = func(10, 20)
print(temp)

# Good Example

def add_numbers(first_number, second_number):
return first_number + second_number

result = add_numbers(10, 20)
print(result)
```

### Meaningful Function & Variable Names

Functions and variables should have clean and meaningful names that clearly indicate their purpose and functionality.

A descriptive name provides context, reduces ambiguity, and eliminates the need for excessive comments to explain its use. Adhering to consistent naming conventions also ensures uniformity across the project and enhances collaboration.

### Unnecessary Computations

Avoid redundant computations, excessive loops, and duplicate code segments to enhance efficiency and reduce points of error.

Evaluate whether computations can be precomputed, reused, or consolidated to minimize resource consumption. By refactoring repetitive patterns into shared methods, you not only simplify maintenance but also prevent errors caused by inconsistent updates to duplicated logic.

If you come across any such improvement in the existing Illuminator code, we would love to hear them! Contact the main developers at TODO LINK.

### Hard-Coded bits & Spaghetti Code

Hard-coded values and spaghetti code undermine the flexibility and scalability of a project and make debugging and future development exceedingly difficult. Prioritize clean, versatille design.

### Libraries, Dependencies & Versions

You are welcome to use any library or package in your custom models, try however to not import unused modules or entire libraries when only specific functionalities are required.

```python

# Bad Example:

import pandas # Entire library is imported but only DataFrame is used

df = pandas.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
print(df)

# Good Example:

from pandas import DataFrame # Only importing what is needed

df = DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
print(df)

```

The docstrings should also have a clearly separated sections for other parts of the code (if any). These may include, but is not limited to: Parameters, Attributes, Returns, Raises.
Additionally, please ensure you update and specify exact version numbers in dependency manifests (requirements.txt) to ensure that builds are reproducible and unaffected by breaking changes in newer releases.

## Project Documentation

Documentation and code comprehensibility are crucial for an open-source project like the Illuminator. Only through them can contributors and users understand, maintain, and improve the codebase effectively.

### Comments

Focus on adding comments where the code's purpose or logic is not immediately obvious to the reader. Avoid redundant comments that merely restate the code or clutter the file.

### Docstrings

Docstrings are crucial to custom models because each model's documentation is generated through them. Follow the current style for functions and classes.

The docstrings should have a clearly separated sections for other parts of the code (if any). These may include, but is not limited to: Parameters, Attributes, Returns, Raises.

Each separated section should start with the Title of the section, followed by a row of dashes such as in the following section:

Expand Down Expand Up @@ -42,6 +108,7 @@ def multiply(a, b):
When appropriate, we should also ensure to include the name and/or type of variables for the any of the aforementioned sections.

Lastly, type hints are also a useful addition to any code. They can be used to "hint" to other developers what is expected as input and/or output when a function is used.

```python
def sum(a:int, b:int) -> float:
```
Expand Down Expand Up @@ -71,10 +138,29 @@ def sum(a:int, b:int) -> float:
result = a + b
return result
```
Docstrings are essential to the Illuminator since each model's documentation is automatically generated through them. It is a model developers responsibility to ensure thorough documentation of their implemented model.

### Consistency & Linting

Always adhere to the conventions and style used in the existing code, including naming patterns, indentation, spacing, and structure. For example, if camelCase is used for variable names, avoid switching to snake_case.

Tools like linters and formatters can help enforce these conventions, this project utilises pylint TODO LINK across its codebase. This package also helps maintain good coding practices mentioned in TODO LINK. Any submitted code must pass pylint's format check.

## Model Testing

This section lists the testing methods you must implement along with your model to verify it operates properly within the rest of the Illuminator framework.

### Scenario Implementation

Creating a YAML scenario file for your custom model is essential for verifying that it integrates and runs properly within the simulation framework. This file essentially acts as a lightweight end-to-end test, providing an easy way to confirm that the model behaves as expected.

### Unit Tests

Unit tests are a critical component of ensuring the internal functionality of your custom model. These tests validate individual methods and components to confirm that they produce the expected outputs for a variety of input cases, including edge scenarios. Further instructions can be found in TODO LINK.

## Missing data in older docstrings
<!-- ## Missing data in older docstrings
There is still a lot of missing data for older docstrings, which has not been completed due to missing domain knowledge.
In order to contribute to those, one should simply search for any file which contains `???` in its docstrings and change it to whatever is appropriate.
In most cases, the description is missing since we could still acquire datatypes of attributes/parameters based on context clues or debugging/testing. However some bits of code are unused which means that it is also missing the type hints/docstring object types.
There exists an excel sheet within the `docs` folder called `Illuminator Model Classification.xlsx` which contains a semi-filled list of variables and their descriptions which can be used to help finish the incomplete docstrings.
There exists an excel sheet within the `docs` folder called `Illuminator Model Classification.xlsx` which contains a semi-filled list of variables and their descriptions which can be used to help finish the incomplete docstrings. -->
84 changes: 65 additions & 19 deletions examples/Tutorial1/Tutorial_1.yaml
Original file line number Diff line number Diff line change
@@ -1,29 +1,26 @@
scenario:
name: "Tutorial 1" # in mosaik so called world
start_time: '2012-01-01 00:00:00' # ISO 8601 start time of the simulation
start_time: '2012-06-01 00:00:00' # ISO 8601 start time of the simulation
#end_time: '2012-01-01 01:00:00' # duration in seconds
end_time: '2012-02-28 23:45:00' # duration in seconds
end_time: '2012-06-01 23:45:00' # duration in seconds
time_resolution: 900 # time step in seconds (optional). Defaults to 15 minutes (900 s)

models:
- name: CSVload
type: CSV
parameters:
start: '2012-01-01 00:00:00'
file_path: './examples/Tutorial1/load_data.txt'
delimiter: ','
date_format: 'YYYY-MM-DD HH:mm:ss'
- name: CSV_pv
type: CSV
parameters:
start: '2012-01-01 00:00:00'
file_path: './examples/Tutorial1/pv_data_Rotterdam_NL-15min.txt'
delimiter: ','
date_format: 'YYYY-MM-DD HH:mm:ss'
- name: CSV_wind
type: CSV
parameters:
start: '2012-01-01 00:00:00'
file_path: './examples/Tutorial1/winddata_NL.txt'
delimiter: ','
date_format: 'YYYY-MM-DD HH:mm:ss'
Expand All @@ -45,18 +42,35 @@ models:
time: None
forecast: None

- name: Load2
type: Load
parameters:
houses: 5 # number of houses that determine the total load demand
output_type: 'power' # type of output for consumption calculation ('energy' or 'power')
inputs:
load: 0 # incoming energy or power demand per house (kWh) for each time step (15 minutes)
outputs:
load_dem: 0 # total energy or power consumption for all houses (kWh) over the time step
consumption: 0 # Current energy or power consumption based on the number of houses and input load (kWh)
time: None, # Current simulation time step in seconds
forecast: None # Forecasted load demand (if applicable, not defined in the code but mentioned in META)
states:
consumption: 0
time: None
forecast: None

- name: PV1
type: PV # models can reuse the same type
parameters:
m_area: 1.26
NOCT: 44
m_area: 1.26 # m2
NOCT: 44 # Celcius
m_efficiency_stc: 0.198
G_NOCT: 800
P_STC: 250
peak_power: 600
m_tilt: 14
m_az: 180
cap: 500
G_NOCT: 800 # W/m2
P_STC: 250 # W
peak_power: 600 # W
m_tilt: 14 # degrees
m_az: 180 # degrees
cap: 500 # W
output_type: 'power'
inputs:
G_Gh: null
Expand Down Expand Up @@ -85,6 +99,8 @@ models:
outputs:
wind_gen: 0 # Generated wind power output (kW) or energy (kWh) based on the chosen output type (power or energy).
u: 0 # Adjusted wind speed (m/s) at 25m height after converting from the original height (e.g., 100m or 60m).
states:
u60: 5

- name: Battery1
type: Battery # models can reuse the same type
Expand All @@ -101,8 +117,9 @@ models:
outputs:
p_out: 0 # output power from the battery after discharge/charge decision (Kw)
p_in: 0 # input power to the battery (kW)
soc: 80 # updated state of charge after battery operation (%)
mod: 0 # operation mode: 0=no action, 1=charge, -1=discharge
states:
soc: 10 # state of charge of the battery (%)
flag: 0 # flag indicating battery status: 1=fully charged, -1=fully discharged, 0=available for control

- name: Controller1
Expand All @@ -114,6 +131,7 @@ models:
h2_soc_max: 0 # Maximum state of charge of the hydrogen storage before charging stops
fc_eff: 100 # Efficiency of the fuel cell
inputs:
u60: 0
wind_gen: 0 # Wind power generation
pv_gen: 0 # Solar power generation
load_dem: 0 # Electrical load demand
Expand All @@ -129,6 +147,8 @@ models:
connections:
- from: CSVload.load
to: Load1.load
- from: CSVload.load
to: Load2.load

- from: CSV_pv.G_Gh # start model, pattern: model_name.output_name/input_name
to: PV1.G_Gh # end model
Expand All @@ -148,20 +168,46 @@ connections:
- from: CSV_wind.u
to: Wind1.u

- from: Controller1.flow2b
to: Battery1.flow2b
time_shifted: True

- from: Wind1.wind_gen
to: Controller1.wind_gen
- from: Wind1.u60
to: Controller1.u60


- from: PV1.pv_gen
to: Controller1.pv_gen
- from: Load1.load_dem
to: Controller1.load_dem
# - from: Load2.load_dem
# to: Controller1.load_dem
- from: Battery1.soc
to: Controller1.soc

- from: Controller1.flow2b
to: Battery1.flow2b
time_shifted: True

monitor:
file: './out_Tutorial1.csv'
items:
- Battery1.soc
#- CSV_pv.G_Gh
# - Controller1.dump
# - PV1.pv_gen
# - Wind1.wind_gen
# - Load1.load_dem

- Controller1.flow2b
#- Controller1.res_load
- Controller1.dump
- Battery1.p_out
- Battery1.soc
- PV1.pv_gen
- Wind1.wind_gen
- Load1.load_dem
- Wind1.u60

#- CSVload.load
#- Load1.load_dem
#- Load2.load_dem
#- Controller1.load_dem
#- Battery1.soc
6 changes: 4 additions & 2 deletions examples/battery.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,10 @@ connections:
#time_shifted: True
- from: CSVB.flow2b
to: Battery1.flow2b
- from: CSVB.load
to: Load1.load
# - from: CSVB.load
# to: Load1.load
- from: Load1.load
to: Battery1.p_in

monitor:
file: './out_battery.csv' # optional with default, path to the results file for the scenario. This should be optional # a list of models, its inputs, output and states to be monitored and logged
Expand Down
Loading

0 comments on commit dc8cdbb

Please sign in to comment.