frequenz-client-common 0.3.6__tar.gz → 0.3.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {frequenz_client_common-0.3.6/src/frequenz_client_common.egg-info → frequenz_client_common-0.3.7}/PKG-INFO +23 -20
- frequenz_client_common-0.3.7/RELEASE_NOTES.md +22 -0
- {frequenz_client_common-0.3.6 → frequenz_client_common-0.3.7}/pyproject.toml +22 -19
- frequenz_client_common-0.3.7/src/frequenz/client/common/enum_proto.py +82 -0
- {frequenz_client_common-0.3.6 → frequenz_client_common-0.3.7}/src/frequenz/client/common/metric/__init__.py +4 -1
- frequenz_client_common-0.3.7/src/frequenz/client/common/metrics/__init__.py +24 -0
- frequenz_client_common-0.3.7/src/frequenz/client/common/metrics/_bounds.py +45 -0
- frequenz_client_common-0.3.7/src/frequenz/client/common/metrics/_metric.py +278 -0
- frequenz_client_common-0.3.7/src/frequenz/client/common/metrics/_sample.py +233 -0
- frequenz_client_common-0.3.7/src/frequenz/client/common/metrics/proto/__init__.py +19 -0
- frequenz_client_common-0.3.7/src/frequenz/client/common/metrics/proto/_bounds.py +50 -0
- frequenz_client_common-0.3.7/src/frequenz/client/common/metrics/proto/_sample.py +150 -0
- {frequenz_client_common-0.3.6 → frequenz_client_common-0.3.7}/src/frequenz/client/common/microgrid/components/__init__.py +14 -3
- {frequenz_client_common-0.3.6 → frequenz_client_common-0.3.7}/src/frequenz/client/common/microgrid/electrical_components/__init__.py +15 -3
- {frequenz_client_common-0.3.6 → frequenz_client_common-0.3.7}/src/frequenz/client/common/pagination/__init__.py +5 -4
- frequenz_client_common-0.3.7/src/frequenz/client/common/proto/__init__.py +13 -0
- frequenz_client_common-0.3.7/src/frequenz/client/common/proto/_timestamp.py +69 -0
- {frequenz_client_common-0.3.6 → frequenz_client_common-0.3.7/src/frequenz_client_common.egg-info}/PKG-INFO +23 -20
- {frequenz_client_common-0.3.6 → frequenz_client_common-0.3.7}/src/frequenz_client_common.egg-info/SOURCES.txt +10 -0
- {frequenz_client_common-0.3.6 → frequenz_client_common-0.3.7}/src/frequenz_client_common.egg-info/requires.txt +22 -19
- frequenz_client_common-0.3.6/RELEASE_NOTES.md +0 -21
- {frequenz_client_common-0.3.6 → frequenz_client_common-0.3.7}/LICENSE +0 -0
- {frequenz_client_common-0.3.6 → frequenz_client_common-0.3.7}/MANIFEST.in +0 -0
- {frequenz_client_common-0.3.6 → frequenz_client_common-0.3.7}/README.md +0 -0
- {frequenz_client_common-0.3.6 → frequenz_client_common-0.3.7}/setup.cfg +0 -0
- {frequenz_client_common-0.3.6 → frequenz_client_common-0.3.7}/src/frequenz/client/common/__init__.py +0 -0
- {frequenz_client_common-0.3.6 → frequenz_client_common-0.3.7}/src/frequenz/client/common/conftest.py +0 -0
- {frequenz_client_common-0.3.6 → frequenz_client_common-0.3.7}/src/frequenz/client/common/microgrid/__init__.py +0 -0
- {frequenz_client_common-0.3.6 → frequenz_client_common-0.3.7}/src/frequenz/client/common/microgrid/sensors.py +0 -0
- /frequenz_client_common-0.3.6/src/frequenz/client/common/enum_proto.py → /frequenz_client_common-0.3.7/src/frequenz/client/common/proto/_enum.py +0 -0
- {frequenz_client_common-0.3.6 → frequenz_client_common-0.3.7}/src/frequenz/client/common/py.typed +0 -0
- {frequenz_client_common-0.3.6 → frequenz_client_common-0.3.7}/src/frequenz/client/common/streaming/__init__.py +0 -0
- {frequenz_client_common-0.3.6 → frequenz_client_common-0.3.7}/src/frequenz_client_common.egg-info/dependency_links.txt +0 -0
- {frequenz_client_common-0.3.6 → frequenz_client_common-0.3.7}/src/frequenz_client_common.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: frequenz-client-common
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.7
|
|
4
4
|
Summary: Common code and utilities for Frequenz API clients
|
|
5
5
|
Author-email: Frequenz Energy-as-a-Service GmbH <floss@frequenz.com>
|
|
6
6
|
License: MIT
|
|
@@ -23,41 +23,44 @@ License-File: LICENSE
|
|
|
23
23
|
Requires-Dist: typing-extensions<5,>=4.13.0
|
|
24
24
|
Requires-Dist: frequenz-api-common<1,>=0.8.0
|
|
25
25
|
Requires-Dist: frequenz-core<2,>=1.0.2
|
|
26
|
+
Requires-Dist: protobuf<7,>=6.33.1
|
|
26
27
|
Provides-Extra: dev-flake8
|
|
27
28
|
Requires-Dist: flake8==7.3.0; extra == "dev-flake8"
|
|
28
29
|
Requires-Dist: flake8-docstrings==1.7.0; extra == "dev-flake8"
|
|
29
30
|
Requires-Dist: flake8-pyproject==1.2.3; extra == "dev-flake8"
|
|
30
|
-
Requires-Dist: pydoclint==0.
|
|
31
|
+
Requires-Dist: pydoclint==0.7.6; extra == "dev-flake8"
|
|
31
32
|
Requires-Dist: pydocstyle==6.3.0; extra == "dev-flake8"
|
|
32
33
|
Provides-Extra: dev-formatting
|
|
33
|
-
Requires-Dist: black==25.
|
|
34
|
-
Requires-Dist: isort==6.0
|
|
34
|
+
Requires-Dist: black==25.9.0; extra == "dev-formatting"
|
|
35
|
+
Requires-Dist: isort==6.1.0; extra == "dev-formatting"
|
|
35
36
|
Provides-Extra: dev-mkdocs
|
|
36
|
-
Requires-Dist: Markdown==3.
|
|
37
|
-
Requires-Dist: black==25.
|
|
37
|
+
Requires-Dist: Markdown==3.9; extra == "dev-mkdocs"
|
|
38
|
+
Requires-Dist: black==25.9.0; extra == "dev-mkdocs"
|
|
38
39
|
Requires-Dist: mike==2.1.3; extra == "dev-mkdocs"
|
|
39
40
|
Requires-Dist: mkdocs-gen-files==0.5.0; extra == "dev-mkdocs"
|
|
40
41
|
Requires-Dist: mkdocs-literate-nav==0.6.2; extra == "dev-mkdocs"
|
|
41
|
-
Requires-Dist: mkdocs-macros-plugin==1.
|
|
42
|
-
Requires-Dist: mkdocs-material==9.6.
|
|
43
|
-
Requires-Dist: mkdocstrings[python]==0.30.
|
|
44
|
-
Requires-Dist: mkdocstrings-python==1.
|
|
45
|
-
Requires-Dist: frequenz-repo-config[lib]==0.13.
|
|
42
|
+
Requires-Dist: mkdocs-macros-plugin==1.4.0; extra == "dev-mkdocs"
|
|
43
|
+
Requires-Dist: mkdocs-material==9.6.21; extra == "dev-mkdocs"
|
|
44
|
+
Requires-Dist: mkdocstrings[python]==0.30.1; extra == "dev-mkdocs"
|
|
45
|
+
Requires-Dist: mkdocstrings-python==1.18.2; extra == "dev-mkdocs"
|
|
46
|
+
Requires-Dist: frequenz-repo-config[lib]==0.13.6; extra == "dev-mkdocs"
|
|
46
47
|
Provides-Extra: dev-mypy
|
|
47
|
-
Requires-Dist: mypy==1.
|
|
48
|
-
Requires-Dist: types-Markdown==3.
|
|
48
|
+
Requires-Dist: mypy==1.18.2; extra == "dev-mypy"
|
|
49
|
+
Requires-Dist: types-Markdown==3.9.0.20250906; extra == "dev-mypy"
|
|
50
|
+
Requires-Dist: types-protobuf==6.32.1.20251105; extra == "dev-mypy"
|
|
49
51
|
Requires-Dist: frequenz-client-common[dev-mkdocs,dev-noxfile,dev-pytest]; extra == "dev-mypy"
|
|
50
52
|
Provides-Extra: dev-noxfile
|
|
51
|
-
Requires-Dist: nox==2025.
|
|
52
|
-
Requires-Dist: frequenz-repo-config[lib]==0.13.
|
|
53
|
+
Requires-Dist: nox==2025.10.16; extra == "dev-noxfile"
|
|
54
|
+
Requires-Dist: frequenz-repo-config[lib]==0.13.6; extra == "dev-noxfile"
|
|
53
55
|
Provides-Extra: dev-pylint
|
|
54
|
-
Requires-Dist: pylint==
|
|
56
|
+
Requires-Dist: pylint==4.0.3; extra == "dev-pylint"
|
|
55
57
|
Requires-Dist: frequenz-client-common[dev-mkdocs,dev-noxfile,dev-pytest]; extra == "dev-pylint"
|
|
56
58
|
Provides-Extra: dev-pytest
|
|
57
|
-
Requires-Dist: pytest==8.4.
|
|
58
|
-
Requires-Dist: frequenz-repo-config[extra-lint-examples]==0.13.
|
|
59
|
-
Requires-Dist:
|
|
60
|
-
Requires-Dist: pytest-
|
|
59
|
+
Requires-Dist: pytest==8.4.2; extra == "dev-pytest"
|
|
60
|
+
Requires-Dist: frequenz-repo-config[extra-lint-examples]==0.13.6; extra == "dev-pytest"
|
|
61
|
+
Requires-Dist: hypothesis==6.140.3; extra == "dev-pytest"
|
|
62
|
+
Requires-Dist: pytest-mock==3.15.1; extra == "dev-pytest"
|
|
63
|
+
Requires-Dist: pytest-asyncio==1.2.0; extra == "dev-pytest"
|
|
61
64
|
Requires-Dist: async-solipsism==0.8; extra == "dev-pytest"
|
|
62
65
|
Provides-Extra: dev
|
|
63
66
|
Requires-Dist: frequenz-client-common[dev-flake8,dev-formatting,dev-mkdocs,dev-mypy,dev-noxfile,dev-pylint,dev-pytest]; extra == "dev"
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Frequenz Client Common Library Release Notes
|
|
2
|
+
|
|
3
|
+
## Summary
|
|
4
|
+
|
|
5
|
+
This release main change is the introduction of a new `metrics` package compatible with the common API v0.8 (`v1alpha8`) (the old `metric` package, in singular, still works with the old v0.5/`v1` version).
|
|
6
|
+
|
|
7
|
+
## Deprecations
|
|
8
|
+
|
|
9
|
+
- The old `frequenz.client.common.enum_proto` module is now deprecated, please use `frequenz.client.common.proto.enum_from_proto` instead.
|
|
10
|
+
|
|
11
|
+
## New Features
|
|
12
|
+
|
|
13
|
+
- New `frequenz.client.common.common.proto` module with conversion utilities for protobuf types:
|
|
14
|
+
- `enum_from_proto()` (moved from `enum_proto).
|
|
15
|
+
- `datetime_to_proto()` and `datetime_from_proto()` functions to convert between Python `datetime` and protobuf `Timestamp` (imported from `frequenz-client-base`.
|
|
16
|
+
- New `metrics` package compatible with API v0.8, which includes:
|
|
17
|
+
- `Metric` enum with all supported metrics.
|
|
18
|
+
- `MetricSample` dataclass to represent metric samples.
|
|
19
|
+
- `AggregatedMetricValue` dataclass to represent derived statistical summaries.
|
|
20
|
+
- `Bounds` dataclass to represent bounds for metrics.
|
|
21
|
+
- `MetricConnection` and `MetricConnectionCategory` to represent connections from which metrics are obtained.
|
|
22
|
+
- `proto` submodule with conversion functions to/from protobuf types.
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
[build-system]
|
|
5
5
|
requires = [
|
|
6
6
|
"setuptools == 80.9.0",
|
|
7
|
-
"setuptools_scm[toml] ==
|
|
8
|
-
"frequenz-repo-config[lib] == 0.13.
|
|
7
|
+
"setuptools_scm[toml] == 9.2.2",
|
|
8
|
+
"frequenz-repo-config[lib] == 0.13.6",
|
|
9
9
|
]
|
|
10
10
|
build-backend = "setuptools.build_meta"
|
|
11
11
|
|
|
@@ -29,6 +29,7 @@ dependencies = [
|
|
|
29
29
|
"typing-extensions >= 4.13.0, < 5",
|
|
30
30
|
"frequenz-api-common >= 0.8.0, < 1",
|
|
31
31
|
"frequenz-core >= 1.0.2, < 2",
|
|
32
|
+
"protobuf >= 6.33.1, < 7",
|
|
32
33
|
]
|
|
33
34
|
dynamic = ["version"]
|
|
34
35
|
|
|
@@ -41,39 +42,41 @@ dev-flake8 = [
|
|
|
41
42
|
"flake8 == 7.3.0",
|
|
42
43
|
"flake8-docstrings == 1.7.0",
|
|
43
44
|
"flake8-pyproject == 1.2.3", # For reading the flake8 config from pyproject.toml
|
|
44
|
-
"pydoclint == 0.
|
|
45
|
+
"pydoclint == 0.7.6",
|
|
45
46
|
"pydocstyle == 6.3.0",
|
|
46
47
|
]
|
|
47
|
-
dev-formatting = ["black == 25.
|
|
48
|
+
dev-formatting = ["black == 25.9.0", "isort == 6.1.0"]
|
|
48
49
|
dev-mkdocs = [
|
|
49
|
-
"Markdown == 3.
|
|
50
|
-
"black == 25.
|
|
50
|
+
"Markdown == 3.9",
|
|
51
|
+
"black == 25.9.0",
|
|
51
52
|
"mike == 2.1.3",
|
|
52
53
|
"mkdocs-gen-files == 0.5.0",
|
|
53
54
|
"mkdocs-literate-nav == 0.6.2",
|
|
54
|
-
"mkdocs-macros-plugin == 1.
|
|
55
|
-
"mkdocs-material == 9.6.
|
|
56
|
-
"mkdocstrings[python] == 0.30.
|
|
57
|
-
"mkdocstrings-python == 1.
|
|
58
|
-
"frequenz-repo-config[lib] == 0.13.
|
|
55
|
+
"mkdocs-macros-plugin == 1.4.0",
|
|
56
|
+
"mkdocs-material == 9.6.21",
|
|
57
|
+
"mkdocstrings[python] == 0.30.1",
|
|
58
|
+
"mkdocstrings-python == 1.18.2",
|
|
59
|
+
"frequenz-repo-config[lib] == 0.13.6",
|
|
59
60
|
]
|
|
60
61
|
dev-mypy = [
|
|
61
|
-
"mypy == 1.
|
|
62
|
-
"types-Markdown == 3.
|
|
62
|
+
"mypy == 1.18.2",
|
|
63
|
+
"types-Markdown == 3.9.0.20250906",
|
|
64
|
+
"types-protobuf == 6.32.1.20251105",
|
|
63
65
|
# For checking the noxfile, docs/ script, and tests
|
|
64
66
|
"frequenz-client-common[dev-mkdocs,dev-noxfile,dev-pytest]",
|
|
65
67
|
]
|
|
66
|
-
dev-noxfile = ["nox == 2025.
|
|
68
|
+
dev-noxfile = ["nox == 2025.10.16", "frequenz-repo-config[lib] == 0.13.6"]
|
|
67
69
|
dev-pylint = [
|
|
68
|
-
"pylint ==
|
|
70
|
+
"pylint == 4.0.3",
|
|
69
71
|
# For checking the noxfile, docs/ script, and tests
|
|
70
72
|
"frequenz-client-common[dev-mkdocs,dev-noxfile,dev-pytest]",
|
|
71
73
|
]
|
|
72
74
|
dev-pytest = [
|
|
73
|
-
"pytest == 8.4.
|
|
74
|
-
"frequenz-repo-config[extra-lint-examples] == 0.13.
|
|
75
|
-
"
|
|
76
|
-
"pytest-
|
|
75
|
+
"pytest == 8.4.2",
|
|
76
|
+
"frequenz-repo-config[extra-lint-examples] == 0.13.6",
|
|
77
|
+
"hypothesis == 6.140.3",
|
|
78
|
+
"pytest-mock == 3.15.1",
|
|
79
|
+
"pytest-asyncio == 1.2.0",
|
|
77
80
|
"async-solipsism == 0.8",
|
|
78
81
|
]
|
|
79
82
|
dev = [
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# License: MIT
|
|
2
|
+
# Copyright © 2025 Frequenz Energy-as-a-Service GmbH
|
|
3
|
+
|
|
4
|
+
"""Conversion of protobuf int enums to Python enums."""
|
|
5
|
+
|
|
6
|
+
import enum
|
|
7
|
+
from typing import Literal, TypeVar, overload
|
|
8
|
+
|
|
9
|
+
from typing_extensions import deprecated
|
|
10
|
+
|
|
11
|
+
EnumT = TypeVar("EnumT", bound=enum.Enum)
|
|
12
|
+
"""A type variable that is bound to an enum."""
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@overload
|
|
16
|
+
def enum_from_proto(
|
|
17
|
+
value: int, enum_type: type[EnumT], *, allow_invalid: Literal[False]
|
|
18
|
+
) -> EnumT: ...
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@overload
|
|
22
|
+
def enum_from_proto(
|
|
23
|
+
value: int, enum_type: type[EnumT], *, allow_invalid: Literal[True] = True
|
|
24
|
+
) -> EnumT | int: ...
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@deprecated(
|
|
28
|
+
"frequenz.client.common.enum_proto.enum_from_proto is deprecated. "
|
|
29
|
+
"Please use frequenz.client.common.proto.enum_from_proto instead."
|
|
30
|
+
)
|
|
31
|
+
def enum_from_proto(
|
|
32
|
+
value: int, enum_type: type[EnumT], *, allow_invalid: bool = True
|
|
33
|
+
) -> EnumT | int:
|
|
34
|
+
"""Convert a protobuf int enum value to a python enum.
|
|
35
|
+
|
|
36
|
+
Example:
|
|
37
|
+
```python
|
|
38
|
+
import enum
|
|
39
|
+
|
|
40
|
+
from proto import proto_pb2 # Just an example. pylint: disable=import-error
|
|
41
|
+
|
|
42
|
+
@enum.unique
|
|
43
|
+
class SomeEnum(enum.Enum):
|
|
44
|
+
# These values should match the protobuf enum values.
|
|
45
|
+
UNSPECIFIED = 0
|
|
46
|
+
SOME_VALUE = 1
|
|
47
|
+
|
|
48
|
+
enum_value = enum_from_proto(proto_pb2.SomeEnum.SOME_ENUM_SOME_VALUE, SomeEnum)
|
|
49
|
+
# -> SomeEnum.SOME_VALUE
|
|
50
|
+
|
|
51
|
+
enum_value = enum_from_proto(42, SomeEnum)
|
|
52
|
+
# -> 42
|
|
53
|
+
|
|
54
|
+
enum_value = enum_from_proto(
|
|
55
|
+
proto_pb2.SomeEnum.SOME_ENUM_UNKNOWN_VALUE, SomeEnum, allow_invalid=False
|
|
56
|
+
)
|
|
57
|
+
# -> ValueError
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
value: The protobuf int enum value.
|
|
62
|
+
enum_type: The python enum type to convert to.
|
|
63
|
+
allow_invalid: If `True`, return the value as an `int` if the value is not
|
|
64
|
+
a valid member of the enum (this allows for forward-compatibility with new
|
|
65
|
+
enum values defined in the protocol but not added to the Python enum yet).
|
|
66
|
+
If `False`, raise a `ValueError` if the value is not a valid member of the
|
|
67
|
+
enum.
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
The resulting python enum value if the protobuf value is known, otherwise
|
|
71
|
+
the input value converted to a plain `int`.
|
|
72
|
+
|
|
73
|
+
Raises:
|
|
74
|
+
ValueError: If `allow_invalid` is `False` and the value is not a valid member
|
|
75
|
+
of the enum.
|
|
76
|
+
"""
|
|
77
|
+
try:
|
|
78
|
+
return enum_type(value)
|
|
79
|
+
except ValueError:
|
|
80
|
+
if allow_invalid:
|
|
81
|
+
return value
|
|
82
|
+
raise
|
|
@@ -142,7 +142,10 @@ class Metric(enum.Enum):
|
|
|
142
142
|
SENSOR_IRRADIANCE = PBMetric.METRIC_SENSOR_IRRADIANCE
|
|
143
143
|
|
|
144
144
|
@classmethod
|
|
145
|
-
@deprecated(
|
|
145
|
+
@deprecated(
|
|
146
|
+
"frequenz.client.common.metric.Metric.from_proto() is deprecated. "
|
|
147
|
+
"Use frequenz.client.common.proto.enum_from_proto instead."
|
|
148
|
+
)
|
|
146
149
|
def from_proto(cls, metric: PBMetric.ValueType) -> Self:
|
|
147
150
|
"""Convert a protobuf Metric value to Metric enum.
|
|
148
151
|
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# License: MIT
|
|
2
|
+
# Copyright © 2025 Frequenz Energy-as-a-Service GmbH
|
|
3
|
+
|
|
4
|
+
"""Metrics definitions."""
|
|
5
|
+
|
|
6
|
+
from ._bounds import Bounds
|
|
7
|
+
from ._metric import Metric
|
|
8
|
+
from ._sample import (
|
|
9
|
+
AggregatedMetricValue,
|
|
10
|
+
AggregationMethod,
|
|
11
|
+
MetricConnection,
|
|
12
|
+
MetricConnectionCategory,
|
|
13
|
+
MetricSample,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"AggregatedMetricValue",
|
|
18
|
+
"AggregationMethod",
|
|
19
|
+
"Bounds",
|
|
20
|
+
"Metric",
|
|
21
|
+
"MetricConnection",
|
|
22
|
+
"MetricConnectionCategory",
|
|
23
|
+
"MetricSample",
|
|
24
|
+
]
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# License: MIT
|
|
2
|
+
# Copyright © 2024 Frequenz Energy-as-a-Service GmbH
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
"""Definitions for bounds."""
|
|
6
|
+
|
|
7
|
+
import dataclasses
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclasses.dataclass(frozen=True, kw_only=True)
|
|
11
|
+
class Bounds:
|
|
12
|
+
"""A set of lower and upper bounds for any metric.
|
|
13
|
+
|
|
14
|
+
The lower bound must be less than or equal to the upper bound.
|
|
15
|
+
|
|
16
|
+
The units of the bounds are always the same as the related metric.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
lower: float | None = None
|
|
20
|
+
"""The lower bound.
|
|
21
|
+
|
|
22
|
+
If `None`, there is no lower bound.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
upper: float | None = None
|
|
26
|
+
"""The upper bound.
|
|
27
|
+
|
|
28
|
+
If `None`, there is no upper bound.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __post_init__(self) -> None:
|
|
32
|
+
"""Validate these bounds."""
|
|
33
|
+
if self.lower is None:
|
|
34
|
+
return
|
|
35
|
+
if self.upper is None:
|
|
36
|
+
return
|
|
37
|
+
if self.lower > self.upper:
|
|
38
|
+
raise ValueError(
|
|
39
|
+
f"Lower bound ({self.lower}) must be less than or equal to upper "
|
|
40
|
+
f"bound ({self.upper})"
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
def __str__(self) -> str:
|
|
44
|
+
"""Return a string representation of these bounds."""
|
|
45
|
+
return f"[{self.lower}, {self.upper}]"
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
# License: MIT
|
|
2
|
+
# Copyright © 2024 Frequenz Energy-as-a-Service GmbH
|
|
3
|
+
|
|
4
|
+
"""Supported metrics for microgrid components."""
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
import enum
|
|
8
|
+
|
|
9
|
+
from frequenz.api.common.v1alpha8.metrics import metrics_pb2
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@enum.unique
|
|
13
|
+
class Metric(enum.Enum):
|
|
14
|
+
"""List of supported metrics.
|
|
15
|
+
|
|
16
|
+
Metric units are as follows:
|
|
17
|
+
|
|
18
|
+
* `VOLTAGE`: V (Volts)
|
|
19
|
+
* `CURRENT`: A (Amperes)
|
|
20
|
+
* `POWER_ACTIVE`: W (Watts)
|
|
21
|
+
* `POWER_APPARENT`: VA (Volt-Amperes)
|
|
22
|
+
* `POWER_REACTIVE`: VAr (Volt-Amperes reactive)
|
|
23
|
+
* `ENERGY_ACTIVE`: Wh (Watt-hours)
|
|
24
|
+
* `ENERGY_APPARENT`: VAh (Volt-Ampere hours)
|
|
25
|
+
* `ENERGY_REACTIVE`: VArh (Volt-Ampere reactive hours)
|
|
26
|
+
* `FREQUENCY`: Hz (Hertz)
|
|
27
|
+
* `TEMPERATURE`: °C (Degree Celsius)
|
|
28
|
+
* `BATTERY_SOC_PCT`: % (percentage)
|
|
29
|
+
* `BATTERY_CAPACITY`: Wh (Watt-hours)
|
|
30
|
+
* `FACTOR`: no unit
|
|
31
|
+
|
|
32
|
+
Note: AC energy metrics information
|
|
33
|
+
- This energy metric is reported directly from the component, and not a
|
|
34
|
+
result of aggregations in our systems. If a component does not have this
|
|
35
|
+
metric, this field cannot be populated.
|
|
36
|
+
|
|
37
|
+
- Components that provide energy metrics reset this metric from time to
|
|
38
|
+
time. This behaviour is specific to each component model. E.g., some
|
|
39
|
+
components reset it on UTC 00:00:00.
|
|
40
|
+
|
|
41
|
+
- This energy metric does not specify the start time of the accumulation
|
|
42
|
+
period, and therefore can be inconsistent.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
UNSPECIFIED = metrics_pb2.METRIC_UNSPECIFIED
|
|
46
|
+
"""The metric is unspecified (this should not be used)."""
|
|
47
|
+
|
|
48
|
+
DC_VOLTAGE = metrics_pb2.METRIC_DC_VOLTAGE
|
|
49
|
+
"""The DC voltage."""
|
|
50
|
+
|
|
51
|
+
DC_CURRENT = metrics_pb2.METRIC_DC_CURRENT
|
|
52
|
+
"""The DC current."""
|
|
53
|
+
|
|
54
|
+
DC_POWER = metrics_pb2.METRIC_DC_POWER
|
|
55
|
+
"""The DC power."""
|
|
56
|
+
|
|
57
|
+
AC_FREQUENCY = metrics_pb2.METRIC_AC_FREQUENCY
|
|
58
|
+
"""The AC frequency."""
|
|
59
|
+
|
|
60
|
+
AC_VOLTAGE = metrics_pb2.METRIC_AC_VOLTAGE
|
|
61
|
+
"""The AC electric potential difference."""
|
|
62
|
+
|
|
63
|
+
AC_VOLTAGE_PHASE_1_N = metrics_pb2.METRIC_AC_VOLTAGE_PHASE_1_N
|
|
64
|
+
"""The AC electric potential difference between phase 1 and neutral."""
|
|
65
|
+
|
|
66
|
+
AC_VOLTAGE_PHASE_2_N = metrics_pb2.METRIC_AC_VOLTAGE_PHASE_2_N
|
|
67
|
+
"""The AC electric potential difference between phase 2 and neutral."""
|
|
68
|
+
|
|
69
|
+
AC_VOLTAGE_PHASE_3_N = metrics_pb2.METRIC_AC_VOLTAGE_PHASE_3_N
|
|
70
|
+
"""The AC electric potential difference between phase 3 and neutral."""
|
|
71
|
+
|
|
72
|
+
AC_VOLTAGE_PHASE_1_PHASE_2 = metrics_pb2.METRIC_AC_VOLTAGE_PHASE_1_PHASE_2
|
|
73
|
+
"""The AC electric potential difference between phase 1 and phase 2."""
|
|
74
|
+
|
|
75
|
+
AC_VOLTAGE_PHASE_2_PHASE_3 = metrics_pb2.METRIC_AC_VOLTAGE_PHASE_2_PHASE_3
|
|
76
|
+
"""The AC electric potential difference between phase 2 and phase 3."""
|
|
77
|
+
|
|
78
|
+
AC_VOLTAGE_PHASE_3_PHASE_1 = metrics_pb2.METRIC_AC_VOLTAGE_PHASE_3_PHASE_1
|
|
79
|
+
"""The AC electric potential difference between phase 3 and phase 1."""
|
|
80
|
+
|
|
81
|
+
AC_CURRENT = metrics_pb2.METRIC_AC_CURRENT
|
|
82
|
+
"""The AC current."""
|
|
83
|
+
|
|
84
|
+
AC_CURRENT_PHASE_1 = metrics_pb2.METRIC_AC_CURRENT_PHASE_1
|
|
85
|
+
"""The AC current in phase 1."""
|
|
86
|
+
|
|
87
|
+
AC_CURRENT_PHASE_2 = metrics_pb2.METRIC_AC_CURRENT_PHASE_2
|
|
88
|
+
"""The AC current in phase 2."""
|
|
89
|
+
|
|
90
|
+
AC_CURRENT_PHASE_3 = metrics_pb2.METRIC_AC_CURRENT_PHASE_3
|
|
91
|
+
"""The AC current in phase 3."""
|
|
92
|
+
|
|
93
|
+
AC_POWER_APPARENT = metrics_pb2.METRIC_AC_POWER_APPARENT
|
|
94
|
+
"""The AC apparent power."""
|
|
95
|
+
|
|
96
|
+
AC_POWER_APPARENT_PHASE_1 = metrics_pb2.METRIC_AC_POWER_APPARENT_PHASE_1
|
|
97
|
+
"""The AC apparent power in phase 1."""
|
|
98
|
+
|
|
99
|
+
AC_POWER_APPARENT_PHASE_2 = metrics_pb2.METRIC_AC_POWER_APPARENT_PHASE_2
|
|
100
|
+
"""The AC apparent power in phase 2."""
|
|
101
|
+
|
|
102
|
+
AC_POWER_APPARENT_PHASE_3 = metrics_pb2.METRIC_AC_POWER_APPARENT_PHASE_3
|
|
103
|
+
"""The AC apparent power in phase 3."""
|
|
104
|
+
|
|
105
|
+
AC_POWER_ACTIVE = metrics_pb2.METRIC_AC_POWER_ACTIVE
|
|
106
|
+
"""The AC active power."""
|
|
107
|
+
|
|
108
|
+
AC_POWER_ACTIVE_PHASE_1 = metrics_pb2.METRIC_AC_POWER_ACTIVE_PHASE_1
|
|
109
|
+
"""The AC active power in phase 1."""
|
|
110
|
+
|
|
111
|
+
AC_POWER_ACTIVE_PHASE_2 = metrics_pb2.METRIC_AC_POWER_ACTIVE_PHASE_2
|
|
112
|
+
"""The AC active power in phase 2."""
|
|
113
|
+
|
|
114
|
+
AC_POWER_ACTIVE_PHASE_3 = metrics_pb2.METRIC_AC_POWER_ACTIVE_PHASE_3
|
|
115
|
+
"""The AC active power in phase 3."""
|
|
116
|
+
|
|
117
|
+
AC_POWER_REACTIVE = metrics_pb2.METRIC_AC_POWER_REACTIVE
|
|
118
|
+
"""The AC reactive power."""
|
|
119
|
+
|
|
120
|
+
AC_POWER_REACTIVE_PHASE_1 = metrics_pb2.METRIC_AC_POWER_REACTIVE_PHASE_1
|
|
121
|
+
"""The AC reactive power in phase 1."""
|
|
122
|
+
|
|
123
|
+
AC_POWER_REACTIVE_PHASE_2 = metrics_pb2.METRIC_AC_POWER_REACTIVE_PHASE_2
|
|
124
|
+
"""The AC reactive power in phase 2."""
|
|
125
|
+
|
|
126
|
+
AC_POWER_REACTIVE_PHASE_3 = metrics_pb2.METRIC_AC_POWER_REACTIVE_PHASE_3
|
|
127
|
+
"""The AC reactive power in phase 3."""
|
|
128
|
+
|
|
129
|
+
AC_POWER_FACTOR = metrics_pb2.METRIC_AC_POWER_FACTOR
|
|
130
|
+
"""The AC power factor."""
|
|
131
|
+
|
|
132
|
+
AC_POWER_FACTOR_PHASE_1 = metrics_pb2.METRIC_AC_POWER_FACTOR_PHASE_1
|
|
133
|
+
"""The AC power factor in phase 1."""
|
|
134
|
+
|
|
135
|
+
AC_POWER_FACTOR_PHASE_2 = metrics_pb2.METRIC_AC_POWER_FACTOR_PHASE_2
|
|
136
|
+
"""The AC power factor in phase 2."""
|
|
137
|
+
|
|
138
|
+
AC_POWER_FACTOR_PHASE_3 = metrics_pb2.METRIC_AC_POWER_FACTOR_PHASE_3
|
|
139
|
+
"""The AC power factor in phase 3."""
|
|
140
|
+
|
|
141
|
+
AC_ENERGY_APPARENT = metrics_pb2.METRIC_AC_ENERGY_APPARENT
|
|
142
|
+
"""The AC apparent energy."""
|
|
143
|
+
|
|
144
|
+
AC_ENERGY_APPARENT_PHASE_1 = metrics_pb2.METRIC_AC_ENERGY_APPARENT_PHASE_1
|
|
145
|
+
"""The AC apparent energy in phase 1."""
|
|
146
|
+
|
|
147
|
+
AC_ENERGY_APPARENT_PHASE_2 = metrics_pb2.METRIC_AC_ENERGY_APPARENT_PHASE_2
|
|
148
|
+
"""The AC apparent energy in phase 2."""
|
|
149
|
+
|
|
150
|
+
AC_ENERGY_APPARENT_PHASE_3 = metrics_pb2.METRIC_AC_ENERGY_APPARENT_PHASE_3
|
|
151
|
+
"""The AC apparent energy in phase 3."""
|
|
152
|
+
|
|
153
|
+
AC_ENERGY_ACTIVE = metrics_pb2.METRIC_AC_ENERGY_ACTIVE
|
|
154
|
+
"""The AC active energy."""
|
|
155
|
+
|
|
156
|
+
AC_ENERGY_ACTIVE_PHASE_1 = metrics_pb2.METRIC_AC_ENERGY_ACTIVE_PHASE_1
|
|
157
|
+
"""The AC active energy in phase 1."""
|
|
158
|
+
|
|
159
|
+
AC_ENERGY_ACTIVE_PHASE_2 = metrics_pb2.METRIC_AC_ENERGY_ACTIVE_PHASE_2
|
|
160
|
+
"""The AC active energy in phase 2."""
|
|
161
|
+
|
|
162
|
+
AC_ENERGY_ACTIVE_PHASE_3 = metrics_pb2.METRIC_AC_ENERGY_ACTIVE_PHASE_3
|
|
163
|
+
"""The AC active energy in phase 3."""
|
|
164
|
+
|
|
165
|
+
AC_ENERGY_ACTIVE_CONSUMED = metrics_pb2.METRIC_AC_ENERGY_ACTIVE_CONSUMED
|
|
166
|
+
"""The AC active energy consumed."""
|
|
167
|
+
|
|
168
|
+
AC_ENERGY_ACTIVE_CONSUMED_PHASE_1 = (
|
|
169
|
+
metrics_pb2.METRIC_AC_ENERGY_ACTIVE_CONSUMED_PHASE_1
|
|
170
|
+
)
|
|
171
|
+
"""The AC active energy consumed in phase 1."""
|
|
172
|
+
|
|
173
|
+
AC_ENERGY_ACTIVE_CONSUMED_PHASE_2 = (
|
|
174
|
+
metrics_pb2.METRIC_AC_ENERGY_ACTIVE_CONSUMED_PHASE_2
|
|
175
|
+
)
|
|
176
|
+
"""The AC active energy consumed in phase 2."""
|
|
177
|
+
|
|
178
|
+
AC_ENERGY_ACTIVE_CONSUMED_PHASE_3 = (
|
|
179
|
+
metrics_pb2.METRIC_AC_ENERGY_ACTIVE_CONSUMED_PHASE_3
|
|
180
|
+
)
|
|
181
|
+
"""The AC active energy consumed in phase 3."""
|
|
182
|
+
|
|
183
|
+
AC_ENERGY_ACTIVE_DELIVERED = metrics_pb2.METRIC_AC_ENERGY_ACTIVE_DELIVERED
|
|
184
|
+
"""The AC active energy delivered."""
|
|
185
|
+
|
|
186
|
+
AC_ENERGY_ACTIVE_DELIVERED_PHASE_1 = (
|
|
187
|
+
metrics_pb2.METRIC_AC_ENERGY_ACTIVE_DELIVERED_PHASE_1
|
|
188
|
+
)
|
|
189
|
+
"""The AC active energy delivered in phase 1."""
|
|
190
|
+
|
|
191
|
+
AC_ENERGY_ACTIVE_DELIVERED_PHASE_2 = (
|
|
192
|
+
metrics_pb2.METRIC_AC_ENERGY_ACTIVE_DELIVERED_PHASE_2
|
|
193
|
+
)
|
|
194
|
+
"""The AC active energy delivered in phase 2."""
|
|
195
|
+
|
|
196
|
+
AC_ENERGY_ACTIVE_DELIVERED_PHASE_3 = (
|
|
197
|
+
metrics_pb2.METRIC_AC_ENERGY_ACTIVE_DELIVERED_PHASE_3
|
|
198
|
+
)
|
|
199
|
+
"""The AC active energy delivered in phase 3."""
|
|
200
|
+
|
|
201
|
+
AC_ENERGY_REACTIVE = metrics_pb2.METRIC_AC_ENERGY_REACTIVE
|
|
202
|
+
"""The AC reactive energy."""
|
|
203
|
+
|
|
204
|
+
AC_ENERGY_REACTIVE_PHASE_1 = metrics_pb2.METRIC_AC_ENERGY_REACTIVE_PHASE_1
|
|
205
|
+
"""The AC reactive energy in phase 1."""
|
|
206
|
+
|
|
207
|
+
AC_ENERGY_REACTIVE_PHASE_2 = metrics_pb2.METRIC_AC_ENERGY_REACTIVE_PHASE_2
|
|
208
|
+
"""The AC reactive energy in phase 2."""
|
|
209
|
+
|
|
210
|
+
AC_ENERGY_REACTIVE_PHASE_3 = metrics_pb2.METRIC_AC_ENERGY_REACTIVE_PHASE_3
|
|
211
|
+
"""The AC reactive energy in phase 3."""
|
|
212
|
+
|
|
213
|
+
AC_TOTAL_HARMONIC_DISTORTION_CURRENT = (
|
|
214
|
+
metrics_pb2.METRIC_AC_TOTAL_HARMONIC_DISTORTION_CURRENT
|
|
215
|
+
)
|
|
216
|
+
"""The AC total harmonic distortion current."""
|
|
217
|
+
|
|
218
|
+
AC_TOTAL_HARMONIC_DISTORTION_CURRENT_PHASE_1 = (
|
|
219
|
+
metrics_pb2.METRIC_AC_TOTAL_HARMONIC_DISTORTION_CURRENT_PHASE_1
|
|
220
|
+
)
|
|
221
|
+
"""The AC total harmonic distortion current in phase 1."""
|
|
222
|
+
|
|
223
|
+
AC_TOTAL_HARMONIC_DISTORTION_CURRENT_PHASE_2 = (
|
|
224
|
+
metrics_pb2.METRIC_AC_TOTAL_HARMONIC_DISTORTION_CURRENT_PHASE_2
|
|
225
|
+
)
|
|
226
|
+
"""The AC total harmonic distortion current in phase 2."""
|
|
227
|
+
|
|
228
|
+
AC_TOTAL_HARMONIC_DISTORTION_CURRENT_PHASE_3 = (
|
|
229
|
+
metrics_pb2.METRIC_AC_TOTAL_HARMONIC_DISTORTION_CURRENT_PHASE_3
|
|
230
|
+
)
|
|
231
|
+
"""The AC total harmonic distortion current in phase 3."""
|
|
232
|
+
|
|
233
|
+
BATTERY_CAPACITY = metrics_pb2.METRIC_BATTERY_CAPACITY
|
|
234
|
+
"""The capacity of the battery."""
|
|
235
|
+
|
|
236
|
+
BATTERY_SOC_PCT = metrics_pb2.METRIC_BATTERY_SOC_PCT
|
|
237
|
+
"""The state of charge of the battery as a percentage."""
|
|
238
|
+
|
|
239
|
+
BATTERY_TEMPERATURE = metrics_pb2.METRIC_BATTERY_TEMPERATURE
|
|
240
|
+
"""The temperature of the battery."""
|
|
241
|
+
|
|
242
|
+
INVERTER_TEMPERATURE = metrics_pb2.METRIC_INVERTER_TEMPERATURE
|
|
243
|
+
"""The temperature of the inverter."""
|
|
244
|
+
|
|
245
|
+
INVERTER_TEMPERATURE_CABINET = metrics_pb2.METRIC_INVERTER_TEMPERATURE_CABINET
|
|
246
|
+
"""The temperature of the inverter cabinet."""
|
|
247
|
+
|
|
248
|
+
INVERTER_TEMPERATURE_HEATSINK = metrics_pb2.METRIC_INVERTER_TEMPERATURE_HEATSINK
|
|
249
|
+
"""The temperature of the inverter heatsink."""
|
|
250
|
+
|
|
251
|
+
INVERTER_TEMPERATURE_TRANSFORMER = (
|
|
252
|
+
metrics_pb2.METRIC_INVERTER_TEMPERATURE_TRANSFORMER
|
|
253
|
+
)
|
|
254
|
+
"""The temperature of the inverter transformer."""
|
|
255
|
+
|
|
256
|
+
EV_CHARGER_TEMPERATURE = metrics_pb2.METRIC_EV_CHARGER_TEMPERATURE
|
|
257
|
+
"""The temperature of the EV charger."""
|
|
258
|
+
|
|
259
|
+
SENSOR_WIND_SPEED = metrics_pb2.METRIC_SENSOR_WIND_SPEED
|
|
260
|
+
"""The speed of the wind measured."""
|
|
261
|
+
|
|
262
|
+
SENSOR_WIND_DIRECTION = metrics_pb2.METRIC_SENSOR_WIND_DIRECTION
|
|
263
|
+
"""The direction of the wind measured."""
|
|
264
|
+
|
|
265
|
+
SENSOR_TEMPERATURE = metrics_pb2.METRIC_SENSOR_TEMPERATURE
|
|
266
|
+
"""The temperature measured."""
|
|
267
|
+
|
|
268
|
+
SENSOR_RELATIVE_HUMIDITY = metrics_pb2.METRIC_SENSOR_RELATIVE_HUMIDITY
|
|
269
|
+
"""The relative humidity measured."""
|
|
270
|
+
|
|
271
|
+
SENSOR_DEW_POINT = metrics_pb2.METRIC_SENSOR_DEW_POINT
|
|
272
|
+
"""The dew point measured."""
|
|
273
|
+
|
|
274
|
+
SENSOR_AIR_PRESSURE = metrics_pb2.METRIC_SENSOR_AIR_PRESSURE
|
|
275
|
+
"""The air pressure measured."""
|
|
276
|
+
|
|
277
|
+
SENSOR_IRRADIANCE = metrics_pb2.METRIC_SENSOR_IRRADIANCE
|
|
278
|
+
"""The irradiance measured."""
|