diff --git a/.github/workflows/building-and-installation.yml b/.github/workflows/building-and-installation.yml index 74c792a..c90c6eb 100644 --- a/.github/workflows/building-and-installation.yml +++ b/.github/workflows/building-and-installation.yml @@ -2,14 +2,14 @@ name: Build # event that triggers workflow # runs on every pull request -on: +on: pull_request: branches: - - main + - main jobs: integration-tests: - # specifies the os that the job will run on + # specifies the os that the job will run on runs-on: ubuntu-latest strategy: matrix: @@ -18,7 +18,7 @@ jobs: # downloads the repository code to the runner's file system for workflow access - uses: actions/checkout@v4 - # sets up python environment with specified versions + # sets up python environment with specified versions - name: Set up python ${{ matrix.python-version }} id: setup-python uses: actions/setup-python@v5 @@ -45,17 +45,17 @@ jobs: run: poetry build # install package - - name: Install package - run: pip install dist/*.tar.gz - + - name: Install package + run: pip install dist/*.tar.gz + # Install dependencies needed for notebook execution - name: Install notebook dependencies - run: pip install jupyter nbconvert matplotlib + run: pip install jupyter nbconvert matplotlib windpowerlib # Execute example notebooks to verify that no errors are thrown - name: Run Jupyter Notebooks run: | - notebooks=("examples/signal_example.ipynb" "examples/basic_example.ipynb" "examples/controller_example.ipynb") + notebooks=("examples/signal_example.ipynb" "examples/basic_example.ipynb" "examples/controller_example.ipynb" "examples/stranger_sims_example.ipynb") for notebook in "${notebooks[@]}"; do jupyter nbconvert --to notebook --execute "$notebook" - done \ No newline at end of file + done diff --git a/docs/api_reference/index.rst b/docs/api_reference/index.rst index 81da1e4..1712d2d 100644 --- a/docs/api_reference/index.rst +++ b/docs/api_reference/index.rst @@ -46,10 +46,3 @@ Storage Module :maxdepth: 2 storage - -Power-Meter Module ------------------- -.. toctree:: - :maxdepth: 2 - - power_meter diff --git a/docs/tutorials/index.rst b/docs/tutorials/index.rst index 84f179c..322ec1c 100644 --- a/docs/tutorials/index.rst +++ b/docs/tutorials/index.rst @@ -9,6 +9,7 @@ Tutorials basic_example controller_example sil_example + stranger_sims_example .. note:: diff --git a/docs/tutorials/stranger_sims_example.ipynb b/docs/tutorials/stranger_sims_example.ipynb new file mode 120000 index 0000000..9e72d7b --- /dev/null +++ b/docs/tutorials/stranger_sims_example.ipynb @@ -0,0 +1 @@ +../../examples/stranger_sims_example.ipynb \ No newline at end of file diff --git a/examples/stranger_sims_example.ipynb b/examples/stranger_sims_example.ipynb new file mode 100644 index 0000000..54ffe48 --- /dev/null +++ b/examples/stranger_sims_example.ipynb @@ -0,0 +1,197 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Including other Simulators as Actors\n", + "\n", + "This example demonstrates how to integrate another python simulator such as the [windpowerlib](https://github.com/wind-python/windpowerlib) library to simulate a microgrid consisting of a data center and a\n", + "wind farm." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "import vessim as vs\n", + "from windpowerlib import WindTurbine, ModelChain\n", + "import pandas as pd\n", + "import numpy as np\n", + "\n", + "# Hotfix to execute asyncio in Jupyter\n", + "import nest_asyncio\n", + "nest_asyncio.apply()\n", + "\n", + "some_date = \"2024-07-17\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We configure wind turbines to calculate power output using synthetic weather\n", + "data. We define turbine data (Enercon E-126/4200, 135m hub height) and use a\n", + "list comprehension to create 30 turbines. Weather data for 24 hours is generated\n", + "with random wind speeds (5-15 km/h), temperatures (10-20°C), and a constant\n", + "roughness length of 0.1, organized in a pandas DataFrame. Using windpowerlib's\n", + "ModelChain, each turbine's power output is calculated based on the weather data.\n", + "The total power output from all 30 turbines is then summed." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "turbine_data = {\n", + " \"turbine_type\": \"E-126/4200\",\n", + " \"hub_height\": 135,\n", + "}\n", + "number_turbines = 30\n", + "wind_turbines = [WindTurbine(**turbine_data) for _ in range(number_turbines)]\n", + "hours = 24\n", + "\n", + "wind_speed = pd.Series(\n", + " np.random.uniform(5, 15, hours),\n", + " index=pd.date_range(start=some_date, periods=hours, freq=\"H\"),\n", + ")\n", + "temperature = pd.Series(\n", + " np.random.uniform(10, 20, hours),\n", + " index=pd.date_range(start=some_date, periods=hours, freq=\"H\"),\n", + ")\n", + "roughness = pd.Series(\n", + " [0.1] * hours,\n", + " index=pd.date_range(start=some_date, periods=hours, freq=\"H\")\n", + ")\n", + "\n", + "# the numbers are common reference heights\n", + "weather = pd.DataFrame(\n", + " {\n", + " (\"wind_speed\", 10): wind_speed, # wind speed defined at height 10m\n", + " (\"temperature\", 2): temperature, # temperature at 2m\n", + " (\"roughness_length\", 0): roughness,\n", + " }\n", + ")\n", + "\n", + "wind_power_output_all = sum(\n", + " ModelChain(turbine).run_model(weather).power_output for turbine in wind_turbines\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Using the pandas Dataframe from windpowerlib, we can now use a `HistoricalSignal` to create an `Actor` and add it to our microgrid." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2024-09-03 09:49:56.166 | INFO | mosaik.scenario:start:311 - Starting \"Actor\" as \"load\" ...\n", + "2024-09-03 09:49:56.170 | INFO | mosaik.scenario:start:311 - Starting \"Actor\" as \"wind_turbine\" ...\n", + "2024-09-03 09:49:56.171 | INFO | mosaik.scenario:start:311 - Starting \"Grid\" as \"Grid-0\" ...\n", + "2024-09-03 09:49:56.172 | INFO | mosaik.scenario:start:311 - Starting \"Controller\" as \"Monitor-2\" ...\n", + "2024-09-03 09:49:56.173 | INFO | mosaik.scenario:start:311 - Starting \"Storage\" as \"Storage-0\" ...\n", + "2024-09-03 09:49:56.175 | INFO | mosaik.scenario:run:651 - Starting simulation.\n", + "100%|\u001b[32m██████████\u001b[0m| 86400/86400 [00:00<00:00, 1792118.50steps/s]\n", + "2024-09-03 09:49:56.226 | INFO | mosaik.scenario:run:708 - Simulation finished successfully.\n" + ] + } + ], + "source": [ + "environment = vs.Environment(sim_start=some_date)\n", + "\n", + "monitor = vs.Monitor()\n", + "assert isinstance(wind_power_output_all, pd.Series)\n", + "environment.add_microgrid(\n", + " actors=[\n", + " vs.Actor(\n", + " name=\"load\",\n", + " signal=vs.MockSignal(value=120000000), # 120 MW\n", + " ),\n", + " vs.Actor(\n", + " name=\"wind_turbine\",\n", + " signal=vs.HistoricalSignal(wind_power_output_all)\n", + " ),\n", + " ],\n", + " controllers=[monitor],\n", + " step_size=3600,\n", + ")\n", + "\n", + "environment.run(until=24 * 3600) # 24h\n", + "monitor.to_csv(\"result.csv\")" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "import matplotlib.dates as mdates\n", + "\n", + "df = pd.read_csv(\"result.csv\", parse_dates=[0], index_col=0)\n", + "# divide e_delta by step size because e_delta is energy\n", + "\n", + "fig, ax1 = plt.subplots()\n", + "\n", + "ax1.plot(df.index, df[\"load.p\"], color=\"b\", label=\"load\")\n", + "ax1.legend()\n", + "ax1.plot(df.index, df[\"wind_turbine.p\"], color=\"y\", label=\"wind\")\n", + "ax1.legend()\n", + "ax1.xaxis.set_major_formatter(mdates.DateFormatter(\"%H\"))\n", + "ax1.grid()\n", + "ax1.set_xlabel(\"Time\")\n", + "ax1.set_ylabel(\"W\")\n", + "\n", + "plt.show()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.19" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/pyproject.toml b/pyproject.toml index 0bf0c7e..55d4878 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -80,6 +80,7 @@ nbsphinx = "*" pandoc = "*" ipython = "*" matplotlib = "*" +windpowerlib = "*" [build-system] requires = ["setuptools", "poetry-core>=1.1.0"]