-
Notifications
You must be signed in to change notification settings - Fork 45
API endpoint for scheduling asset #1065
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
176 commits
Select commit
Hold shift + click to select a range
e2fced5
feature: copy trigger_schedule endpoint from SensorAPI to AssetAPI
Flix6x bfdd94f
fix: update function signature
Flix6x 5795e1b
fix: get rid of deprecation warning
Flix6x 2e4cfe0
fix: update docstring
Flix6x 2e28ed9
fix: imports
Flix6x f3711de
fix: obtain sensors from flex-model
Flix6x 305d76d
fix: create one scheduling job for each sensor listed in the flex-model
Flix6x f6e8075
fix: add todos
Flix6x 4bf91dc
docs: update endpoint main descriptions and quickrefs
Flix6x 0917896
style: black
Flix6x 753b411
fix: changelog syntax
Flix6x ba90dd1
fix: remove redundant session commit when calling the API to trigger …
Flix6x af4debf
docs: update FlexContextSchema docstring
Flix6x 49a1a12
feature: helpful message for test developers
Flix6x 8a3e112
feature: check auth on sensors referenced in flex-context
Flix6x 25d1180
feature: allow checking permissions on optional fields
Flix6x 21ac09a
feature: decorator supports custom error handler
Flix6x b4ad01a
docs: add inline note explaining status code
Flix6x 5b4c30f
feature: flex_context_loader lists all sensors contained in a flex-co…
Flix6x 484a022
feature: support context loader that returns multiple contexts
Flix6x 8374a9c
feature: check permissions on sensors referenced in flex-context
Flix6x 4621ef6
feature: add test checking permissions
Flix6x ff22fea
fix: response with field names
Flix6x be51f1b
add create_sequential_scheduling_job function
061e1f3
add fixtures
6eb122b
add test_create_sequential_jobs
b204e4b
Merge remote-tracking branch 'origin/feature/api/endpoint-for-schedul…
22834ca
Revert "fix: response with field names"
Flix6x dc07b11
Revert "feature: add test checking permissions"
Flix6x b583c89
Revert "feature: check permissions on sensors referenced in flex-cont…
Flix6x d04bed0
Revert "feature: support context loader that returns multiple contexts"
Flix6x 5fd2f63
Revert "feature: flex_context_loader lists all sensors contained in a…
Flix6x ee5e19e
Revert "docs: add inline note explaining status code"
Flix6x c2bf1af
Revert "feature: decorator supports custom error handler"
Flix6x 529baa2
Revert "feature: allow checking permissions on optional fields"
Flix6x 1665974
Revert "feature: check auth on sensors referenced in flex-context"
Flix6x 8678a0d
docs: add inline note explaining permission decorator
Flix6x f42ceaf
fix: remove unused parameter (does not need to be formally deprecated…
Flix6x 7b5b3ce
feature: check that each flexible device power sensor lives under the…
Flix6x e9e6ec9
Merge branch 'main' into feature/api/endpoint-for-scheduling-asset
378b0a7
docs: changelog entry
Flix6x 754502a
docs: API changelog entry
Flix6x e1e1019
feature: allow loading API data from three places, and avoid clashing…
Flix6x 4f86bb1
docs: typos
Flix6x de811ec
refactor: parameterize test cases
Flix6x 175cd18
refactor: merge AssetIdField and GenericAssetIDField
Flix6x ffe82b1
refactor: move to AssetTriggerSchema
Flix6x 45592c7
remove
Flix6x 99bd8da
remove: seemingly obsolete workaround
Flix6x 44cfd0c
feature: validate flex-model sensors belong to asset
Flix6x ee08883
feature: more clearly separate the serialized and deserialized parts …
Flix6x a9ddce8
feature: add end-to-end test for triggering and getting a schedule
Flix6x f340a95
docs: add fixture docstring explaining partial deserialization
Flix6x 4c6c52a
style: black
Flix6x b328921
fix: in case no inflexible-device-sensors were part of the flex-context
Flix6x b40d40e
docs: fix inline comment
Flix6x b7961f4
fix: job enqueueing
Flix6x 429d97f
style: black
Flix6x 8423522
refactor: rename argument; sequential scheduling is only for assets
Flix6x c60f5cf
docs: explain assert statement
Flix6x 8ba79aa
Merge remote-tracking branch 'refs/remotes/origin/main' into feature/…
Flix6x 9f5eb6a
style: black
Flix6x 71da5c4
handle fallback and rescheduling
07b44b6
style: flake8
Flix6x a25ab4d
Merge remote-tracking branch 'origin/feature/api/endpoint-for-schedul…
5f9a4dc
fix: clarify join to avoid `sqlalchemy.exc.AmbiguousForeignKeysError`
Flix6x 1f26fa2
Merge remote-tracking branch 'origin/feature/api/endpoint-for-schedul…
8b0c0d0
fix merge
edf38a8
Merge branch 'main' into feature/api/endpoint-for-scheduling-asset
05064ae
fix: remove 404, because the `asset` field should be seen as part of …
Flix6x c7e58cb
feature: avoid having magic number for status codes
Flix6x 36c75da
Merge remote-tracking branch 'refs/remotes/origin/main' into feature/…
Flix6x a15792c
fix: use new flex-context fields
Flix6x 75c80f5
chore: get rid of deprecation warning: The `sensor` keyword argument …
Flix6x 74c3ff5
fix: return the ID of the wrap-up job
Flix6x 0b6ab40
docs: move API changelog entry
Flix6x d14cb93
docs: mention the multi-device scheduler handles inflexible devices, too
Flix6x c8eb88e
fix: GenericAsset becomes asset_or_sensor_type=="genericasset" in the…
Flix6x 559c0ea
feat: test getting the schedule for each flexible device described in…
Flix6x d46a8aa
docs: add clarifying inline comment
Flix6x 7ecab71
feat: create charging hub (hierarchical structure of two existing CP …
Flix6x 2e91265
feat: add util function to sort jobs by time of creation
Flix6x 83ab8bd
feat: test a multi-asset flex-model comprising more than 1 flexible d…
Flix6x 29af4d3
feat: use StorageScheduler by default
Flix6x e44d472
feat: allow to toggle between sequential and simultaneous scheduling,…
Flix6x df0a2f7
fix: prepare to rename GenericAsset class to Asset
Flix6x 3c4113a
feat: test simultaneous and sequential scheduling via API
Flix6x fba0f6e
chore: clean up todo
Flix6x 5b3c06e
fix: update test
Flix6x d23fc7c
fix: correct type annotation
Flix6x 29144b1
fix: point API users to pick up their schedules for each power sensor…
Flix6x 0a9f811
docs: update endpoint documentation in docstring
Flix6x 36da302
docs: update notes regarding API endpoint(s) for triggering schedule …
Flix6x 9afcdef
fix: scheduler_kwargs should be JSON serializable
Flix6x f156981
fix: don't validate storage constraints on a non-storage device
Flix6x 4fdb4a6
docs: update main example on posting flex states
Flix6x 9b7f8bd
docs: update comment on persisting flexibility states
Flix6x c99045c
docs: update the trigger endpoints referenced in the scheduling section
Flix6x 85c144b
docs: update quickref
Flix6x f7e2843
docs: update note
Flix6x afed806
docs: fix grammar
Flix6x 217a632
docs: show different texts
Flix6x 7963c54
docs: clarify assumed sensor/asset structure
Flix6x f95dae6
docs: mention single-asset scheduling can still take into account inf…
Flix6x f054037
Merge remote-tracking branch 'refs/remotes/origin/main' into feature/…
Flix6x 7162ff0
docs: add code examples for API and flexmeasures-client for triggerin…
Flix6x 26f7f45
docs: add link to flexmeasures-client on PyPI
Flix6x 040b36f
docs: add missing sensor IDs to multi-asset flex-model
Flix6x 5666321
docs: fix RST syntax
Flix6x 588ae1a
docs: improve capitalization
Flix6x 67d3f05
docs: add code examples for API and flexmeasures-client for triggerin…
Flix6x 9fb381e
docs: sync timezone offsets across tutorials
Flix6x 650077b
docs: fix flex-model in API example
Flix6x d877518
docs: add multi-asset example for PV curtailment in API and flexmeasu…
Flix6x 43e3b4a
fix: serializable job kwargs
Flix6x e9c65a5
docs: add inline notes explaining the IDs in the flexmeasures-client …
Flix6x acbc49b
docs: fix url to trigger endpoint
Flix6x 4bc892c
docs: link to the endpoint docs instead of the actual endpoint, which…
Flix6x de35747
docs: better phrasing
Flix6x 1bd3b5a
style: emphasize new lines with respect to previous examples
Flix6x 48aaf0a
docs: add comment hinting at the parameter name we are introducing in…
Flix6x 29385fc
style: use a new line for each option
Flix6x 9df1392
fix: remove outdated comment (the consumption-price sensor is preconf…
Flix6x 8c141ef
feat: simplify expanded CLI example (the consumption-price sensor is …
Flix6x 075d61a
docs: refer to multiple schedules
Flix6x e85d511
docs: add note regarding the lack of flex-context in the example
Flix6x becdf12
docs: highlight consumption-price in flex-context
Flix6x b874ddd
docs: stop using the --consumption-price-sensor option in the Process…
Flix6x 99eae75
docs: reduce indentation of CLI command output
Flix6x 8040e90
docs: add missing $
Flix6x 07dc5bf
docs: rerun some tutorial steps to get the right indentation (updatin…
Flix6x 903b9c7
docs: fix header navigation
Flix6x b130b1e
docs: add example setting
Flix6x 822516c
docs: suggested changes
Flix6x 84f9cf9
docs: clarify curtailment model
Flix6x 81a54e0
docs: rewrite quickref
Flix6x 71dff5f
fix: revert accidental revision from resolving merge conflicts
Flix6x ca6bb86
feat: check resulting schedule
Flix6x 252af4c
fix: extending scheduling horizon with simultaneous scheduling was si…
Flix6x 0b09890
fix: update test accordingly
Flix6x 21d3f81
fix: test charging during cheapest hour
Flix6x a2b134c
fix: use soc-unit in multi-asset flex-models
Flix6x 2174073
fix: revise test expectations accordingly
Flix6x a5eaad4
Merge remote-tracking branch 'refs/remotes/origin/main' into feature/…
Flix6x a47efed
refactor: use explanatory util variable
Flix6x 0eabc38
refactor: remove obsolete argument
Flix6x 9aedfc6
feat: check constraints
Flix6x 47fc431
fix: only check the CP with a target
Flix6x 56f490b
fix: if/else logic
Flix6x 9354979
refactor: simplify
Flix6x 1cc6574
refactor: remove obsolete argument (second part)
Flix6x 26ae60c
refactor: remove another obsolete argument
Flix6x 55c6f5f
refactor: assign intermediate result to variable
Flix6x d143338
feat: test fetching SoC schedules
Flix6x 54be949
refactor: clarifying variable
Flix6x eff5761
Merge remote-tracking branch 'refs/remotes/origin/main' into feature/…
Flix6x 45a13f8
fix: API should only switch sign if the scheduling service switched i…
Flix6x 8ba2b50
dev: remove print statement
Flix6x 7fd964c
fix: "%" units not supported in Python 3.8?
Flix6x 10f7f1b
docs: add paragraph on interpreting schedules and making them suit sp…
Flix6x 22ba034
docs: use the same sensor ID as in the previous example from posting_…
Flix6x 59f10c9
docs: add note on retrieving the SoC schedule
Flix6x 673b378
docs: reference the sensor ID in the main body of text
Flix6x 363ad0a
docs: fill in API version 3
Flix6x 96db6e1
docs: also also
Flix6x 9befe96
docs: follow capitalization of package itself
Flix6x 58e7743
Merge remote-tracking branch 'refs/remotes/origin/main' into feature/…
Flix6x edc099e
refactor: simplify expected schedule
Flix6x 867e1ae
docs: clarify note
Flix6x d0f4e02
docs: clarify asserts
Flix6x 4fa292d
fix: np.assert_equal does not treat -0.0 the same as 0 (or as 0.0)
Flix6x 6dc8a98
Merge branch 'main' into feature/api/endpoint-for-scheduling-asset
nhoening ecb355f
docs: rephrase note
Flix6x 094bf05
docs: explain test expectations
Flix6x d1750b5
Merge remote-tracking branch 'refs/remotes/origin/main' into feature/…
Flix6x 8fc151c
Merge remote-tracking branch 'origin/feature/api/endpoint-for-schedul…
Flix6x File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -63,7 +63,7 @@ Setting the data source type to "forecaster" helps FlexMeasures to visually dist | |
| $ flexmeasures add beliefs --sensor 3 --source 4 solar-tomorrow.csv --timezone Europe/Amsterdam | ||
| Successfully created beliefs | ||
|
|
||
| The one-hour CSV data is automatically resampled to the 15-minute resolution of the sensor that is recording solar production. We can see solar production in the `FlexMeasures UI <http://localhost:5000/sensors/3>`_ : | ||
| The one-hour CSV data is automatically resampled to the 15-minute resolution of the sensor that is recording solar production. We can see solar production in the `FlexMeasures UI <http://localhost:5000/sensors/3>`_: | ||
|
|
||
| .. image:: https://github.com/FlexMeasures/screenshots/raw/main/tut/toy-schedule/sensor-data-production.png | ||
| :align: center | ||
|
|
@@ -75,17 +75,139 @@ The one-hour CSV data is automatically resampled to the 15-minute resolution of | |
| Trigger an updated schedule | ||
| ---------------------------- | ||
|
|
||
| Now, we'll reschedule the battery while taking into account the solar production. This will have an effect on the available headroom for the battery, given the ``site-power-capacity`` limit discussed earlier. | ||
|
|
||
| .. code-block:: bash | ||
|
|
||
| $ flexmeasures add schedule for-storage --sensor 2 --consumption-price-sensor 1 \ | ||
| --inflexible-device-sensor 3 \ | ||
| --start ${TOMORROW}T07:00+02:00 --duration PT12H \ | ||
| --soc-at-start 50% --roundtrip-efficiency 90% | ||
| New schedule is stored. | ||
|
|
||
| We can see the updated scheduling in the `FlexMeasures UI <http://localhost:5000/sensors/2>`_ : | ||
| Now, we'll reschedule the battery while taking into account the solar production (forecast) as an inflexible device. | ||
| This will have an effect on the available headroom for the battery, given the ``site-power-capacity`` limit discussed earlier. | ||
|
|
||
| .. tabs:: | ||
|
|
||
| .. tab:: CLI | ||
|
|
||
| .. code-block:: bash | ||
| :emphasize-lines: 3 | ||
|
|
||
| $ flexmeasures add schedule for-storage \ | ||
| --sensor 2 \ | ||
| --inflexible-device-sensor 3 \ | ||
| --start ${TOMORROW}T07:00+01:00 \ | ||
| --duration PT12H \ | ||
| --soc-at-start 50% \ | ||
| --roundtrip-efficiency 90% | ||
| New schedule is stored. | ||
|
|
||
| .. tab:: API | ||
|
|
||
| Example call: `[POST] http://localhost:5000/api/v3_0/assets/2/schedules/trigger <../api/v3_0.html#post--api-v3_0-assets-(id)-schedules-trigger>`_ (update the start date to tomorrow): | ||
|
|
||
| .. code-block:: json | ||
| :emphasize-lines: 11-13 | ||
|
|
||
| { | ||
| "start": "2025-06-11T07:00+01:00", | ||
| "duration": "PT12H", | ||
| "flex-model": [ | ||
| { | ||
| "sensor": 2, | ||
| "soc-at-start": "50%", | ||
| "roundtrip-efficiency": "90%" | ||
| } | ||
| ], | ||
| "flex-context": { | ||
| "inflexible-device-sensors": [3] | ||
| } | ||
| } | ||
|
|
||
| Alternatively, if the solar production is curtailable, move the solar production to the flex-model. | ||
| There, we tell the scheduler to pick any production value between 0 and the production forecast recorded on sensor 3, and to store the resulting schedule on sensor 3 as well (the FlexMeasures UI will still be able to distinguish forecasts from schedules): | ||
|
|
||
| .. code-block:: json | ||
| :emphasize-lines: 10-14,16 | ||
|
|
||
| { | ||
| "start": "2025-06-11T07:00+01:00", | ||
| "duration": "PT12H", | ||
| "flex-model": [ | ||
| { | ||
| "sensor": 2, | ||
| "soc-at-start": "50%", | ||
| "roundtrip-efficiency": "90%" | ||
| }, | ||
| { | ||
| "sensor": 3, | ||
| "consumption-capacity": "0 kW", | ||
| "production-capacity": {"sensor": 3}, | ||
| } | ||
| ], | ||
| "flex-context": {} | ||
| } | ||
|
|
||
| .. tab:: FlexMeasures Client | ||
|
|
||
| Using the `FlexMeasures Client <https://pypi.org/project/flexmeasures-client/>`_: | ||
|
|
||
| .. code-block:: bash | ||
|
|
||
| pip install flexmeasures-client | ||
|
|
||
| .. code-block:: python | ||
| :emphasize-lines: 22-24 | ||
|
|
||
| import asyncio | ||
| from datetime import date | ||
| from flexmeasures_client import FlexMeasuresClient as Client | ||
|
|
||
| async def client_script(): | ||
| client = Client( | ||
| email="[email protected]", | ||
| password="toy-password", | ||
| host="localhost:5000", | ||
| ) | ||
| schedule = await client.trigger_and_get_schedule( | ||
| asset_id=2, # Toy building (asset ID) | ||
| start=f"{date.today().isoformat()}T07:00+01:00", | ||
| duration="PT12H", | ||
| flex_model=[ | ||
| { | ||
| "sensor": 2, # battery power (sensor ID) | ||
| "soc-at-start": "50%", | ||
| "roundtrip-efficiency": "90%", | ||
| }, | ||
| ], | ||
| flex_context={ | ||
| "inflexible-device-sensors": [3], # solar production (sensor ID) | ||
| }, | ||
| ) | ||
| print(schedule) | ||
| await client.close() | ||
|
|
||
| asyncio.run(client_script()) | ||
|
|
||
| Alternatively, if the solar production is curtailable, move the solar production to the flex-model: | ||
|
|
||
| .. code-block:: python | ||
| :emphasize-lines: 11-15,17 | ||
|
|
||
| schedule = await client.trigger_and_get_schedule( | ||
| asset_id=2, # Toy building (asset ID) | ||
| start=f"{date.today().isoformat()}T07:00+01:00", | ||
| duration="PT12H", | ||
| flex_model=[ | ||
| { | ||
| "sensor": 2, # battery power (sensor ID) | ||
| "soc-at-start": "50%", | ||
| "roundtrip-efficiency": "90%", | ||
| }, | ||
| { | ||
| "sensor": 3, # solar production (sensor ID) | ||
| "consumption-capacity": "0 kW", | ||
| "production-capacity": {"sensor": 3}, | ||
| }, | ||
| ], | ||
| flex_context={}, | ||
| ) | ||
|
|
||
|
|
||
|
|
||
| We can see the updated scheduling in the `FlexMeasures UI <http://localhost:5000/sensors/2>`_: | ||
|
|
||
| .. image:: https://github.com/FlexMeasures/screenshots/raw/main/tut/toy-schedule/sensor-data-charging-with-solar.png | ||
| :align: center | ||
|
|
@@ -117,7 +239,7 @@ In the case of the scheduler that we ran in the previous tutorial, which did not | |
|
|
||
| .. note:: You can add arbitrary sensors to a chart using the asset UI or the attribute ``sensors_to_show``. See :ref:`view_asset-data` for more. | ||
|
|
||
| A nice feature is that you can check the data connectivity status of your building asset. Now that we have made the schedule, both lamps are green. You can also view it in `FlexMeasures UI <http://localhost:5000/assets/2/status>`_ : | ||
| A nice feature is that you can check the data connectivity status of your building asset. Now that we have made the schedule, both lamps are green. You can also view it in `FlexMeasures UI <http://localhost:5000/assets/2/status>`_: | ||
|
|
||
| .. image:: https://github.com/FlexMeasures/screenshots/raw/main/tut/toy-schedule/screenshot_building_status.png | ||
| :align: center | ||
|
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.