From 7a33c37b7408c5aeaa10d1f070af9b5b42ed6acc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20H=C3=B6ning?= Date: Sat, 11 Apr 2026 14:24:17 +0200 Subject: [PATCH 1/6] improve docs about running Redis container locally with a password so RQ-Dashboard works MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nicolas Höning --- documentation/host/installation.rst | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) 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 From 7450d21ecf8e41646476a01828871069c2c0c59a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20H=C3=B6ning?= Date: Sat, 11 Apr 2026 14:24:49 +0200 Subject: [PATCH 2/6] new page about scripting, mention HEMS example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nicolas Höning --- documentation/dev/scripting.rst | 90 +++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 documentation/dev/scripting.rst diff --git a/documentation/dev/scripting.rst b/documentation/dev/scripting.rst new file mode 100644 index 0000000000..3bba939806 --- /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 an asset: + +.. 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 cimpletely 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 vor 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. + +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. From 034df9142877e6d2e7aa90e9568ae49c5d6016a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20H=C3=B6ning?= Date: Sat, 11 Apr 2026 14:25:32 +0200 Subject: [PATCH 3/6] rename headers slightly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nicolas Höning --- documentation/index.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) 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 From bb279881921a0edb66ad70a1a946a505d994b7ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20H=C3=B6ning?= Date: Sat, 11 Apr 2026 14:28:49 +0200 Subject: [PATCH 4/6] add changelog entry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nicolas Höning --- documentation/changelog.rst | 1 + 1 file changed, 1 insertion(+) 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 ----------- From 1458893a435782c9e417b2f79d48389946033111 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20H=C3=B6ning?= Date: Sat, 11 Apr 2026 15:08:01 +0200 Subject: [PATCH 5/6] fix typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nicolas Höning --- documentation/dev/scripting.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/dev/scripting.rst b/documentation/dev/scripting.rst index 3bba939806..f95a18dfa2 100644 --- a/documentation/dev/scripting.rst +++ b/documentation/dev/scripting.rst @@ -60,7 +60,7 @@ To illustrate how far scripting with the client can go, we made an example where :target: https://raw.githubusercontent.com/FlexMeasures/screenshots/main/HEMS-tutorial-dashboard.png :align: center - The resulting dashboard of a cimpletely scripted HEMS system + The resulting dashboard of a completely scripted HEMS system This example ... From 681c4769629565587a7cd4c505b73dae42570248 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20H=C3=B6ning?= Date: Mon, 13 Apr 2026 18:19:01 +0200 Subject: [PATCH 6/6] implement review comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nicolas Höning --- documentation/dev/scripting.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/documentation/dev/scripting.rst b/documentation/dev/scripting.rst index f95a18dfa2..85739a80ae 100644 --- a/documentation/dev/scripting.rst +++ b/documentation/dev/scripting.rst @@ -14,7 +14,7 @@ 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 an asset: +Let's look at two examples, to give an impression. The first one creates a sensor: .. code-block:: python @@ -72,19 +72,19 @@ This example ... 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. +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 vor everyone - only if you are hosting FlexMeasures, can you run such scripts. +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. +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. +If you are developing your own plugin, you can freely write your own CLI commands. Read more on :ref:`plugin_showcase`.