diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 61ae5803..a76f8b24 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -37,13 +37,13 @@ jobs: # Only use hashes here, as we are passing the github token, we want to # make sure updates are done consciously to avoid security issues if the # action repo gets hacked - uses: yoheimuta/action-protolint@a7c658b971a0874e120e046edb6fd137fdbc92a7 # v1.1.0 + uses: yoheimuta/action-protolint@e62319541dc5107df5e3a5010acb8987004d3d25 # v1.3.0 with: fail_on_error: true filter_mode: nofilter github_token: ${{ secrets.github_token }} protolint_flags: proto/ - protolint_version: "0.45.0" + protolint_version: "0.50.5" reporter: github-check nox: diff --git a/.github/workflows/release-notes-check.yml b/.github/workflows/release-notes-check.yml index 31cfa7a7..82882db0 100644 --- a/.github/workflows/release-notes-check.yml +++ b/.github/workflows/release-notes-check.yml @@ -20,7 +20,7 @@ jobs: steps: - name: Check for a release notes update if: github.event_name == 'pull_request' - uses: brettcannon/check-for-changed-files@4170644959a21843b31f1181f2a1761d65ef4791 # v1.2.0 + uses: brettcannon/check-for-changed-files@871d7b8b5917a4f6f06662e2262e8ffc51dff6d1 # v1.2.1 with: file-pattern: "RELEASE_NOTES.md" prereq-pattern: "{proto,py}/**" diff --git a/MANIFEST.in b/MANIFEST.in index c15e5b3d..9dc76cd5 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -6,7 +6,7 @@ exclude CODEOWNERS exclude CONTRIBUTING.md exclude mkdocs.yml exclude noxfile.py -exclude src/conftest.py +exclude py/frequenz/api/common/conftest.py recursive-exclude .github * recursive-exclude benchmarks * recursive-exclude docs * diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index a1e366fc..8545ca6c 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -4,6 +4,23 @@ - Added message linking microgrid and sensor IDs. +- Update of the `PaginationParams` struct. + +## Upgrading + +- `PaginationParams` has been changed so that the `page_size` and `page_token` + fields are now mutually exclusive. + +- A new component category `COMPONENT_CATEGORY_HVAC` has been added to the API + to represent HVAC (Heating, Ventilation, and Air Conditioning) systems. + +- Additional information for energy metric + +- Generalize Energy message documentation for broader market use + +- Add Power message to represent Power in MW + ## Bug Fixes - Fix a dependency issue by pinning the `grpcio` version and related libraries. +- Fixed a wrong documentation comment for `COMPONENT_CATEGORY_UNSPECIFIED`. diff --git a/proto/frequenz/api/common/v1/market/energy.proto b/proto/frequenz/api/common/v1/market/energy.proto index 1dfe9564..9157f1e6 100644 --- a/proto/frequenz/api/common/v1/market/energy.proto +++ b/proto/frequenz/api/common/v1/market/energy.proto @@ -1,4 +1,4 @@ -// Frequenz definitions of energy for electricity trading. +// Frequenz definitions of energy. // // Copyright 2023 Frequenz Energy-as-a-Service GmbH // @@ -14,11 +14,11 @@ import "frequenz/api/common/v1/types/decimal.proto"; // Represents a single unit of electricity. // // !!! note -// In these trading orders, the unit of energy is denominated in MWh -// (Megawatt-hours) as opposed to MW (Megawatts). MWh is a unit of energy -// representing total output over a period, while MW is a unit of power that -// represents the rate of energy production or consumption. +// The unit of energy is denominated in MWh, which is a unit of energy +// representing total output over a period.(Megawatt-hours). This differs +// from MW (Megawatts), a unit of power representing the rate of energy +// production or consumption. message Energy { - // Represents energy unit in Megawatthours (MWh). + // Energy unit in Megawatthours (MWh). frequenz.api.common.v1.types.Decimal mwh = 1; } diff --git a/proto/frequenz/api/common/v1/market/power.proto b/proto/frequenz/api/common/v1/market/power.proto new file mode 100644 index 00000000..a77308e7 --- /dev/null +++ b/proto/frequenz/api/common/v1/market/power.proto @@ -0,0 +1,30 @@ +// Frequenz definitions of power. +// +// Copyright 2024 Frequenz Energy-as-a-Service GmbH +// +// Licensed under the MIT License (the "License"); +// you may not use this file except in compliance with the License. + +syntax = "proto3"; + +package frequenz.api.common.v1.market; + +import "frequenz/api/common/v1/types/decimal.proto"; + +// Represents a single unit of power. +// +// !!! note +// The power unit is denominated in MW (Megawatts), which is a unit of +// power representing the rate of energy production or consumption at any +// given moment. This differs from MWh (Megawatt-hours), which measures +// the total amount of energy delivered or consumed over a period. +// +// Example: +// A power plant running at 10 MW for 1 hour generates 10 MWh of energy. +// +// This message standardizes the representation of power in MW across all +// market applications. +message Power { + // Power amount in Megawatts (MW). + frequenz.api.common.v1.types.Decimal mw = 1; +} diff --git a/proto/frequenz/api/common/v1/metrics/metric_sample.proto b/proto/frequenz/api/common/v1/metrics/metric_sample.proto index af37d611..dd9bc533 100644 --- a/proto/frequenz/api/common/v1/metrics/metric_sample.proto +++ b/proto/frequenz/api/common/v1/metrics/metric_sample.proto @@ -63,6 +63,20 @@ message MetricValueVariant { } // List of supported metrics. +// +// !!! note +// AC energy metrics information: +// +// * This energy metric is reported directly from the component, and not a +// result of aggregations in our systems. If a component does not have this +// metric, this field cannot be populated. +// +// * Components that provide energy metrics reset this metric from time to +// time. This behaviour is specific to each component model. E.g., some +// components reset it on UTC 00:00:00. +// +// * This energy metric does not specify the timestamp since when the energy +// was being accumulated, and therefore can be inconsistent. enum Metric { // Default value. METRIC_UNSPECIFIED = 0; diff --git a/proto/frequenz/api/common/v1/microgrid/components/components.proto b/proto/frequenz/api/common/v1/microgrid/components/components.proto index c21251d1..8b9520ff 100644 --- a/proto/frequenz/api/common/v1/microgrid/components/components.proto +++ b/proto/frequenz/api/common/v1/microgrid/components/components.proto @@ -24,8 +24,7 @@ import "google/protobuf/timestamp.proto"; // Enumrated component categories. enum ComponentCategory { - // An unknown component categories, useful for error handling, and marking - // unknown components in a list of components with otherwise known categories. + // The component category is unspecified. This should not be used. COMPONENT_CATEGORY_UNSPECIFIED = 0; // The point where the local microgrid is connected to the grid. diff --git a/proto/frequenz/api/common/v1/microgrid/lifetime.proto b/proto/frequenz/api/common/v1/microgrid/lifetime.proto index 8fb32123..82d62193 100644 --- a/proto/frequenz/api/common/v1/microgrid/lifetime.proto +++ b/proto/frequenz/api/common/v1/microgrid/lifetime.proto @@ -15,14 +15,27 @@ import "google/protobuf/timestamp.proto"; // a microgrid asset, such as a component, connection, sensor, or any other // entity with a limited operational lifetime. // -// !!! warning "Permanent Deletion" -// The `end_timestamp` indicates that the asset has been permanently removed -// from the system. +// It is normally used to track the historical evolution of assets, and it +// determines the validity period for the asset's data. // +// If the `start_timestamp` is not set, the asset is considered to be in +// operation since the beginning of the system's operational history. +// +// If the `end_timestamp` is not set, the asset is considered to be in +// operation indefinitely into the future. +// +// If the Lifetime message is completely missing, it means both timestamps are +// not set, which means the asset is considered to be in operation since the +// beginning of the system's operational history and indefinitely into the +// future. message Lifetime { // The timestamp when the asset became operationally active. + // If not set, the asset is considered to be in operation since the beginning + // of the system's operational history. google.protobuf.Timestamp start_timestamp = 1; // Optional timestamp when the asset's operational activity ceased. + // If not set, the asset is considered to be in operation indefinitely into + // the future. google.protobuf.Timestamp end_timestamp = 2; } diff --git a/proto/frequenz/api/common/v1/microgrid/microgrid.proto b/proto/frequenz/api/common/v1/microgrid/microgrid.proto index 743b8a5d..419a1f02 100644 --- a/proto/frequenz/api/common/v1/microgrid/microgrid.proto +++ b/proto/frequenz/api/common/v1/microgrid/microgrid.proto @@ -51,9 +51,15 @@ message Microgrid { // The delivery area where the microgrid is located, as identified by a // specific code. + // + // If a microgrid is not connected to the grid (it is an island) it does not + // belong to any delivery area and this field will be missing, but it could + // be missing for other reasons as well. frequenz.api.common.v1.grid.DeliveryArea delivery_area = 4; // Physical location of the microgrid, in geographical co-ordinates. + // + // If the location is not known, this field will be missing. frequenz.api.common.v1.Location location = 5; // The current status of the microgrid. diff --git a/proto/frequenz/api/common/v1/pagination/pagination_params.proto b/proto/frequenz/api/common/v1/pagination/pagination_params.proto index a21bffa7..8129236e 100644 --- a/proto/frequenz/api/common/v1/pagination/pagination_params.proto +++ b/proto/frequenz/api/common/v1/pagination/pagination_params.proto @@ -11,16 +11,21 @@ package frequenz.api.common.v1.pagination; // A message defining parameters for paginating list requests. // It can be appended to a request message to specify the desired page of -// results and the maximum number of results per page. For initial requests -// (requesting the first page), the page_token should not be provided. For -// subsequent requests (requesting any page after the first), the -// next_page_token from the previous responses PaginationInfo must be supplied. -// The page_size should only be specified in the initial request and will be -// disregarded in subsequent requests. +// results and the maximum number of results per page. message PaginationParams { - // The maximum number of results to be returned per request. - optional uint32 page_size = 1; + oneof params { + // The maximum number of results to return in a single page. The service may + // return fewer results than requested. If unspecified, the service may + // choose a reasonable default. + // May only be specified in the first request. + uint32 page_size = 1; - // The token identifying a specific page of the list results. - optional string page_token = 2; + // A token identifying a page of results to return. This should be the value + // of the `next_page_token` field in the previous response's PaginationInfo. + // For the first request, this field should be omitted. + // + // To avoid keeping remembering the page_size across requests, service + // implementations may choose to encode the page_size in the page_token. + string page_token = 2; + } } diff --git a/py/conftest.py b/py/frequenz/api/common/conftest.py similarity index 100% rename from py/conftest.py rename to py/frequenz/api/common/conftest.py diff --git a/pyproject.toml b/pyproject.toml index 1c7e1154..ec8f5079 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,9 +10,9 @@ requires = [ # sure the code is generated using the minimum supported versions, as older # versions can't work with code that was generated with newer versions. # https://protobuf.dev/support/cross-version-runtime-guarantee/#backwards - "protobuf == 4.25.3", - "grpcio-tools == 1.51.1", - "grpcio == 1.51.1", + "protobuf == 5.28.0", + "grpcio-tools == 1.66.1", + "grpcio == 1.66.1", ] build-backend = "setuptools.build_meta" @@ -33,13 +33,14 @@ classifiers = [ ] requires-python = ">= 3.11, < 4" dependencies = [ - # We can't widen beyond 6 because of protobuf cross-version runtime guarantees + # We can't widen beyond the current value unless we bump the minimum + # requirements too because of protobuf cross-version runtime guarantees: # https://protobuf.dev/support/cross-version-runtime-guarantee/#major - "protobuf >= 4.25.3, < 6", # Do not widen beyond 6! + "protobuf >= 5.28.0, < 7", # Do not widen beyond 7! # We couldn't find any document with a spec about the cross-version runtime # guarantee for grpcio, so unless we find one in the future, we'll assume # major version jumps are not compatible - "grpcio >= 1.51.1, < 2", # Do not widen beyond 2! + "grpcio >= 1.66.1, < 2", # Do not widen beyond 2! ] dynamic = ["version"] @@ -49,30 +50,30 @@ email = "floss@frequenz.com" [project.optional-dependencies] dev-flake8 = [ - "flake8 == 7.0.0", + "flake8 == 7.1.1", "flake8-docstrings == 1.7.0", "flake8-pyproject == 1.2.3", # For reading the flake8 config from pyproject.toml - "pydoclint == 0.4.1", + "pydoclint == 0.5.9", "pydocstyle == 6.3.0", ] -dev-formatting = ["black == 24.4.2", "isort == 5.13.2"] +dev-formatting = ["black == 24.8.0", "isort == 5.13.2"] dev-mkdocs = [ "mike == 1.1.2", "mkdocs-gen-files == 0.5.0", "mkdocs-literate-nav == 0.6.1", - "mkdocs-material == 9.5.21", - "mkdocstrings[python] == 0.25.1", + "mkdocs-material == 9.5.39", + "mkdocstrings[python] == 0.26.1", "frequenz-repo-config[api] == 0.11.0", ] dev-mypy = [ - "mypy == 1.10.0", + "mypy == 1.11.2", "grpc-stubs == 1.53.0.5", # For checking the noxfile, docs/ script, and tests "frequenz-api-common[dev-mkdocs,dev-noxfile,dev-pytest]", ] dev-noxfile = ["nox == 2024.4.15", "frequenz-repo-config[api] == 0.11.0"] dev-pylint = [ - "pylint == 3.1.0", + "pylint == 3.3.1", # For checking the noxfile, docs/ script, and tests "frequenz-api-common[dev-mkdocs,dev-noxfile,dev-pytest]", ]