Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions documentation/api/change_log.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ API change log
.. note:: The FlexMeasures API follows its own versioning scheme. This is also reflected in the URL (e.g. `/api/v3_0`), allowing developers to upgrade at their own pace.


v3.0-26 | 2025-09-02
""""""""""""""""""""
- Added endpoint `GET /assets/types`.


v3.0-25 | 2025-07-24
""""""""""""""""""""
- Removed /play blueprint with endpoint `PUT /restoreData`.
Expand Down
2 changes: 2 additions & 0 deletions documentation/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ v0.28.0 | September XX, 2025

New features
-------------

* Display KPIs for asset sensors with daily event resolution [see `PR #1608 <https://github.com/FlexMeasures/flexmeasures/pull/1608>`_, `PR #1634 <https://github.com/FlexMeasures/flexmeasures/pull/1634>`_ and `PR #1656 <https://github.com/FlexMeasures/flexmeasures/pull/1656>`_]
* Improved timestamp on sensor detail page to be more friendly [see `PR #1632 <https://www.github.com/FlexMeasures/flexmeasures/pull/1632>`_]
* Asset types support: new API endpoint (`GET /assets/types`), better docs and fix CLI command `flexmeasures show asset-types` [see `PR #1663 <https://github.com/FlexMeasures/flexmeasures/pull/1663>`_]

Infrastructure / Support
----------------------
Expand Down
9 changes: 8 additions & 1 deletion documentation/concepts/data-model.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,14 @@ Here is an example of an asset with sub-assets:
D <--> H[Battery]
D <--> I["Charge<br>Point"]

We model asset types explicitly. None are required for running FlexMeasures. Some asset types have support in the UI (for icons, like a sun for ``"solar"``), and in the toy tutorial and test. Some are used to select the scheduler (e.g. using ``"battery"`` or ``"one-way_evse"`` leads to using the storage scheduler). You can add your own types, which is useful for plugin logic (an example is the ``"weather station"`` type for a plugin that reads in weather forecasts).
We model asset types explicitly. None are required for running FlexMeasures.
Some asset types have support in the UI (for icons, like a sun for ``"solar"``), and in the toy tutorial and test.

Some are used to select the scheduler (e.g. using ``"battery"`` or ``"one-way_evse"`` leads to using the storage scheduler).
However, in practice (for now), we default to storage scheduling for everything not typed "process" or "load" (as those would use the process scheduler).

You can add default types (and other useful things like data sources and user roles) by running ``flexmeasures add initial-structure``.
You can add your own types, which is useful for plugin logic (an example is the ``"weather station"`` type for a plugin that reads in weather forecasts). The CLI command for this is ``flexmeasures add asset-type``.

Sensors
---------
Expand Down
15 changes: 15 additions & 0 deletions documentation/dev/setup-and-guidelines.rst
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,21 @@ Otherwise, you need to add some other user first. Here is how we add an admin:
We recommend to use the Windows Sub-system for Linux (https://learn.microsoft.com/en-us/windows/wsl/install) or work via Docker-compose (https://flexmeasures.readthedocs.io/en/latest/dev/docker-compose.html).


We recommend you populate the database with some standard asset types, user roles, data sources etc.:

.. code-block:: bash

$ flexmeasures add initial-structure

For instance, without an asset type, you cannot add an asset.

Actually, you can add many things from the terminal. Check what data you can add yourself:

.. code-block:: bash

$ flexmeasures add --help



Logfile
--------
Expand Down
17 changes: 10 additions & 7 deletions documentation/host/data.rst
Original file line number Diff line number Diff line change
Expand Up @@ -253,23 +253,26 @@ First, you can get the database structure with:

.. note:: If you develop code (and might want to make changes to the data model), you should also check out the maintenance section about database migrations.

You can create users with the ``add user`` command. Check it out:

You should create some pre-determined asset types, user/account roles and data sources with this command:

.. code-block:: bash

$ flexmeasures add account --help
$ flexmeasures add user --help
$ flexmeasures add initial-structure


You can create some pre-determined asset types and data sources with this command:
Another good first step is to create an account for yourself, plus a user to log in with:

.. code-block:: bash

$ flexmeasures add initial-structure
$ flexmeasures add account --help
$ flexmeasures add user --help

Creating accounts and users for your clients would also happen this way (soon also in the UI).

You can also create assets in the FlexMeasures UI.
You can also create assets in the CLI (``flexmeasures add asset``), but that is also possible in the FlexMeasures UI.

On the command line, you can add many things. Check what data you can add yourself:
Actually, you can add many things from the terminal. Check what data you can add yourself:

.. code-block:: bash

Expand Down
2 changes: 1 addition & 1 deletion documentation/host/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ FlexMeasures is also a web-based platform, so we need to create a user to authen
Add initial structure
^^^^^^^^^^^^^^^^^^^^^^^

Populate the database with some standard asset types, user roles etc.:
Populate the database with some standard asset types, user roles, data sources etc.:

.. code-block:: bash

Expand Down
3 changes: 2 additions & 1 deletion flexmeasures/api/v3_0/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from flexmeasures.api.v3_0.sensors import SensorAPI
from flexmeasures.api.v3_0.accounts import AccountAPI
from flexmeasures.api.v3_0.users import UserAPI
from flexmeasures.api.v3_0.assets import AssetAPI
from flexmeasures.api.v3_0.assets import AssetAPI, AssetTypesAPI
from flexmeasures.api.v3_0.health import HealthAPI
from flexmeasures.api.v3_0.public import ServicesAPI

Expand All @@ -21,5 +21,6 @@ def register_at(app: Flask):
AccountAPI.register(app, route_prefix=v3_0_api_prefix)
UserAPI.register(app, route_prefix=v3_0_api_prefix)
AssetAPI.register(app, route_prefix=v3_0_api_prefix)
AssetTypesAPI.register(app, route_prefix=v3_0_api_prefix)
HealthAPI.register(app, route_prefix=v3_0_api_prefix)
ServicesAPI.register(app)
40 changes: 39 additions & 1 deletion flexmeasures/api/v3_0/assets.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@
from flexmeasures.data import db
from flexmeasures.data.models.user import Account
from flexmeasures.data.models.audit_log import AssetAuditLog
from flexmeasures.data.models.generic_assets import GenericAsset
from flexmeasures.data.models.generic_assets import GenericAsset, GenericAssetType
from flexmeasures.data.queries.generic_assets import query_assets_by_search_terms
from flexmeasures.data.schemas import AwareDateTimeField
from flexmeasures.data.schemas.generic_assets import (
GenericAssetSchema as AssetSchema,
GenericAssetIdField as AssetIdField,
GenericAssetTypeSchema as AssetTypeSchema,
)
from flexmeasures.data.schemas.scheduling import AssetTriggerSchema
from flexmeasures.data.services.scheduling import (
Expand All @@ -56,6 +57,7 @@
from flexmeasures.utils.time_utils import naturalized_datetime_str
from flexmeasures.data.utils import get_downsample_function_and_value

asset_type_schema = AssetTypeSchema()
asset_schema = AssetSchema()
assets_schema = AssetSchema(many=True)
sensor_schema = SensorSchema()
Expand All @@ -75,6 +77,42 @@ def get_accessible_accounts() -> list[Account]:
return accounts


class AssetTypesAPI(FlaskView):
"""
This API view exposes generic asset types.
"""

route_base = "/assets/types"
trailing_slash = False
decorators = [auth_required()]

@route("", methods=["GET"])
@as_json
def index(self):
"""List all asset types available on this platform.

.. :quickref: Asset; Get list of available asset types

**Example response**

An example of one asset type being returned in the response:

.. sourcecode:: json

[
{
"id": 1,
"name": "solar",
"description": "solar panel(s)",
}
]
"""
response = asset_type_schema.dump(
db.session.scalars(select(GenericAssetType)).all(), many=True
)
return response, 200


class AssetAPI(FlaskView):
"""
This API view exposes generic assets.
Expand Down
4 changes: 2 additions & 2 deletions flexmeasures/api/v3_0/health.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ def is_ready(self):
.. sourcecode:: json

{
'database_sql': True,
'database_redis': False
"database_sql": True,
"database_redis": False
}

"""
Expand Down
16 changes: 16 additions & 0 deletions flexmeasures/api/v3_0/tests/test_assets_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,22 @@
from flexmeasures.utils.unit_utils import is_valid_unit


@pytest.mark.parametrize(
"requesting_user", ["test_prosumer_user@seita.nl"], indirect=True
)
def test_get_asset_types(
client, setup_api_test_data, setup_roles_users, requesting_user
):
get_asset_types_response = client.get(url_for("AssetTypesAPI:index"))
print("Server responded with:\n%s" % get_asset_types_response.json)
assert get_asset_types_response.status_code == 200
assert isinstance(get_asset_types_response.json, list)
assert len(get_asset_types_response.json) > 0
assert isinstance(get_asset_types_response.json[0], dict)
for key in ("id", "name", "description"):
assert key in get_asset_types_response.json[0].keys()


@pytest.mark.parametrize(
"requesting_user, status_code",
[
Expand Down
10 changes: 5 additions & 5 deletions flexmeasures/data/scripts/data_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@ def add_default_data_sources(db: SQLAlchemy):
("Seita", "forecaster"),
("Seita", "scheduler"),
):
source = db.session.execute(
sources = db.session.execute(
select(DataSource).filter(
and_(DataSource.name == source_name, DataSource.type == source_type)
)
).scalar_one_or_none()
if source:
click.echo(f"Source {source_name} ({source_type}) already exists.")
).scalar()
if sources:
click.echo(f"A source {source_name} ({source_type}) already exists.")
else:
db.session.add(DataSource(name=source_name, type=source_type))

Expand Down Expand Up @@ -101,7 +101,7 @@ def add_default_user_roles(db: SQLAlchemy):
select(Role).filter_by(name=role_name)
).scalar_one_or_none()
if role:
click.echo(f"Role {role_name} already exists.")
click.echo(f"User role {role_name} already exists.")
else:
db.session.add(Role(name=role_name, description=role_description))

Expand Down