diff --git a/documentation/changelog.rst b/documentation/changelog.rst index 9a93b5c81b..4fef8746fe 100644 --- a/documentation/changelog.rst +++ b/documentation/changelog.rst @@ -33,6 +33,7 @@ Infrastructure / Support * Improve error logging for various exceptions [see `PR #2045 `_] * Update agent instructions and workflows to customize the primary entry point and to make the test environment used by agents and by the test workflow identical [see `PR #2066 `_, `PR #1998 `_ and `PR #2068 `_] * Filter out 404 (Not Found) errors from Sentry reports by default, configurable via ``FLEXMEASURES_DO_NOT_SEND_NOTFOUND_TO_SENTRY`` [see `PR #2071 `_] +* Document scripting with the client and in the CLI [see `PR #2097 `_] Bugfixes ----------- diff --git a/documentation/dev/scripting.rst b/documentation/dev/scripting.rst new file mode 100644 index 0000000000..85739a80ae --- /dev/null +++ b/documentation/dev/scripting.rst @@ -0,0 +1,90 @@ +.. _scripting: + +Scripting FlexMeasures +======================== + +Scripting means to write simple Python code so that FlexMeasures gets the data structure you need and will do what you want. + +There are two ways: Scripting via the FlexMeasures Client and via the CLI. + + +Scripting via the FlexMeasures-Client +-------------------------------------- + +The most universal way to script FlexMeasures is via `the FlexMeasures Client `_. +Actually, this is scripting via the API, as the client is not much more than a wrapper around the FlexMeasures server API. + +Let's look at two examples, to give an impression. The first one creates a sensor: + +.. code-block:: python + + # Create energy costs KPI sensor (1D resolution, EUR) + energy_costs_sensor = await client.add_sensor( + name="energy-costs-kpi", + event_resolution="P1D", + unit="EUR", + generic_asset_id=site_asset["id"], + timezone="Europe/Amsterdam", + ) + +The second one triggers a schedule and polls until it is ready: + +.. code-block:: python + + schedule = await flexmeasures_client.trigger_and_get_schedule( + asset_id=, # the asset ID (int) of the asset that all relevant power sensors belong to (or live under, in case of a tree-like asset structure) + start="2023-03-26T10:00+02:00", # ISO datetime + duration="PT12H", # ISO duration + flex-model=[ + # Example flex-model for an electric truck at a regular Charge Point + { + "sensor": , # int + "soc-at-start": "50 kWh", + "soc-targets": [ + {"value": "100 kWh", "datetime": "2023-03-03T11:00+02:00"}, + ], + }, + # Example flex-model for curtailable solar panels + { + "sensor": , # int + "power-capacity": "20 kVA", + "consumption-capacity": "0 kW", + "production-capacity": {"sensor": }, # int + }, + ], + ) + +To illustrate how far scripting with the client can go, we made an example where a whole simulation of a building with both EVs and heat pump is ran for a few days. + +.. figure:: https://raw.githubusercontent.com/FlexMeasures/screenshots/main/HEMS-tutorial-dashboard.png + :target: https://raw.githubusercontent.com/FlexMeasures/screenshots/main/HEMS-tutorial-dashboard.png + :align: center + + The resulting dashboard of a completely scripted HEMS system + + +This example ... + +- creates the whole structure - with PV, battery and a heat pump. +- loads two weeks of historical data and creates forecasts through the forecasting API. +- goes through one week in 4h steps, forecasting and scheduling all flexible assets. + +You can dive into the code `here `_. + + +We believe the client code is also a very good way to create small, reproducible examples. That can be quote productive to share small setups between teams or on GitHub for troubleshooting. + + +Scripting via the CLI +--------------------- + +Scripting via the CLI is not for everyone - only if you are hosting FlexMeasures, can you run such scripts. +It is also just Python code, but you need to be on the server to use them. + +A good example might be that the construction of the toy account (for use in the toy tutorials) is scripted via the CLI, see the command ``flexmeasures add toy-account``. + +We wrote a reasonably large library of :ref:`cli`. You can use them easily in Bash scripting. They do, however, take a bit of time to execute, as they first load the Flask app context. The client is faster, as the server does not need to restart anything. + +Some features that are not on the API (like, at the time of writing, account creation) would only work via the CLI. + +If you are developing your own plugin, you can freely write your own CLI commands. Read more on :ref:`plugin_showcase`. diff --git a/documentation/host/installation.rst b/documentation/host/installation.rst index 14f566547b..2a32705eab 100644 --- a/documentation/host/installation.rst +++ b/documentation/host/installation.rst @@ -379,15 +379,17 @@ A quick way to run redis locally (if you are testing your setup) is via Docker: .. code-block:: bash - $ docker run -d --rm --name fm-redis -p 6379:6379 redis - + $ docker run -d --rm --name fm-redis -p 6379:6379 redis redis-server --requirepass fm-redis-pass Then, start workers in a console (or some other method to keep a long-running process going): .. code-block:: bash - $ flexmeasures jobs run-worker --queue forecasting - $ flexmeasures jobs run-worker --queue scheduling + $ flexmeasures jobs run-worker --queue "scheduling|forecasting" + + +You can go to `http://localhost:5000/tasks/` and see the state of job queues and find individual jobs (and investigate why they failed, for instance). +You need to set ``FLEXMEASURES_REDIS_PASSWORD="fm-redis-pass"`` in your `~/.flexmeasures.cfg` config file for this to work. Two-factor authentication diff --git a/documentation/index.rst b/documentation/index.rst index 7d755d65cd..a771ccb589 100644 --- a/documentation/index.rst +++ b/documentation/index.rst @@ -238,7 +238,7 @@ In :ref:`getting_started`, we have some helpful tips how to dive into this docum .. toctree:: - :caption: Developing Plugins + :caption: Creating plugins :maxdepth: 1 plugin/introduction @@ -247,12 +247,13 @@ In :ref:`getting_started`, we have some helpful tips how to dive into this docum .. toctree:: - :caption: Developing on FlexMeasures + :caption: For developers :maxdepth: 1 dev/why - dev/setup-and-guidelines + dev/scripting dev/docker-compose + dev/setup-and-guidelines dev/ci dev/auth dev/dependency-management