Skip to content

Commit

Permalink
Merge branch 'dev' into feature/optimisation
Browse files Browse the repository at this point in the history
  • Loading branch information
j-ti committed Jul 11, 2024
2 parents 2ba7a7c + c3cdeec commit b210a49
Show file tree
Hide file tree
Showing 18 changed files with 366 additions and 211 deletions.
184 changes: 29 additions & 155 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ Getting started

Introduction
===============
Simply is an electricity market simulation frame work consisting of scripts for
Simply is an electricity market simulation package consisting of modules and scripts for

* scenario generation,
* market simulation and
* results visualisation and analysis.

Simply is an agent-based market simulation tool with market actors sending bids and asks to a
market, that can be cleared using different periodic `Matching Algorithms <https://simply.readthedocs.io/en/latest/matching_strategies.html>`_.
The algorithms take grid fees into account, which can be based on clusters defined by the agent's
market, that can be periodically cleared using different `Matching Algorithms <https://simply.readthedocs.io/en/latest/matching_strategies.html>`_.
The algorithms take grid fees into account, which can be based on locally differentiated clusters defined by the agent's
location in the network.
The matching algorithms can also be used individually via a wrapper using a json format for order
The matching algorithms can also be used individually as a module or via a wrapper using a json formatted order
definition.

Documentation
Expand All @@ -47,15 +47,13 @@ After cloning the repository, a virtual environment is created (e.g. using virtu
Then there are two options to use simply:

#.
Use the cloned repository directly and install the necessary dependencies using:
1. Use the cloned repository directly and install the necessary dependencies using:

.. code:: bash
pip install -r requirements.txt
#.
Or install the package in editable mode using:
2. Or install the package in editable mode using:

.. code:: bash
Expand All @@ -67,154 +65,25 @@ such as `matplotlib <https://matplotlib.org/>`_, `pandas <https://pandas.pydata.

Using Simply
============
The core of simply is the market matching algorithms. To be able to use the market matching algorithms, a
scenario is required as an input. The scenario can either be built from own data or randomly generated
by simply.
The core of simply is the market :ref:`matching_algorithms`. To be able to use the market matching algorithms, a
:ref:`scenarios` is required as an input. The scenario can either be built from own data or randomly generated
and simulated by simply as described below.

**Configuration file**
In all cases for using simply, a :ref:`config` (`config.cfg`) is required to specify the correct parameters
of the scenario and simulation.

In all cases for using simply, a configuration file (`config.cfg`) is required to specify the correct parameters
of the scenario and simulation. If a parameter is not specified in `config.cfg` and there is a default option,
this will be chosen. The file is split into the sections `scenario`, `market` and `outputs`, and
the parameters for each section are outlined as follows:
.. _run_build_scenario:

.. csv-table:: Scenario
:file: doc/files_to_be_displayed/scenario_params.csv
:widths: 30, 70, 30, 30
:header-rows: 1
Create your own scenario
------------------------

.. csv-table:: Market
:file: doc/files_to_be_displayed/market_params.csv
:widths: 30, 70, 30, 30
:header-rows: 1

.. csv-table:: Output
:file: doc/files_to_be_displayed/output_params.csv
:widths: 30, 70, 30, 30
:header-rows: 1

Building your own scenario
--------------------------

A scenario is built from a number of required inputs: data (load, pricing, production, load directory), information on each
actor, information on the network and a configuration file. The structure to build a scenario can be set up
as shown below. Note that the directory containing your data timeseries (scenario inputs) can be located elsewhere if you
specify in the command line. However, actors_config, config and network_config must all be stored in your project
directory:

::

|-- projects
|-- your_project_name
|-- scenario_inputs
|-- load
|-- your load timeseries
|-- price
|-- your price timeseries
|-- production
|-- your production timeseries
|-- loads_dir.csv
|-- actors_config.json
|-- config.cfg
|-- network_config.json

**Scenario inputs**

The input timeseries data can be in either csv or json format. Below shows the generic format of the input timeseries.
The `Time` column contains entries for each interval in the format `YYYY-MM-DD hh:mm:ss`, where the interval time is
specified in `config.cfg`. The number of entries must be equal to the number of timesteps
(also specified in `config.cfg`). The second column contains the values for each interval for either load, production or
pricing, and `col_name` will change based on which data is represented.

::

+---------------------+------------+
| Time | col_name |
+=====================+============+
| 2020-01-01 00:00:00 | 0.02 |
+---------------------+------------+
| 2020-01-01 00:00:15 | 0.05 |
+---------------------+------------+
| ... | ... |
+---------------------+------------+

.. note:: There are no units set in simply, so all input files must be consistent with their units!

**Actors configuration**

The `actors_config.json` file represents a template for setting up a market community consisting of the market maker
and other market participants. For each market actor, the following must be specified, analogous to the example file:

#. The name of the market actor, e.g. "residential_1".
#. The market actor type, i.e. "market_maker", "residential", "industrial" or "business".
#. The location of the actor in the community network, i.e. the network node at which the prosumer is located.
#. The information about power consumption and power devices (if any):

- The device type, i.e. "load", "solar" or "battery".
- The device ID: here is the name of a file (.json or .csv), which is to be stored under /sample and contains the load curve for the respective power consumption or the respective power device.

Each actor is represented with the following structure:

::

{
"comment": "An example of a residential prosumer with load and pv data specifed by their 'deviceID'",
"prosumerName": "residential_1",
"prosumerType": "residential",
"gridLocation": "N04",
"devices": [
{
"deviceType": "load",
"deviceID": "CHH10_sample.csv"
},
{
"deviceType": "solar",
"deviceID": "generated_pv.csv"
}
]
}


**Network configuration**

The file `network_config.json` represents a template for the construction of a market community network. Under "nodes"
the names of the individual nodes are listed (e.g. N01, N02). The market maker represents a separate node.
Under "links" the network charge is defined for each combination of two nodes. Nodes between which there is a network
charge of 0 represent a common cluster (see BEST Matching Algorithm). The general structure is shown below:

::

{
"example_network": {
"directed": false,
"multigraph": false,
"graph": {},
"nodes": [
{
"id": "N01"
},
{
... : ...
}
],
"links": [
{
"weight": 0,
"source": "N01",
"target": "N02"
},
{
... : ...,
... : ...,
... : ...
}
]
}
}
In order to build a scenario in a format that simply understands please prepare the data
as described by :ref:`build_scenario` (in :ref:`scenarios`), to define which data is associated
to which actor of the community and how they are connected by the network.

**Running build_scenario**

After the network and the community have been created, `build_scenario.py` can be executed. This is done by:
After the network and the community definitions have been set up, `build_scenario.py` can be executed. This is done by:

.. code:: bash
Expand All @@ -231,8 +100,8 @@ time series for each actor with power generation, power consumption, and market

An example of a scenario can be found in `projects/example_projects/example_project`.

Generating a random scenario
----------------------------
**Generating a randomized scenario**

There is also the option of generating a random scenario right before matching using `match_market.py`
(as explained in the section below). In this case, the parameters `nb_actors`,
`nb_nodes` and `weight_factor` should be specified in `config.cfg`, otherwise the default parameters are used. The only
Expand All @@ -245,10 +114,14 @@ input required before running the main simply function is the `config.cfg` file
|-- config.cfg

An example of config file and a generated random scenario can be found in `projects/example_projects/random_scenario`.
For more details please also see :ref:`scenarios`.

.. _run_simulation:

Running the simulation
----------------------

Running the match market function
---------------------------------
The match market function is executed by:
A simulation is executed by running the `match_market.py` script:

.. code:: bash
Expand All @@ -259,7 +132,8 @@ scenario - here is where time series for each actor with power generation, power
(including bid price) can be found.

For both instances, once you run `match_market.py` the results will be stored in path/to/your/project/dir/market_results.
Here you can see the results for the matches and orders in the network.
Here you can see the results in csv-format for the matches and orders of actors in the network
as well as individual results per actor.

License
=======
Expand Down
19 changes: 5 additions & 14 deletions build_scenario.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import datetime
import os
import json
import shutil
import warnings

import pandas as pd
import numpy as np
from pathlib import Path
import argparse

from simply.actor import Actor
from simply.scenario import Scenario
from simply.power_network import create_power_network_from_config
from simply.config import Config
from simply.util import dates_to_datetime

"""
This script creates a simulation scenario from a config JSON file, network JSON file,
Expand Down Expand Up @@ -68,14 +68,6 @@ def remove_existing_dir(path):
shutil.rmtree(path)


def dates_to_datetime(start_date="2016-01-01", nb_ts=None, horizon=24, ts_hour=1):
"""Converts string dates to datetime dtype and calculates end date from timesteps parameter."""
start_date = pd.to_datetime(start_date)
time_change = datetime.timedelta(minutes=(nb_ts + horizon - 1) * (60 / ts_hour))
end_date = start_date + time_change
return start_date, end_date


def basic_strategy(df, csv_peak, ps, ls):
"""Scales load and pv by peak or scaling factor parameter and calculates schedule."""
if ls:
Expand Down Expand Up @@ -137,7 +129,7 @@ def create_actor_from_config(actor_id, environment, asset_dict={}, start_date="2
:return: Actor object
"""
df = pd.DataFrame([], columns=cols)
start_date, end_date = dates_to_datetime(start_date, nb_ts + 1, horizon, ts_hour)
start_date, end_date, _ = dates_to_datetime(start_date, nb_ts + 1, horizon, ts_hour)
# Read csv files for each asset
csv_peak = {}
battery_cap = 0
Expand Down Expand Up @@ -192,7 +184,7 @@ def create_scenario_from_config(
config_json, network_path, loads_dir_path, data_dirpath=None,
buy_sell_function=None,
weight_factor=1, ts_hour=4, nb_ts=None, horizon=24,
start_date=None, plot_network=False,
start_date="2016-01-01", plot_network=False,
price_filename="basic_prices.csv", mm_buy_col="buy_prices", mm_sell_col="sell_prices",
ps=None, ls=None):
"""
Expand Down Expand Up @@ -240,9 +232,8 @@ def create_scenario_from_config(
pn.plot()

if start_date is None:
start_date = "2016-01-01"
warnings.warn(f"No start date was given, use default date {start_date}.")
start_date, end_date = dates_to_datetime(start_date, nb_ts + 1, horizon, ts_hour)
start_date, end_date, _ = dates_to_datetime(start_date, nb_ts + 1, horizon, ts_hour)
try:
buy_prices = get_mm_prices(price_path / price_filename, start_date, end_date,
mm_buy_col, required=True)
Expand Down
3 changes: 3 additions & 0 deletions doc/files_to_be_displayed/actor_params.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
name,description,type,default
horizon,Horizon up to which energy management is considered,int,24
actor_strategy,strategy that every actor uses if not specified,int,0
2 changes: 1 addition & 1 deletion doc/files_to_be_displayed/market_params.csv
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name,description,type,default
start,initial timestep,int,0
nb_ts,number of timesteps in simulation,int,3
step_size,interval between simulation timesteps,int,1
market_type,selects matching strategy: NEED TO CLARIFY STRATEGIES,str,?
market_type,selects matching strategy: pab (pay-as-bid)| pac (pay-as-clear); fair (custom BEST matching),str,pab
reset_market,resets market after each interval (discards unmatched orders),bool,True
energy_unit,size of energy units to be traded individually,num,0.01
default_grid_fee,default grid fee to be used by the market maker,num,0
1 change: 1 addition & 0 deletions doc/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Welcome to simply's documentation!
:caption: Contents:

readme
scenarios
matching_strategies
pricing_strategies
actor_strategies
Expand Down
Loading

0 comments on commit b210a49

Please sign in to comment.