Skip to content

Commit

Permalink
Update toy tutorial (#1025)
Browse files Browse the repository at this point in the history
* add all assets to building asset in toy tutorial + add status page screenshot

Signed-off-by: Nikolai Rozanov <nickolay.rozanov@gmail.com>

* add child assets to show asset call

Signed-off-by: Nikolai Rozanov <nickolay.rozanov@gmail.com>

* Update child assets data on show asset call

Signed-off-by: Nikolai Rozanov <nickolay.rozanov@gmail.com>

---------

Signed-off-by: Nikolai Rozanov <nickolay.rozanov@gmail.com>
  • Loading branch information
nrozanov committed Apr 2, 2024
1 parent 94f3321 commit 7382672
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 14 deletions.
6 changes: 6 additions & 0 deletions documentation/tut/toy-example-expanded.rst
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@ 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 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/1/status>`_ :

.. image:: https://github.com/FlexMeasures/screenshots/raw/main/tut/toy-schedule/screenshot_building_status.png
:align: center
|
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 a quick way to add an inflexible load (like solar power) and a grid connection.
Expand Down
38 changes: 33 additions & 5 deletions documentation/tut/toy-example-setup.rst
Original file line number Diff line number Diff line change
Expand Up @@ -173,34 +173,62 @@ If you want, you can inspect what you created:
All assets:
ID Name Type Location
ID Name Type Location
---- ----------- ------- -----------------
2 toy-battery battery (52.374, 4.88969)
3 toy-solar solar (52.374, 4.88969)
2 toy-building building (52.374, 4.88969)
3 toy-battery battery (52.374, 4.88969)
4 toy-solar solar (52.374, 4.88969)
.. code-block:: bash
$ flexmeasures show asset --id 2
=========================
Asset toy-battery (ID: 2)
Asset toy-building (ID: 2)
=========================
Type Location Attributes
------- ----------------- ----------------------------
building (52.374, 4.88969)
====================================
Child assets of toy-building (ID: 2)
====================================
Id Name Type
------- ----------------- ----------------------------
3 toy-battery battery
4 toy-solar solar
No sensors in asset ...
$ flexmeasures show asset --id 3
==================================
Asset toy-battery (ID: 3)
Child of asset toy-building (ID: 2)
==================================
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: [1, [3, 2]]
====================================
Child assets of toy-battery (ID: 3)
====================================
No children assets ...
All sensors in asset:
ID Name Unit Resolution Timezone Attributes
---- ----------- ------ ------------ ---------------- ------------
2 discharging MW 15 minutes Europe/Amsterdam
Yes, that is quite a large battery :)
.. note:: Obviously, you can use the ``flexmeasures`` command to create your own, custom account and assets. See :ref:`cli`. And to create, edit or read asset data via the API, see :ref:`v3_0`.
Expand Down
28 changes: 21 additions & 7 deletions flexmeasures/cli/data_add.py
Original file line number Diff line number Diff line change
Expand Up @@ -2005,15 +2005,21 @@ def create_asset_with_one_sensor(
asset_type: str,
sensor_name: str,
unit: str = "MW",
parent_asset_id: int | None = None,
**asset_attributes,
):
asset_kwargs = dict()
if parent_asset_id is not None:
asset_kwargs["parent_asset_id"] = parent_asset_id

asset = get_or_create_model(
GenericAsset,
name=asset_name,
generic_asset_type=asset_types[asset_type],
owner=db.session.get(Account, account_id),
latitude=location[0],
longitude=location[1],
**asset_kwargs,
)
if len(asset_attributes) > 0:
asset.attributes = asset_attributes
Expand All @@ -2031,22 +2037,32 @@ def create_asset_with_one_sensor(
)
return sensor

# create building asset
building_asset = get_or_create_model(
GenericAsset,
name="toy-building",
generic_asset_type=asset_types["building"],
owner=db.session.get(Account, account_id),
latitude=location[0],
longitude=location[1],
)
db.session.flush()

if kind == "battery":
# create battery
discharging_sensor = create_asset_with_one_sensor(
"toy-battery",
"battery",
"discharging",
parent_asset_id=building_asset.id,
capacity_in_mw=0.5,
min_soc_in_mwh=0.05,
max_soc_in_mwh=0.45,
)

# create solar
production_sensor = create_asset_with_one_sensor(
"toy-solar",
"solar",
"production",
"toy-solar", "solar", "production", parent_asset_id=building_asset.id
)

# add day-ahead price sensor and PV production sensor to show on the battery's asset page
Expand Down Expand Up @@ -2118,7 +2134,7 @@ def create_asset_with_one_sensor(
grid_connection_capacity = get_or_create_model(
Sensor,
name="grid connection capacity",
generic_asset=nl_zone,
generic_asset=building_asset,
timezone="Europe/Amsterdam",
event_resolution="P1Y",
unit="MW",
Expand Down Expand Up @@ -2146,9 +2162,7 @@ def create_asset_with_one_sensor(
db.session.commit()

headroom = create_asset_with_one_sensor(
"toy-battery",
"battery",
"headroom",
"toy-battery", "battery", "headroom", parent_asset_id=building_asset.id
)

db.session.commit()
Expand Down
26 changes: 24 additions & 2 deletions flexmeasures/cli/data_show.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,14 @@ def show_generic_asset(asset):
"""
Show asset info and list sensors
"""
click.echo(f"======{len(asset.name) * '='}========")
separator_num = 18 if asset.parent_asset is not None else 8
click.echo(f"======{len(asset.name) * '='}{separator_num * '='}")
click.echo(f"Asset {asset.name} (ID: {asset.id})")
click.echo(f"======{len(asset.name) * '='}========\n")
if asset.parent_asset is not None:
click.echo(
f"Child of asset {asset.parent_asset.name} (ID: {asset.parent_asset.id})"
)
click.echo(f"======{len(asset.name) * '='}{separator_num * '='}\n")

asset_data = [
(
Expand All @@ -201,6 +206,23 @@ def show_generic_asset(asset):
]
click.echo(tabulate(asset_data, headers=["Type", "Location", "Attributes"]))

child_asset_data = [
(
child.id,
child.name,
child.generic_asset_type.name,
)
for child in asset.child_assets
]
click.echo()
click.echo(f"======{len(asset.name) * '='}===================")
click.echo(f"Child assets of {asset.name} (ID: {asset.id})")
click.echo(f"======{len(asset.name) * '='}===================\n")
if child_asset_data:
click.echo(tabulate(child_asset_data, headers=["Id", "Name", "Type"]))
else:
click.secho("No children assets ...", **MsgStyle.WARN)

click.echo()
sensors = db.session.scalars(
select(Sensor).filter_by(generic_asset_id=asset.id).order_by(Sensor.name)
Expand Down

0 comments on commit 7382672

Please sign in to comment.