From e5444ce74e164890220da3ce9daa5c2f0241be75 Mon Sep 17 00:00:00 2001 From: Victor Garcia Reolid Date: Wed, 2 Aug 2023 20:10:56 +0200 Subject: [PATCH] address PR requests + adding table with results Signed-off-by: Victor Garcia Reolid --- documentation/tut/toy-example-expanded.rst | 2 +- .../tut/toy-example-from-scratch.rst | 19 +++-- documentation/tut/toy-example-process.rst | 70 +++++++++++-------- documentation/tut/toy-example-setup.rst | 59 +++++++++++----- 4 files changed, 91 insertions(+), 59 deletions(-) diff --git a/documentation/tut/toy-example-expanded.rst b/documentation/tut/toy-example-expanded.rst index 20fdca18d..8469dcc54 100644 --- a/documentation/tut/toy-example-expanded.rst +++ b/documentation/tut/toy-example-expanded.rst @@ -105,4 +105,4 @@ Second, charging of the battery is also changed a bit (around 10am), as less can We hope this part of the tutorial shows how to incorporate a limited grid connection rather easily with FlexMeasures. There are more ways to model such settings, but this is a straightforward one. -This tutorial showed the fastest way to a schedule. In :ref:`_tut_toy_schedule_process`, we'll go further into settings with more realistic ingredients: solar panels and a limited grid connection. \ No newline at end of file +This tutorial showed a quick way to add an inflexible load (like solar power) and a grid connection. In :ref:`tut_toy_schedule_process`, we'll turn to something different: the optimal timing of processes with fixed energy work and duration. diff --git a/documentation/tut/toy-example-from-scratch.rst b/documentation/tut/toy-example-from-scratch.rst index 76b57517b..3d18c032f 100644 --- a/documentation/tut/toy-example-from-scratch.rst +++ b/documentation/tut/toy-example-from-scratch.rst @@ -5,29 +5,26 @@ Toy example: Scheduling a battery, from scratch Let's walk through an example from scratch! We'll optimize a 12h-schedule for a battery that is half full. -What do you need? Your own computer, with one of two situations: either you have `Docker `_ or your computer supports Python 3.8+, pip and PostgresDB. The former might be easier, see the installation step below. But you choose. +Okay, let's get started! -Below are the ``flexmeasures`` CLI commands we'll run, and which we'll explain step by step. There are some other crucial steps for installation and setup, so this becomes a complete example from scratch, but this is the meat: +.. note:: You can copy the commands by hovering on the top right corner of code examples. You'll copy only the commands, not the output! -.. code-block:: bash +Setup +------ - # make the schedule - $ flexmeasures add schedule for-storage --sensor-id 1 --consumption-price-sensor 2 \ - --start ${TOMORROW}T07:00+01:00 --duration PT12H \ - --soc-at-start 50% --roundtrip-efficiency 90% +.. note:: If you haven't run through :ref:`tut_install_load_data` yet, do that first. There, we added power prices for a 24h window. +For this tutorial, we'll setup a battery asset and a (dis)charging sensor (ID 2) where the schedule will be stored into. -Okay, let's get started! -.. note:: You can copy the commands by hovering on the top right corner of code examples. You'll copy only the commands, not the output! Make a schedule --------------------------------------- -Finally, we can create the schedule, which is the main benefit of FlexMeasures (smart real-time control). +After going through the setup, we can finally create the schedule, which is the main benefit of FlexMeasures (smart real-time control). -We'll ask FlexMeasures for a schedule for our discharging sensor (ID 2). We also need to specify what to optimize against. Here we pass the Id of our market price sensor (ID 1). +We'll ask FlexMeasures for a schedule for our (dis)charging sensor (ID 2). We also need to specify what to optimize against. Here we pass the Id of our market price sensor (ID 1). To keep it short, we'll only ask for a 12-hour window starting at 7am. Finally, the scheduler should know what the state of charge of the battery is when the schedule starts (50%) and what its roundtrip efficiency is (90%). .. code-block:: bash diff --git a/documentation/tut/toy-example-process.rst b/documentation/tut/toy-example-process.rst index 0a2698a17..5d07a5c49 100644 --- a/documentation/tut/toy-example-process.rst +++ b/documentation/tut/toy-example-process.rst @@ -1,15 +1,13 @@ .. _tut_toy_schedule_process: - - Toy example III: Computing schedules for processes -==================================================================== +==================================================== Until this point we've been using a static battery, one of the most flexible energy assets, to reduce electricity bills. However, in some settings, we can reduce electricity bills by *just* consuming energy smartly. In other words, if the process can be displaced, by breaking it into smaller consumption periods or shifting its start time, the process run can match the lower price hours better. -For example, we could have a load that consumes energy at a constant rate (e.g. 100kW) for a fixed duration (e.g. 3h), but there's some flexibility in the start time. In that case, we could find the optimal start time in order to minimize the energy cost. +For example, we could have a load that consumes energy at a constant rate (e.g. 200kW) for a fixed duration (e.g. 4h), but there's some flexibility in the start time. In that case, we could find the optimal start time in order to minimize the energy cost. Examples of flexible processes are: - Water irrigation in agriculture @@ -36,14 +34,7 @@ Before moving forward, we'll add the `process` asset and three sensors to store .. code-block:: bash $ flexmeasures add toy-account --kind process - - Asset type solar already exists. - Asset type wind already exists. - Asset type one-way_evse already exists. - Asset type two-way_evse already exists. - Asset type battery already exists. - Asset type building already exists. - Asset type process already exists. + Account '' already exists. Skipping account creation. Use `flexmeasures delete account --id 1` if you need to remove it. User with email toy-user@flexmeasures.io already exists in account Toy Account. The sensor recording day-ahead prices is day-ahead prices (ID: 1). @@ -60,51 +51,74 @@ Before moving forward, we'll add the `process` asset and three sensors to store Trigger an updated schedule ---------------------------- -In this example, we are planning to consume 200kW for a period of 4h, tomorrow. +In this example, we are planning to consume at a 200kW constant power for a period of 4h. + +This load is to be schedule for tomorrow, except from the period from 3pm to 4pm (imposed using the ``--forbid`` flag). -In addition, we'll add a time period in which the scheduler won't be able to run the process. -Now we are ready to schedule a process. Let's start with the INFLEXIBLE policy, the simplest. The scheduler -cannot schedule the process to run within the first hour after midnight. +Now we are ready to schedule a process. Let's start with the INFLEXIBLE policy, the simplest. .. code-block:: bash flexmeasures add schedule for-process --sensor-id 4 --consumption-price-sensor 1\ --start ${TOMORROW}T00:00:00+02:00 --duration PT24H --process-duration PT4H \ --process-power 0.2MW --process-type INFLEXIBLE \ - --forbid "{\"start\" : \"${TOMORROW}T00:00:00+02:00\", \"duration\" : \"PT1H\"}" + --forbid "{\"start\" : \"${TOMORROW}T15:00:00+02:00\", \"duration\" : \"PT1H\"}" -This policy consist of scheduling the process as soon as possible. That is from 1am to 5am, as the time restriction from 12am to 1am makes the scheduler unable to start at 12am. +Under the INFLEXIBLE policy, the process starts as soon as possible, in this case, coinciding with the start of the planning window. Following the INFLEXIBLE policy, we'll schedule the same 4h block using a BREAKABLE policy. -In this other case, will restrict the period from 2pm to 3pm from scheduling any process. This block corresponds to the lowest price of the day. - .. code-block:: bash flexmeasures add schedule for-process --sensor-id 5 --consumption-price-sensor 1\ --start ${TOMORROW}T00:00:00+02:00 --duration PT24H --process-duration PT4H \ --process-power 0.2MW --process-type BREAKABLE \ - --forbid "{\"start\" : \"${TOMORROW}T14:00:00+02:00\", \"duration\" : \"PT1H\"}" + --forbid "{\"start\" : \"${TOMORROW}T15:00:00+02:00\", \"duration\" : \"PT1H\"}" -The BREAKABLE policy splits or breaks the process into blocks that can be scheduled discontinuously. - -Finally, we'll schedule the process using the SHIFTABLE policy. We'll keep the same time restrictions as in the BREAKABLE process. - +The BREAKABLE policy splits or breaks the process into blocks that can be scheduled discontinuously. The smallest possible unit is (currently) determined by the sensor's resolution. +Finally, we'll schedule the process using the SHIFTABLE policy. .. code-block:: bash flexmeasures add schedule for-process --sensor-id 6 --consumption-price-sensor 1\ --start ${TOMORROW}T00:00:00+02:00 --duration PT24H --process-duration PT4H \ --process-power 0.2MW --process-type SHIFTABLE \ - --forbid "{\"start\" : \"${TOMORROW}T14:00:00+02:00\", \"duration\" : \"PT1H\"}" + --forbid "{\"start\" : \"${TOMORROW}T15:00:00+02:00\", \"duration\" : \"PT1H\"}" + +Results +--------- + +The image below show the resulting schedules following each of the three policies. You will see similar results in your `FlexMeasures UI `_. + .. image:: https://github.com/FlexMeasures/screenshots/raw/main/tut/toy-schedule/asset-view-process.png :align: center | -The image above show the schedules following the three policies. -In the first policy, there's no flexibility and it needs to schedule as soon as possible. Meanwhile, in the BREAKABLE policy, the consumption blocks surrounds the time restriction to consume in the cheapest hours. Finally, in the SHIFTABLE policy, the process is shifted to capture the best prices, avoiding the time restrictions. \ No newline at end of file +In the first policy, there's no flexibility and it needs to schedule the process as soon as possible. +Meanwhile, in the BREAKABLE policy, the consumption blocks surrounds the time restriction to consume in the cheapest hours. Among the three polices, the BREAKABLE policy can achieve the best +Finally, in the SHIFTABLE policy, the process is shifted to capture the best prices, avoiding the time restrictions. + + +Quantitatively, comparing the total cost of running the process under each policy, the BREAKABLE policy achieves the best results. This is because it can fit much more consumption blocks in the cheapest hours. + + ++-------------------------+------------+-----------+-----------+ +| Block | INFLEXIBLE | BREAKABLE | SHIFTABLE | ++=========================+============+===========+===========+ +| 1 | 10.00 | 5.00 | 10.00 | ++-------------------------+------------+-----------+-----------+ +| 2 | 11.00 | 4.00 | 8.00 | ++-------------------------+------------+-----------+-----------+ +| 3 | 12.00 | 5.50 | 5.00 | ++-------------------------+------------+-----------+-----------+ +| 4 | 15.00 | 7.00 | 4.00 | ++-------------------------+------------+-----------+-----------+ +| Average Price (EUR/MWh) | 12.00 | 5.37 | 6.75 | ++-------------------------+------------+-----------+-----------+ +| Total Cost (EUR) | 9.60 | 4.29 | 5.40 | ++-------------------------+------------+-----------+-----------+ diff --git a/documentation/tut/toy-example-setup.rst b/documentation/tut/toy-example-setup.rst index cb2820ea3..b426c058d 100644 --- a/documentation/tut/toy-example-setup.rst +++ b/documentation/tut/toy-example-setup.rst @@ -117,11 +117,29 @@ FlexMeasures offers a command to create a toy account with a battery: .. code-block:: bash - $ flexmeasures add toy-account + $ flexmeasures add toy-account --kind battery + + Generic asset type `solar` created successfully. + Generic asset type `wind` created successfully. + Generic asset type `one-way_evse` created successfully. + Generic asset type `two-way_evse` created successfully. + Generic asset type `battery` created successfully. + Generic asset type `building` created successfully. + Generic asset type `process` created successfully. + Creating account Toy Account ... Toy account Toy Account with user toy-user@flexmeasures.io created successfully. You might want to run `flexmeasures show account --id 1` - The sensor recording battery power is . - The sensor recording day-ahead prices is . - The sensor recording solar forecasts is . + Adding transmission zone type ... + Adding NL transmission zone ... + Created day-ahead prices + The sensor recording day-ahead prices is day-ahead prices (ID: 1). + Created + Created discharging + Created + Created production + The sensor recording battery discharging is discharging (ID: 2). + The sensor recording solar forecasts is production (ID: 3). + + And with that, we're done with the structural data for this tutorial! @@ -138,17 +156,18 @@ If you want, you can inspect what you created: Account has no roles. All users: - - Id Name Email Last Login Roles - ---- -------- ------------------------ ------------ ------------- - 1 toy-user toy-user@flexmeasures.io account-admin + + ID Name Email Last Login Last Seen Roles + ---- -------- ------------------------ ------------ ----------- ------------- + 1 toy-user toy-user@flexmeasures.io None None account-admin All assets: + + ID Name Type Location + ---- ----------- ------- ----------------- + 2 toy-battery battery (52.374, 4.88969) + 3 toy-solar solar (52.374, 4.88969) - ID Name Type Location - ---- ------------ -------- ----------------- - 2 toy-battery battery (52.374, 4.88969) - 3 toy-solar solar (52.374, 4.88969) $ flexmeasures show asset --id 2 @@ -157,17 +176,18 @@ If you want, you can inspect what you created: ========================= Type Location Attributes - ------- ----------------- --------------------- + ------- ----------------- ---------------------------- battery (52.374, 4.88969) capacity_in_mw: 0.5 min_soc_in_mwh: 0.05 max_soc_in_mwh: 0.45 - sensors_to_show: [2, [3, 1]] + sensors_to_show: [1, [3, 2]] All sensors in asset: - - ID Name Unit Resolution Timezone Attributes + + ID Name Unit Resolution Timezone Attributes ---- ----------- ------ ------------ ---------------- ------------ - 2 discharging MW 15 minutes Europe/Amsterdam + 2 discharging MW 15 minutes Europe/Amsterdam + Yes, that is quite a large battery :) @@ -189,7 +209,7 @@ Visit `http://localhost:5000/ `_ (username is "toy-user@ Add some price data --------------------------------------- -Now to add price data. First, we'll create the csv file with prices (EUR/MWh, see the setup for sensor 1 above) for tomorrow. +Now to add price data. First, we'll create the CSV file with prices (EUR/MWh, see the setup for sensor 1 above) for tomorrow. .. code-block:: bash @@ -220,7 +240,7 @@ Now to add price data. First, we'll create the csv file with prices (EUR/MWh, se $ ${TOMORROW}T22:00:00,10 $ ${TOMORROW}T23:00:00,7" > prices-tomorrow.csv -This is time series data, in FlexMeasures we call "beliefs". Beliefs can also be sent to FlexMeasures via API or imported from open data hubs like `ENTSO-E `_ or `OpenWeatherMap `_. However, in this tutorial we'll show how you can read data in from a CSV file. Sometimes that's just what you need :) +This is time series data, in FlexMeasures we call *"beliefs"*. Beliefs can also be sent to FlexMeasures via API or imported from open data hubs like `ENTSO-E `_ or `OpenWeatherMap `_. However, in this tutorial we'll show how you can read data in from a CSV file. Sometimes that's just what you need :) .. code-block:: bash @@ -236,6 +256,7 @@ Let's look at the price data we just loaded: .. code-block:: bash $ flexmeasures show beliefs --sensor-id 1 --start ${TOMORROW}T00:00:00+01:00 --duration PT24H + Beliefs for Sensor 'day-ahead prices' (ID 1). Data spans a day and starts at 2022-03-03 00:00:00+01:00. The time resolution (x-axis) is an hour.