Skip to content

Commit

Permalink
Add tutorial for the Reporters (#825)
Browse files Browse the repository at this point in the history
* add CostReporter with tests

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* rename CostReporter to profit reporter

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* improve validation

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* add DataSource field to flexmeasures add report

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* fix: use source and make it an optional field

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* fix tests

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* add test + fix case of multiple sources

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* Add --id and --show-attributed field to flexmeasures show data-sources.

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* add sensors

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* add new command to create basic sources for the available reporters.

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* set sensor in ouput bdf

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* set resolution

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* add reporter tutorial

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* update docstring

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* add changelog entry

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* rename command + add changelog

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* allow passing multiple sources

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* extend changelog

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* clarify docstring

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* fix comments

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* check sources

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* use for loop in flexmeasures add sources

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* Add `is_profit` to `ProfitOrLossReporter`

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* Call a `Reporter` saved in the DB via CLI (#818)

* add DataSource field to flexmeasures add report

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* add new command to create basic sources for the available reporters.

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* Switch off HiGHS logs for `LOGGING_LEVEL=INFO` (#824)

* add log toggling for HiGHS

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* add changelog entry

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

---------

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* rename command + add changelog

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* use for loop in flexmeasures add sources

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* fix: typo

Signed-off-by: F.N. Claessen <felix@seita.nl>

* refactor: make 'kind' choice singular, so it matches the key in data_generators

Signed-off-by: F.N. Claessen <felix@seita.nl>

* docs: add inline todo

Signed-off-by: F.N. Claessen <felix@seita.nl>

* refactor: get db from where we normally get it

Signed-off-by: F.N. Claessen <felix@seita.nl>

* style: black

Signed-off-by: F.N. Claessen <felix@seita.nl>

---------

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>
Signed-off-by: F.N. Claessen <felix@seita.nl>
Co-authored-by: F.N. Claessen <felix@seita.nl>

* fix gramar and typos

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* add CLI changelog entry

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* rename kind reporting to reporter

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* expand on the description of the fm add report command

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* rename function create_sensor_asset

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* untitlelize words

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* rename sensor names

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* group data sources by type

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* Make source optional in the input field of the `AggregatorReporter` (#819)

* add DataSource field to flexmeasures add report

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* fix: use source and make it an optional field

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* fix tests

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* add test + fix case of multiple sources

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* add new command to create basic sources for the available reporters.

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* set sensor in ouput bdf

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* set resolution

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* update docstring

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* add changelog entry

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* rename command + add changelog

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* allow passing multiple sources

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* extend changelog

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* clarify docstring

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* check sources

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* use for loop in flexmeasures add sources

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

---------

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>
Signed-off-by: Victor <victor@seita.nl>

* untitlelize sensor names

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* rename is_profit to profit_is_positive

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* fix: `highs` string is in `solver_name` (#826)

* fix:  `highs` string is in `solve_name` using `in`

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* chore: update changelog

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

---------

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* Fix: public sensors to show (#830)

Fix two bugs dealing with public assets.


* fix: public sensors have None owner

Signed-off-by: F.N. Claessen <felix@seita.nl>

* docs: changelog entry

Signed-off-by: F.N. Claessen <felix@seita.nl>

* fix: searching for annotations on public assets

Signed-off-by: F.N. Claessen <felix@seita.nl>

* refactor: more explicit if-statement

Signed-off-by: F.N. Claessen <felix@seita.nl>

* docs: add second fix to changelog

Signed-off-by: F.N. Claessen <felix@seita.nl>

---------

Signed-off-by: F.N. Claessen <felix@seita.nl>

* sort data sources by type

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* move changelog entries to v.0.16.0

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* remove type column

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* use loss_is_positive instead of is_profit

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* grammar and typos

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* add link to *Pandas*

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* styling: rephrasings and one more typo

Signed-off-by: F.N. Claessen <felix@seita.nl>

* add new dependency vl-convert-python

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* fix: equal_v out of bound

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* rename Losses to Costs

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* doc change

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* update CLI changelog entry

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* add warning message in the tutorial

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* add changelog entry

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* add `a to entry

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

* Update toy-example-reporter.rst

small typo

Signed-off-by: Felix Claessen <30658763+Flix6x@users.noreply.github.com>

* rename attributes to asset_attributes

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>

---------

Signed-off-by: Victor Garcia Reolid <victor@seita.nl>
Signed-off-by: Victor <victor@seita.nl>
Signed-off-by: F.N. Claessen <felix@seita.nl>
Signed-off-by: Felix Claessen <30658763+Flix6x@users.noreply.github.com>
Co-authored-by: F.N. Claessen <felix@seita.nl>
Co-authored-by: Felix Claessen <30658763+Flix6x@users.noreply.github.com>
  • Loading branch information
3 people committed Aug 25, 2023
1 parent 45bf0f1 commit 0667a0c
Show file tree
Hide file tree
Showing 9 changed files with 414 additions and 27 deletions.
2 changes: 1 addition & 1 deletion documentation/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Infrastructure / Support
----------------------

* Allow additional datetime conversions to quantitative time units, specifically, from timezone-naive and/or dayfirst datetimes, which can be useful when importing data [see `PR #831 <https://github.com/FlexMeasures/flexmeasures/pull/831>`_]

* Add a new tutorial to explain the use of the `AggregatorReporter` to compute the headroom and the `ProfitOrLossReporter` to compute the cost of running a process [see `PR #825 <https://github.com/FlexMeasures/flexmeasures/pull/825>`_]

v0.15.1 | August XX, 2023
============================
Expand Down
7 changes: 4 additions & 3 deletions documentation/cli/change_log.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ FlexMeasures CLI Changelog
since v0.16.0 | September XX, 2023
=======================================
* Add command ``flexmeasures add sources`` to add the base `DataSources` for the `DataGenerators`.

* Add ``--kind reporter`` option to ``flexmeasures add toy-account`` to create the asset and sensors for the reporter tutorial.
* Add ``--id`` option to ``flexmeasures show data-sources`` to show just one ``DataSource``.
* Add ``--show-attributes`` flag to ``flexmeasures show data-sources`` to select whether to show the attributes field or not.

since v0.15.0 | August 9, 2023
=================================

================================
* Allow deleting multiple sensors with a single call to ``flexmeasures delete sensor`` by passing the ``--id`` option multiple times.
* Add ``flexmeasures add schedule for-process`` to create a new process schedule for a given power sensor.
* Add support for describing ``config`` and ``parameters`` in YAML for the command ``flexmeasures add report``, editable in user's code editor using the flags ``--edit-config`` or ``--edit-parameters``.
Expand Down
1 change: 1 addition & 0 deletions documentation/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ The platform operator of FlexMeasures can be an Aggregator.
tut/toy-example-from-scratch
tut/toy-example-expanded
tut/toy-example-process
tut/toy-example-reporter
tut/installation
tut/posting_data
tut/forecasting_scheduling
Expand Down
4 changes: 4 additions & 0 deletions documentation/tut/toy-example-process.rst
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ Finally, in the SHIFTABLE policy, the process is shifted to capture the best pri
Let's list the power price the policies achieved for each of the four blocks they scheduled:
.. _table-process:
+-------------------------+------------+-----------+-----------+
| Block | INFLEXIBLE | BREAKABLE | SHIFTABLE |
+=========================+============+===========+===========+
Expand All @@ -124,3 +126,5 @@ Let's list the power price the policies achieved for each of the four blocks the
+-------------------------+------------+-----------+-----------+
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.
This tutorial showed a quick way to optimize the activation of processes. In :ref:`tut_toy_schedule_reporter`, we'll turn to something different: using *reporters* to apply transformations to sensor data.
246 changes: 246 additions & 0 deletions documentation/tut/toy-example-reporter.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
.. _tut_toy_schedule_reporter:

Toy example IV: Computing reports
=====================================

.. warning::
The reporting functionality is still in an early development stage. Beware that major changes might be introduced.

So far, we have worked on scheduling batteries and processes. Now, we are moving to one of the other three pillars of FlexMeasures: reporting.

In essence, reporters apply arbitrary transformations to data coming from some sensors (multiple inputs) and save the results to other sensors (multiple outputs). In practice, this allows to compute KPIs (such as profit and total daily energy production), to apply operations to beliefs (e.g. changing the sign of a power sensor for some time period), among other things.

.. note::
Currently, FlexMeasures comes with the following reporters:
- `PandasReporter`: applies arbitrary `Pandas <https://pandas.pydata.org>`_ methods to sensor data.
- `AggregatorReporter`: combines data from multiple sensors into one using any of the methods supported by the Pandas `aggregate` function (e.g. sum, average, max, min...).
- `ProfitLossReporter`: computes the profit/loss due to an energy flow under a specific tariff.

Moreover, it's possible to implement your custom reporters in plugins. Instructions for this to come.

Now, coming back to the tutorial, we are going to use the `AggregatorReporter` and the `ProfitLossReporter`. In the first part, we'll use the `AggregatorReporter` to compute the (discharge) headroom of the battery in :ref:`tut_toy_schedule_expanded`. That way, we can verify the maximum power at which the battery can discharge at any point of time. In the second part, we'll use the `ProfitLossReporter` to compute the costs of operating the process of Tut. Part III in the different policies.

Before getting to the meat of the tutorial, we need to set up up all the entities. Instead of having to do that manually (e.g. using commands such as ``flexmeasures add sensor``), we have prepared a command that does that automatically.

Setup
.....

Just as in previous sections, we need to run the command ```flexmeasures add toy-account``, but this time with a different value for *kind*:

.. code-block:: bash
$ flexmeasures add toy-account --kind reporter
Under the hood, this command is adding the following entities:
- A yearly sensor that stores the capacity of the grid connection.
- A power sensor, `headroom`, to store the remaining capacity for the battery. This is where we'll store the report.
- A `ProfitLossReporter` configured to use the prices that we set up in Tut. Part II.
- Three sensors to register the profits/losses from running the three different processes of Tut. Part III.

Let's check it out!

Run the command below to show the values for the `grid connection capacity`:

.. code-block:: bash
$ TOMORROW=$(date --date="next day" '+%Y-%m-%d')
$ flexmeasures show beliefs --sensor-id 7 --start ${TOMORROW}T00:00:00+02:00 --duration PT24H --resolution PT1H
Beliefs for Sensor 'grid connection capacity' (ID 7).
Data spans a day and starts at 2023-08-14 00:00:00+02:00.
The time resolution (x-axis) is an hour.
┌────────────────────────────────────────────────────────────┐
│ │
│ │
│ │
│ │
│ │ 1.0MW
│ │
│ │
│ │
│▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀│ 0.5MW
│ │
│ │
│ │
│▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁│ 0.0MW
│ │
│ │
│ │
│ │ -0.5MW
└────────────────────────────────────────────────────────────┘
5 10 15 20
██ grid connection capacity
Moreover, we can check the freshly created source `<Source id=6>` which defines the `ProfitLossReporter` with the required configuration. You'll notice that the `config` is under the `data_generator` field. That's because reporters belong to a bigger category of classes that also contains the `Schedulers` and `Forecasters`.

.. code-block:: bash
$ flexmeasures show data-sources --show-attributes --id 5
ID Name Type User ID Model Version Attributes
---- ------------ -------- --------- -------------- --------- -----------------------------------------
6 FlexMeasures reporter ProfitLossReporter {
"data_generator": {
"config": {
"consumption_price_sensor": 1
}
}
}
Compute headroom
-------------------

In this case, the discharge headroom is nothing but the difference between the grid connection capacity and the PV power. To compute that quantity, we can use the `AggregatorReporter` using the weights to make the PV to subtract the grid connection capacity.

In practice, we need to create the `config` and `parameters`:

.. code-block:: bash
$ echo "
$ {
$ 'weights' : {
$ 'grid connection capacity' : 1.0,
$ 'PV' : -1.0,
$ }
$ }" > headroom-config.json
.. code-block:: bash
$ echo "
$ {
$ 'input' : [{'name' : 'grid connection capacity','sensor' : 7},
$ {'name' : 'PV', 'sensor' : 3}],
$ 'output' : [{'sensor' : 8}]
$ }" > headroom-parameters.json
Finally, we can create the reporter with the following command:

.. code-block:: bash
$ TOMORROW=$(date --date="next day" '+%Y-%m-%d')
$ flexmeasures add report --reporter AggregatorReporter \
--parameters headroom-parameters.json --config headroom-config.json \
--start-offset DB,1D --end-offset DB,2D \
--resolution PT15M
Now we can visualize the headroom in the following `link <http://localhost:5000/sensor/8/>`_, which should resemble the following image.

.. image:: https://github.com/FlexMeasures/screenshots/raw/main/tut/toy-schedule/sensor-data-headroom.png
:align: center
|
The graph shows that the capacity of the grid is at full disposal for the battery when there's no sun (thus no PV generation), while
at noon the battery can only discharge at 280kW max.

Process scheduler profit
-------------------------

For the second part of this tutorial, we are going to use the `ProfitLossReporter` to compute the losses (defined as `cost - revenue`) of operating the
process from Tut. Part III, under the three different policies: INFLEXIBLE, BREAKABLE and SHIFTABLE.

In addition, we'll explore another way to invoke reporters: data generators. Without going too much into detail, data generators
create new data. The thee main types are: `Reporters`, `Schedulers` and `Forecasters`. This will come handy as the three reports that
we are going to create share the same `config`. The `config` defines the price sensor to use and sets the reporter to work in **losses** mode which means
that it will return costs as positive values and revenue as negative values.

Still, we need to define the parameters. The three reports share the same structure for the parameters with the following fields:
* `input`: sensor that stores the power/energy flow. The number of sensors is limited to 1.
* `output`: sensor to store the report. We can provide sensors with different resolutions to store the same results at different time scales.

.. note::
It's possible to define the `config` and `parameters` in JSON or YAML formats.

After setting up `config` and `parameters`, we can invoke the reporter using the command ``flexmeasures add report``. The command takes the data source id,
the files containing the parameters and the timing parameters (start and end). For this particular case, we make use of the offsets to indicate that we want the
report to encompass the day of tomorrow.

Inflexible process
^^^^^^^^^^^^^^^^^^^

Define parameters in a JSON file:

.. code-block:: bash
$ echo "
$ {
$ 'input' : [{'sensor' : 4}],
$ 'output' : [{'sensor' : 9}]
$ }" > inflexible-parameters.json
Create report:

.. code-block:: bash
$ flexmeasures add report --source 6 \
--parameters inflexible-parameters.json \
--start-offset DB,1D --end-offset DB,2D
Check the results `here <http://localhost:5000/sensor/9/>`_. The image should be similar to the one below.

.. image:: https://github.com/FlexMeasures/screenshots/raw/main/tut/toy-schedule/sensor-data-inflexible.png
:align: center
|

Breakable process
^^^^^^^^^^^^^^^^^^^
Define parameters in a JSON file:

.. code-block:: bash
$ echo "
$ {
$ 'input' : [{'sensor' : 5}],
$ 'output' : [{'sensor' : 10}]
$ }" > breakable-parameters.json
Create report:

.. code-block:: bash
$ flexmeasures add report --source 6 \
--parameters breakable-parameters.json \
--start-offset DB,1D --end-offset DB,2D
Check the results `here <http://localhost:5000/sensor/10/>`_. The image should be similar to the one below.


.. image:: https://github.com/FlexMeasures/screenshots/raw/main/tut/toy-schedule/sensor-data-breakable.png
:align: center
|
Shiftable process
^^^^^^^^^^^^^^^^^^^

Define parameters in a JSON file:

.. code-block:: bash
$ echo "
$ {
$ 'input' : [{'sensor' : 6}],
$ 'output' : [{'sensor' : 11}]
$ }" > shiftable-parameters.json
Create report:

.. code-block:: bash
$ flexmeasures add report --source 6 \
--parameters shiftable-parameters.json \
--start-offset DB,1D --end-offset DB,2D
Check the results `here <http://localhost:5000/sensor/11/>`_. The image should be similar to the one below.


.. image:: https://github.com/FlexMeasures/screenshots/raw/main/tut/toy-schedule/sensor-data-shiftable.png
:align: center
|
Now, we can compare the results of the reports to the ones we computed manually in :ref:`this table <table-process>`). Keep in mind that the
report is showing the profit of each 15min period and adding them all shows that it matches with our previous results.

0 comments on commit 0667a0c

Please sign in to comment.