frequenz-client-common 0.3.3__tar.gz → 0.3.4__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.
Files changed (29) hide show
  1. {frequenz_client_common-0.3.3/src/frequenz_client_common.egg-info → frequenz_client_common-0.3.4}/PKG-INFO +17 -17
  2. frequenz_client_common-0.3.4/RELEASE_NOTES.md +18 -0
  3. {frequenz_client_common-0.3.3 → frequenz_client_common-0.3.4}/pyproject.toml +20 -20
  4. frequenz_client_common-0.3.4/src/frequenz/client/common/v1alpha8/__init__.py +4 -0
  5. frequenz_client_common-0.3.4/src/frequenz/client/common/v1alpha8/metric/__init__.py +162 -0
  6. frequenz_client_common-0.3.4/src/frequenz/client/common/v1alpha8/microgrid/__init__.py +18 -0
  7. frequenz_client_common-0.3.4/src/frequenz/client/common/v1alpha8/microgrid/electrical_components/__init__.py +459 -0
  8. frequenz_client_common-0.3.4/src/frequenz/client/common/v1alpha8/microgrid/sensors.py +13 -0
  9. frequenz_client_common-0.3.4/src/frequenz/client/common/v1alpha8/pagination/__init__.py +91 -0
  10. frequenz_client_common-0.3.4/src/frequenz/client/common/v1alpha8/streaming/__init__.py +26 -0
  11. {frequenz_client_common-0.3.3 → frequenz_client_common-0.3.4/src/frequenz_client_common.egg-info}/PKG-INFO +17 -17
  12. {frequenz_client_common-0.3.3 → frequenz_client_common-0.3.4}/src/frequenz_client_common.egg-info/SOURCES.txt +7 -0
  13. {frequenz_client_common-0.3.3 → frequenz_client_common-0.3.4}/src/frequenz_client_common.egg-info/requires.txt +16 -16
  14. frequenz_client_common-0.3.3/RELEASE_NOTES.md +0 -22
  15. {frequenz_client_common-0.3.3 → frequenz_client_common-0.3.4}/LICENSE +0 -0
  16. {frequenz_client_common-0.3.3 → frequenz_client_common-0.3.4}/MANIFEST.in +0 -0
  17. {frequenz_client_common-0.3.3 → frequenz_client_common-0.3.4}/README.md +0 -0
  18. {frequenz_client_common-0.3.3 → frequenz_client_common-0.3.4}/setup.cfg +0 -0
  19. {frequenz_client_common-0.3.3 → frequenz_client_common-0.3.4}/src/frequenz/client/common/__init__.py +0 -0
  20. {frequenz_client_common-0.3.3 → frequenz_client_common-0.3.4}/src/frequenz/client/common/conftest.py +0 -0
  21. {frequenz_client_common-0.3.3 → frequenz_client_common-0.3.4}/src/frequenz/client/common/enum_proto.py +0 -0
  22. {frequenz_client_common-0.3.3 → frequenz_client_common-0.3.4}/src/frequenz/client/common/metric/__init__.py +0 -0
  23. {frequenz_client_common-0.3.3 → frequenz_client_common-0.3.4}/src/frequenz/client/common/microgrid/__init__.py +0 -0
  24. {frequenz_client_common-0.3.3 → frequenz_client_common-0.3.4}/src/frequenz/client/common/microgrid/components/__init__.py +0 -0
  25. {frequenz_client_common-0.3.3 → frequenz_client_common-0.3.4}/src/frequenz/client/common/microgrid/sensors.py +0 -0
  26. {frequenz_client_common-0.3.3 → frequenz_client_common-0.3.4}/src/frequenz/client/common/pagination/__init__.py +0 -0
  27. {frequenz_client_common-0.3.3 → frequenz_client_common-0.3.4}/src/frequenz/client/common/py.typed +0 -0
  28. {frequenz_client_common-0.3.3 → frequenz_client_common-0.3.4}/src/frequenz_client_common.egg-info/dependency_links.txt +0 -0
  29. {frequenz_client_common-0.3.3 → frequenz_client_common-0.3.4}/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
3
+ Version: 0.3.4
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
@@ -21,10 +21,10 @@ Requires-Python: <4,>=3.11
21
21
  Description-Content-Type: text/markdown
22
22
  License-File: LICENSE
23
23
  Requires-Dist: typing-extensions<5,>=4.13.0
24
- Requires-Dist: frequenz-api-common<7,>=0.6.1
24
+ Requires-Dist: frequenz-api-common<9,>=0.8.0
25
25
  Requires-Dist: frequenz-core<2,>=1.0.2
26
26
  Provides-Extra: dev-flake8
27
- Requires-Dist: flake8==7.2.0; extra == "dev-flake8"
27
+ Requires-Dist: flake8==7.3.0; extra == "dev-flake8"
28
28
  Requires-Dist: flake8-docstrings==1.7.0; extra == "dev-flake8"
29
29
  Requires-Dist: flake8-pyproject==1.2.3; extra == "dev-flake8"
30
30
  Requires-Dist: pydoclint==0.6.6; extra == "dev-flake8"
@@ -33,32 +33,32 @@ Provides-Extra: dev-formatting
33
33
  Requires-Dist: black==25.1.0; extra == "dev-formatting"
34
34
  Requires-Dist: isort==6.0.1; extra == "dev-formatting"
35
35
  Provides-Extra: dev-mkdocs
36
- Requires-Dist: Markdown==3.8; extra == "dev-mkdocs"
36
+ Requires-Dist: Markdown==3.8.2; extra == "dev-mkdocs"
37
37
  Requires-Dist: black==25.1.0; extra == "dev-mkdocs"
38
38
  Requires-Dist: mike==2.1.3; extra == "dev-mkdocs"
39
39
  Requires-Dist: mkdocs-gen-files==0.5.0; extra == "dev-mkdocs"
40
40
  Requires-Dist: mkdocs-literate-nav==0.6.2; extra == "dev-mkdocs"
41
41
  Requires-Dist: mkdocs-macros-plugin==1.3.7; extra == "dev-mkdocs"
42
- Requires-Dist: mkdocs-material==9.6.12; extra == "dev-mkdocs"
43
- Requires-Dist: mkdocstrings[python]==0.29.1; extra == "dev-mkdocs"
44
- Requires-Dist: mkdocstrings-python==1.16.10; extra == "dev-mkdocs"
45
- Requires-Dist: frequenz-repo-config[lib]==0.13.3; extra == "dev-mkdocs"
42
+ Requires-Dist: mkdocs-material==9.6.16; extra == "dev-mkdocs"
43
+ Requires-Dist: mkdocstrings[python]==0.30.0; extra == "dev-mkdocs"
44
+ Requires-Dist: mkdocstrings-python==1.16.12; extra == "dev-mkdocs"
45
+ Requires-Dist: frequenz-repo-config[lib]==0.13.5; extra == "dev-mkdocs"
46
46
  Provides-Extra: dev-mypy
47
- Requires-Dist: mypy==1.15.0; extra == "dev-mypy"
48
- Requires-Dist: types-Markdown==3.8.0.20250415; extra == "dev-mypy"
47
+ Requires-Dist: mypy==1.17.1; extra == "dev-mypy"
48
+ Requires-Dist: types-Markdown==3.8.0.20250708; extra == "dev-mypy"
49
49
  Requires-Dist: frequenz-client-common[dev-mkdocs,dev-noxfile,dev-pytest]; extra == "dev-mypy"
50
50
  Provides-Extra: dev-noxfile
51
51
  Requires-Dist: nox==2025.5.1; extra == "dev-noxfile"
52
- Requires-Dist: frequenz-repo-config[lib]==0.13.3; extra == "dev-noxfile"
52
+ Requires-Dist: frequenz-repo-config[lib]==0.13.5; extra == "dev-noxfile"
53
53
  Provides-Extra: dev-pylint
54
- Requires-Dist: pylint==3.3.6; extra == "dev-pylint"
54
+ Requires-Dist: pylint==3.3.7; extra == "dev-pylint"
55
55
  Requires-Dist: frequenz-client-common[dev-mkdocs,dev-noxfile,dev-pytest]; extra == "dev-pylint"
56
56
  Provides-Extra: dev-pytest
57
- Requires-Dist: pytest==8.3.5; extra == "dev-pytest"
58
- Requires-Dist: frequenz-repo-config[extra-lint-examples]==0.13.3; extra == "dev-pytest"
59
- Requires-Dist: pytest-mock==3.14.0; extra == "dev-pytest"
60
- Requires-Dist: pytest-asyncio==0.26.0; extra == "dev-pytest"
61
- Requires-Dist: async-solipsism==0.7; extra == "dev-pytest"
57
+ Requires-Dist: pytest==8.4.1; extra == "dev-pytest"
58
+ Requires-Dist: frequenz-repo-config[extra-lint-examples]==0.13.5; extra == "dev-pytest"
59
+ Requires-Dist: pytest-mock==3.14.1; extra == "dev-pytest"
60
+ Requires-Dist: pytest-asyncio==1.1.0; extra == "dev-pytest"
61
+ Requires-Dist: async-solipsism==0.8; extra == "dev-pytest"
62
62
  Provides-Extra: dev
63
63
  Requires-Dist: frequenz-client-common[dev-flake8,dev-formatting,dev-mkdocs,dev-mypy,dev-noxfile,dev-pylint,dev-pytest]; extra == "dev"
64
64
  Dynamic: license-file
@@ -0,0 +1,18 @@
1
+ # Frequenz Client Common Library Release Notes
2
+
3
+ ## Summary
4
+
5
+ This release introduces the `v1alpha8` module to support a new API version.
6
+
7
+ ## Upgrading
8
+
9
+ <!-- Here goes notes on how to upgrade from previous versions, including deprecations and what they should be replaced with -->
10
+
11
+ ## New Features
12
+
13
+ - Provide access to new API using new `v1alpha8` module.
14
+ - Mapping for the new `Event` message has been added.
15
+
16
+ ## Bug Fixes
17
+
18
+ - Updated display of protobuf version warnings
@@ -3,9 +3,9 @@
3
3
 
4
4
  [build-system]
5
5
  requires = [
6
- "setuptools == 80.3.1",
6
+ "setuptools == 80.9.0",
7
7
  "setuptools_scm[toml] == 8.3.1",
8
- "frequenz-repo-config[lib] == 0.13.3",
8
+ "frequenz-repo-config[lib] == 0.13.5",
9
9
  ]
10
10
  build-backend = "setuptools.build_meta"
11
11
 
@@ -27,7 +27,7 @@ classifiers = [
27
27
  requires-python = ">= 3.11, < 4"
28
28
  dependencies = [
29
29
  "typing-extensions >= 4.13.0, < 5",
30
- "frequenz-api-common >= 0.6.1, < 7",
30
+ "frequenz-api-common >= 0.8.0, < 9",
31
31
  "frequenz-core >= 1.0.2, < 2",
32
32
  ]
33
33
  dynamic = ["version"]
@@ -38,43 +38,43 @@ email = "floss@frequenz.com"
38
38
 
39
39
  [project.optional-dependencies]
40
40
  dev-flake8 = [
41
- "flake8 == 7.2.0",
41
+ "flake8 == 7.3.0",
42
42
  "flake8-docstrings == 1.7.0",
43
- "flake8-pyproject == 1.2.3", # For reading the flake8 config from pyproject.toml
43
+ "flake8-pyproject == 1.2.3", # For reading the flake8 config from pyproject.toml
44
44
  "pydoclint == 0.6.6",
45
45
  "pydocstyle == 6.3.0",
46
46
  ]
47
47
  dev-formatting = ["black == 25.1.0", "isort == 6.0.1"]
48
48
  dev-mkdocs = [
49
- "Markdown == 3.8",
49
+ "Markdown == 3.8.2",
50
50
  "black == 25.1.0",
51
51
  "mike == 2.1.3",
52
52
  "mkdocs-gen-files == 0.5.0",
53
53
  "mkdocs-literate-nav == 0.6.2",
54
54
  "mkdocs-macros-plugin == 1.3.7",
55
- "mkdocs-material == 9.6.12",
56
- "mkdocstrings[python] == 0.29.1",
57
- "mkdocstrings-python == 1.16.10",
58
- "frequenz-repo-config[lib] == 0.13.3",
55
+ "mkdocs-material == 9.6.16",
56
+ "mkdocstrings[python] == 0.30.0",
57
+ "mkdocstrings-python == 1.16.12",
58
+ "frequenz-repo-config[lib] == 0.13.5",
59
59
  ]
60
60
  dev-mypy = [
61
- "mypy == 1.15.0",
62
- "types-Markdown == 3.8.0.20250415",
61
+ "mypy == 1.17.1",
62
+ "types-Markdown == 3.8.0.20250708",
63
63
  # For checking the noxfile, docs/ script, and tests
64
64
  "frequenz-client-common[dev-mkdocs,dev-noxfile,dev-pytest]",
65
65
  ]
66
- dev-noxfile = ["nox == 2025.5.1", "frequenz-repo-config[lib] == 0.13.3"]
66
+ dev-noxfile = ["nox == 2025.5.1", "frequenz-repo-config[lib] == 0.13.5"]
67
67
  dev-pylint = [
68
- "pylint == 3.3.6",
68
+ "pylint == 3.3.7",
69
69
  # For checking the noxfile, docs/ script, and tests
70
70
  "frequenz-client-common[dev-mkdocs,dev-noxfile,dev-pytest]",
71
71
  ]
72
72
  dev-pytest = [
73
- "pytest == 8.3.5",
74
- "frequenz-repo-config[extra-lint-examples] == 0.13.3",
75
- "pytest-mock == 3.14.0",
76
- "pytest-asyncio == 0.26.0",
77
- "async-solipsism == 0.7",
73
+ "pytest == 8.4.1",
74
+ "frequenz-repo-config[extra-lint-examples] == 0.13.5",
75
+ "pytest-mock == 3.14.1",
76
+ "pytest-asyncio == 1.1.0",
77
+ "async-solipsism == 0.8",
78
78
  ]
79
79
  dev = [
80
80
  "frequenz-client-common[dev-mkdocs,dev-flake8,dev-formatting,dev-mkdocs,dev-mypy,dev-noxfile,dev-pylint,dev-pytest]",
@@ -145,7 +145,6 @@ disable = [
145
145
  ]
146
146
 
147
147
  [tool.pytest.ini_options]
148
- addopts = "-vv"
149
148
  filterwarnings = [
150
149
  "error",
151
150
  "once::DeprecationWarning",
@@ -157,6 +156,7 @@ filterwarnings = [
157
156
  # characters as this is a regex.
158
157
  'ignore:Protobuf gencode version .*exactly one major version older.*:UserWarning',
159
158
  ]
159
+ addopts = "-vv"
160
160
  testpaths = ["tests", "src"]
161
161
  asyncio_mode = "auto"
162
162
  asyncio_default_fixture_loop_scope = "function"
@@ -0,0 +1,4 @@
1
+ # License: MIT
2
+ # Copyright © 2025 Frequenz Energy-as-a-Service GmbH
3
+
4
+ """Types introduced or modified in the v1alpha8 version of the common api."""
@@ -0,0 +1,162 @@
1
+ # License: MIT
2
+ # Copyright © 2024 Frequenz Energy-as-a-Service GmbH
3
+
4
+ """Module to define the metrics used with the common client."""
5
+
6
+ import enum
7
+ from typing import Self
8
+
9
+ from frequenz.api.common.v1alpha8.metrics.metrics_pb2 import Metric as PBMetric
10
+ from typing_extensions import deprecated
11
+
12
+
13
+ @enum.unique
14
+ class Metric(enum.Enum):
15
+ """List of supported metrics.
16
+
17
+ AC energy metrics information:
18
+ * This energy metric is reported directly from the component, and not a
19
+ result of aggregations in our systems. If a component does not have this
20
+ metric, this field cannot be populated.
21
+ * Components that provide energy metrics reset this metric from time to
22
+ time. This behaviour is specific to each component model. E.g., some
23
+ components reset it on UTC 00:00:00.
24
+ * This energy metric does not specify the timestamp since when the energy
25
+ was being accumulated, and therefore can be inconsistent.
26
+ """
27
+
28
+ # Default value
29
+ UNSPECIFIED = PBMetric.METRIC_UNSPECIFIED
30
+
31
+ # DC electricity metrics
32
+ DC_VOLTAGE = PBMetric.METRIC_DC_VOLTAGE
33
+ DC_CURRENT = PBMetric.METRIC_DC_CURRENT
34
+ DC_POWER = PBMetric.METRIC_DC_POWER
35
+
36
+ # General AC electricity metrics
37
+ AC_FREQUENCY = PBMetric.METRIC_AC_FREQUENCY
38
+ AC_VOLTAGE = PBMetric.METRIC_AC_VOLTAGE
39
+ AC_VOLTAGE_PHASE_1_N = PBMetric.METRIC_AC_VOLTAGE_PHASE_1_N
40
+ AC_VOLTAGE_PHASE_2_N = PBMetric.METRIC_AC_VOLTAGE_PHASE_2_N
41
+ AC_VOLTAGE_PHASE_3_N = PBMetric.METRIC_AC_VOLTAGE_PHASE_3_N
42
+ AC_VOLTAGE_PHASE_1_PHASE_2 = PBMetric.METRIC_AC_VOLTAGE_PHASE_1_PHASE_2
43
+ AC_VOLTAGE_PHASE_2_PHASE_3 = PBMetric.METRIC_AC_VOLTAGE_PHASE_2_PHASE_3
44
+ AC_VOLTAGE_PHASE_3_PHASE_1 = PBMetric.METRIC_AC_VOLTAGE_PHASE_3_PHASE_1
45
+ AC_CURRENT = PBMetric.METRIC_AC_CURRENT
46
+ AC_CURRENT_PHASE_1 = PBMetric.METRIC_AC_CURRENT_PHASE_1
47
+ AC_CURRENT_PHASE_2 = PBMetric.METRIC_AC_CURRENT_PHASE_2
48
+ AC_CURRENT_PHASE_3 = PBMetric.METRIC_AC_CURRENT_PHASE_3
49
+
50
+ # AC power metrics
51
+ AC_POWER_APPARENT = PBMetric.METRIC_AC_POWER_APPARENT
52
+ AC_POWER_APPARENT_PHASE_1 = PBMetric.METRIC_AC_POWER_APPARENT_PHASE_1
53
+ AC_POWER_APPARENT_PHASE_2 = PBMetric.METRIC_AC_POWER_APPARENT_PHASE_2
54
+ AC_POWER_APPARENT_PHASE_3 = PBMetric.METRIC_AC_POWER_APPARENT_PHASE_3
55
+ AC_POWER_ACTIVE = PBMetric.METRIC_AC_POWER_ACTIVE
56
+ AC_POWER_ACTIVE_PHASE_1 = PBMetric.METRIC_AC_POWER_ACTIVE_PHASE_1
57
+ AC_POWER_ACTIVE_PHASE_2 = PBMetric.METRIC_AC_POWER_ACTIVE_PHASE_2
58
+ AC_POWER_ACTIVE_PHASE_3 = PBMetric.METRIC_AC_POWER_ACTIVE_PHASE_3
59
+ AC_POWER_REACTIVE = PBMetric.METRIC_AC_POWER_REACTIVE
60
+ AC_POWER_REACTIVE_PHASE_1 = PBMetric.METRIC_AC_POWER_REACTIVE_PHASE_1
61
+ AC_POWER_REACTIVE_PHASE_2 = PBMetric.METRIC_AC_POWER_REACTIVE_PHASE_2
62
+ AC_POWER_REACTIVE_PHASE_3 = PBMetric.METRIC_AC_POWER_REACTIVE_PHASE_3
63
+
64
+ # AC power factor
65
+ AC_POWER_FACTOR = PBMetric.METRIC_AC_POWER_FACTOR
66
+ AC_POWER_FACTOR_PHASE_1 = PBMetric.METRIC_AC_POWER_FACTOR_PHASE_1
67
+ AC_POWER_FACTOR_PHASE_2 = PBMetric.METRIC_AC_POWER_FACTOR_PHASE_2
68
+ AC_POWER_FACTOR_PHASE_3 = PBMetric.METRIC_AC_POWER_FACTOR_PHASE_3
69
+
70
+ # AC energy metrics - Please be careful when using and check Enum docs
71
+ AC_ENERGY_APPARENT = PBMetric.METRIC_AC_ENERGY_APPARENT
72
+ AC_ENERGY_APPARENT_PHASE_1 = PBMetric.METRIC_AC_ENERGY_APPARENT_PHASE_1
73
+ AC_ENERGY_APPARENT_PHASE_2 = PBMetric.METRIC_AC_ENERGY_APPARENT_PHASE_2
74
+ AC_ENERGY_APPARENT_PHASE_3 = PBMetric.METRIC_AC_ENERGY_APPARENT_PHASE_3
75
+ AC_ENERGY_ACTIVE = PBMetric.METRIC_AC_ENERGY_ACTIVE
76
+ AC_ENERGY_ACTIVE_PHASE_1 = PBMetric.METRIC_AC_ENERGY_ACTIVE_PHASE_1
77
+ AC_ENERGY_ACTIVE_PHASE_2 = PBMetric.METRIC_AC_ENERGY_ACTIVE_PHASE_2
78
+ AC_ENERGY_ACTIVE_PHASE_3 = PBMetric.METRIC_AC_ENERGY_ACTIVE_PHASE_3
79
+ AC_ENERGY_ACTIVE_CONSUMED = PBMetric.METRIC_AC_ENERGY_ACTIVE_CONSUMED
80
+ AC_ENERGY_ACTIVE_CONSUMED_PHASE_1 = (
81
+ PBMetric.METRIC_AC_ENERGY_ACTIVE_CONSUMED_PHASE_1
82
+ )
83
+ AC_ENERGY_ACTIVE_CONSUMED_PHASE_2 = (
84
+ PBMetric.METRIC_AC_ENERGY_ACTIVE_CONSUMED_PHASE_2
85
+ )
86
+ AC_ENERGY_ACTIVE_CONSUMED_PHASE_3 = (
87
+ PBMetric.METRIC_AC_ENERGY_ACTIVE_CONSUMED_PHASE_3
88
+ )
89
+ AC_ENERGY_ACTIVE_DELIVERED = PBMetric.METRIC_AC_ENERGY_ACTIVE_DELIVERED
90
+ AC_ENERGY_ACTIVE_DELIVERED_PHASE_1 = (
91
+ PBMetric.METRIC_AC_ENERGY_ACTIVE_DELIVERED_PHASE_1
92
+ )
93
+ AC_ENERGY_ACTIVE_DELIVERED_PHASE_2 = (
94
+ PBMetric.METRIC_AC_ENERGY_ACTIVE_DELIVERED_PHASE_2
95
+ )
96
+ AC_ENERGY_ACTIVE_DELIVERED_PHASE_3 = (
97
+ PBMetric.METRIC_AC_ENERGY_ACTIVE_DELIVERED_PHASE_3
98
+ )
99
+ AC_ENERGY_REACTIVE = PBMetric.METRIC_AC_ENERGY_REACTIVE
100
+ AC_ENERGY_REACTIVE_PHASE_1 = PBMetric.METRIC_AC_ENERGY_REACTIVE_PHASE_1
101
+ AC_ENERGY_REACTIVE_PHASE_2 = PBMetric.METRIC_AC_ENERGY_REACTIVE_PHASE_2
102
+ AC_ENERGY_REACTIVE_PHASE_3 = PBMetric.METRIC_AC_ENERGY_REACTIVE_PHASE_3
103
+
104
+ # AC harmonics
105
+ AC_TOTAL_HARMONIC_DISTORTION_CURRENT = (
106
+ PBMetric.METRIC_AC_TOTAL_HARMONIC_DISTORTION_CURRENT
107
+ )
108
+ AC_TOTAL_HARMONIC_DISTORTION_CURRENT_PHASE_1 = (
109
+ PBMetric.METRIC_AC_TOTAL_HARMONIC_DISTORTION_CURRENT_PHASE_1
110
+ )
111
+ AC_TOTAL_HARMONIC_DISTORTION_CURRENT_PHASE_2 = (
112
+ PBMetric.METRIC_AC_TOTAL_HARMONIC_DISTORTION_CURRENT_PHASE_2
113
+ )
114
+ AC_TOTAL_HARMONIC_DISTORTION_CURRENT_PHASE_3 = (
115
+ PBMetric.METRIC_AC_TOTAL_HARMONIC_DISTORTION_CURRENT_PHASE_3
116
+ )
117
+
118
+ # General BMS metrics
119
+ BATTERY_CAPACITY = PBMetric.METRIC_BATTERY_CAPACITY
120
+ BATTERY_SOC_PCT = PBMetric.METRIC_BATTERY_SOC_PCT
121
+ BATTERY_TEMPERATURE = PBMetric.METRIC_BATTERY_TEMPERATURE
122
+
123
+ # General inverter metrics
124
+ INVERTER_TEMPERATURE = PBMetric.METRIC_INVERTER_TEMPERATURE
125
+ INVERTER_TEMPERATURE_CABINET = PBMetric.METRIC_INVERTER_TEMPERATURE_CABINET
126
+ INVERTER_TEMPERATURE_HEATSINK = PBMetric.METRIC_INVERTER_TEMPERATURE_HEATSINK
127
+ INVERTER_TEMPERATURE_TRANSFORMER = PBMetric.METRIC_INVERTER_TEMPERATURE_TRANSFORMER
128
+
129
+ # EV charging station metrics
130
+ EV_CHARGER_TEMPERATURE = PBMetric.METRIC_EV_CHARGER_TEMPERATURE
131
+
132
+ # General sensor metrics
133
+ SENSOR_WIND_SPEED = PBMetric.METRIC_SENSOR_WIND_SPEED
134
+ SENSOR_WIND_DIRECTION = PBMetric.METRIC_SENSOR_WIND_DIRECTION
135
+ SENSOR_TEMPERATURE = PBMetric.METRIC_SENSOR_TEMPERATURE
136
+ SENSOR_RELATIVE_HUMIDITY = PBMetric.METRIC_SENSOR_RELATIVE_HUMIDITY
137
+ SENSOR_DEW_POINT = PBMetric.METRIC_SENSOR_DEW_POINT
138
+ SENSOR_AIR_PRESSURE = PBMetric.METRIC_SENSOR_AIR_PRESSURE
139
+ SENSOR_IRRADIANCE = PBMetric.METRIC_SENSOR_IRRADIANCE
140
+
141
+ @classmethod
142
+ @deprecated("Use `frequenz.client.common.enum_proto.enum_from_proto` instead.")
143
+ def from_proto(cls, metric: PBMetric.ValueType) -> Self:
144
+ """Convert a protobuf Metric value to Metric enum.
145
+
146
+ Args:
147
+ metric: Metric to convert.
148
+ Returns:
149
+ Enum value corresponding to the protobuf message.
150
+ """
151
+ if not any(m.value == metric for m in cls):
152
+ return cls(Metric.UNSPECIFIED)
153
+
154
+ return cls(metric)
155
+
156
+ def to_proto(self) -> PBMetric.ValueType:
157
+ """Convert a Metric object to protobuf Metric.
158
+
159
+ Returns:
160
+ Protobuf message corresponding to the Metric object.
161
+ """
162
+ return self.value
@@ -0,0 +1,18 @@
1
+ # License: MIT
2
+ # Copyright © 2025 Frequenz Energy-as-a-Service GmbH
3
+
4
+ """Frequenz microgrid definition."""
5
+
6
+ from typing import final
7
+
8
+ from frequenz.core.id import BaseId
9
+
10
+
11
+ @final
12
+ class EnterpriseId(BaseId, str_prefix="EID"):
13
+ """A unique identifier for an enterprise account."""
14
+
15
+
16
+ @final
17
+ class MicrogridId(BaseId, str_prefix="MID"):
18
+ """A unique identifier for a microgrid."""
@@ -0,0 +1,459 @@
1
+ # License: MIT
2
+ # Copyright © 2022 Frequenz Energy-as-a-Service GmbH
3
+
4
+ """Defines the electrical components that can be used in a microgrid."""
5
+ from __future__ import annotations
6
+
7
+ import enum
8
+ from typing import final
9
+
10
+ # pylint: disable=no-name-in-module
11
+ from frequenz.api.common.v1alpha8.microgrid.electrical_components.electrical_components_pb2 import (
12
+ ElectricalComponentCategory as PBElectricalComponentCategory,
13
+ )
14
+ from frequenz.api.common.v1alpha8.microgrid.electrical_components.electrical_components_pb2 import (
15
+ ElectricalComponentDiagnosticCode as PBElectricalComponentDiagnosticCode,
16
+ )
17
+ from frequenz.api.common.v1alpha8.microgrid.electrical_components.electrical_components_pb2 import (
18
+ ElectricalComponentStateCode as PBElectricalComponentStateCode,
19
+ )
20
+ from frequenz.core.id import BaseId
21
+ from typing_extensions import deprecated
22
+
23
+ # pylint: enable=no-name-in-module
24
+
25
+
26
+ @final
27
+ class ElectricalComponentId(BaseId, str_prefix="CID"):
28
+ """A unique identifier for a microgrid electrical component."""
29
+
30
+
31
+ @enum.unique
32
+ class ElectricalComponentCategory(enum.Enum):
33
+ """Possible types of microgrid electrical component."""
34
+
35
+ UNSPECIFIED = (
36
+ PBElectricalComponentCategory.ELECTRICAL_COMPONENT_CATEGORY_UNSPECIFIED
37
+ )
38
+ """An unknown component category.
39
+
40
+ Useful for error handling, and marking unknown components in
41
+ a list of components with otherwise known categories.
42
+ """
43
+
44
+ GRID_CONNECTION_POINT = (
45
+ PBElectricalComponentCategory.ELECTRICAL_COMPONENT_CATEGORY_GRID_CONNECTION_POINT
46
+ )
47
+ """The point where the local microgrid is connected to the grid."""
48
+
49
+ METER = PBElectricalComponentCategory.ELECTRICAL_COMPONENT_CATEGORY_METER
50
+ """A meter, for measuring electrical metrics, e.g., current, voltage, etc."""
51
+
52
+ INVERTER = PBElectricalComponentCategory.ELECTRICAL_COMPONENT_CATEGORY_INVERTER
53
+ """An electricity generator, with batteries or solar energy."""
54
+
55
+ CONVERTER = PBElectricalComponentCategory.ELECTRICAL_COMPONENT_CATEGORY_CONVERTER
56
+ """An electricity converter, e.g., a DC-DC converter."""
57
+
58
+ BATTERY = PBElectricalComponentCategory.ELECTRICAL_COMPONENT_CATEGORY_BATTERY
59
+ """A storage system for electrical energy, used by inverters."""
60
+
61
+ EV_CHARGER = PBElectricalComponentCategory.ELECTRICAL_COMPONENT_CATEGORY_EV_CHARGER
62
+ """A station for charging electrical vehicles."""
63
+
64
+ CRYPTO_MINER = (
65
+ PBElectricalComponentCategory.ELECTRICAL_COMPONENT_CATEGORY_CRYPTO_MINER
66
+ )
67
+ """A device for mining cryptocurrencies."""
68
+
69
+ ELECTROLYZER = (
70
+ PBElectricalComponentCategory.ELECTRICAL_COMPONENT_CATEGORY_ELECTROLYZER
71
+ )
72
+ """A device for splitting water into hydrogen and oxygen using electricity."""
73
+
74
+ CHP = PBElectricalComponentCategory.ELECTRICAL_COMPONENT_CATEGORY_CHP
75
+ """A heat and power combustion plant (CHP stands for combined heat and power)."""
76
+
77
+ BREAKER = PBElectricalComponentCategory.ELECTRICAL_COMPONENT_CATEGORY_BREAKER
78
+ """A relay, used for switching electrical circuits on and off."""
79
+
80
+ PRECHARGER = PBElectricalComponentCategory.ELECTRICAL_COMPONENT_CATEGORY_PRECHARGER
81
+ """A precharger, used for preparing electrical circuits for switching on."""
82
+
83
+ POWER_TRANSFORMER = (
84
+ PBElectricalComponentCategory.ELECTRICAL_COMPONENT_CATEGORY_POWER_TRANSFORMER
85
+ )
86
+ """A transformer, used for changing the voltage of electrical circuits."""
87
+
88
+ HVAC = PBElectricalComponentCategory.ELECTRICAL_COMPONENT_CATEGORY_HVAC
89
+ """A heating, ventilation, and air conditioning (HVAC) system."""
90
+
91
+ @classmethod
92
+ @deprecated("Use `frequenz.client.common.enum_proto.enum_from_proto` instead.")
93
+ def from_proto(
94
+ cls, component_category: PBElectricalComponentCategory.ValueType
95
+ ) -> ElectricalComponentCategory:
96
+ """Convert a protobuf ElectricalComponentCategory message to enum.
97
+
98
+ Args:
99
+ component_category: protobuf enum to convert
100
+
101
+ Returns:
102
+ Enum value corresponding to the protobuf message.
103
+ """
104
+ if not any(t.value == component_category for t in ElectricalComponentCategory):
105
+ return ElectricalComponentCategory.UNSPECIFIED
106
+ return cls(component_category)
107
+
108
+ def to_proto(self) -> PBElectricalComponentCategory.ValueType:
109
+ """Convert a ElectricalComponentCategory enum to protobuf message.
110
+
111
+ Returns:
112
+ Enum value corresponding to the protobuf message.
113
+ """
114
+ return self.value
115
+
116
+
117
+ @enum.unique
118
+ class ElectricalComponentStateCode(enum.Enum):
119
+ """All possible states of a microgrid electrical component."""
120
+
121
+ UNSPECIFIED = (
122
+ PBElectricalComponentStateCode.ELECTRICAL_COMPONENT_STATE_CODE_UNSPECIFIED
123
+ )
124
+ """Default value when the component state is not explicitly set."""
125
+
126
+ UNKNOWN = PBElectricalComponentStateCode.ELECTRICAL_COMPONENT_STATE_CODE_UNKNOWN
127
+ """State when the component is in an unknown or undefined condition.
128
+
129
+ This is used when the sender is unable to classify the component into any
130
+ other state.
131
+ """
132
+
133
+ UNAVAILABLE = (
134
+ PBElectricalComponentStateCode.ELECTRICAL_COMPONENT_STATE_CODE_UNAVAILABLE
135
+ )
136
+ """State when the component is not available for use."""
137
+
138
+ SWITCHING_OFF = (
139
+ PBElectricalComponentStateCode.ELECTRICAL_COMPONENT_STATE_CODE_SWITCHING_OFF
140
+ )
141
+ """State when the component is in the process of switching off."""
142
+
143
+ OFF = PBElectricalComponentStateCode.ELECTRICAL_COMPONENT_STATE_CODE_OFF
144
+ """State when the component has successfully switched off."""
145
+
146
+ SWITCHING_ON = (
147
+ PBElectricalComponentStateCode.ELECTRICAL_COMPONENT_STATE_CODE_SWITCHING_ON
148
+ )
149
+ """State when the component is in the process of switching on from an off state."""
150
+
151
+ STANDBY = PBElectricalComponentStateCode.ELECTRICAL_COMPONENT_STATE_CODE_STANDBY
152
+ """State when the component is in standby mode, and not immediately ready for operation."""
153
+
154
+ READY = PBElectricalComponentStateCode.ELECTRICAL_COMPONENT_STATE_CODE_READY
155
+ """State when the component is fully operational and ready for use."""
156
+
157
+ CHARGING = PBElectricalComponentStateCode.ELECTRICAL_COMPONENT_STATE_CODE_CHARGING
158
+ """State when the component is actively consuming energy."""
159
+
160
+ DISCHARGING = (
161
+ PBElectricalComponentStateCode.ELECTRICAL_COMPONENT_STATE_CODE_DISCHARGING
162
+ )
163
+ """State when the component is actively producing or releasing energy."""
164
+
165
+ ERROR = PBElectricalComponentStateCode.ELECTRICAL_COMPONENT_STATE_CODE_ERROR
166
+ """State when the component is in an error state and may need attention."""
167
+
168
+ EV_CHARGING_CABLE_UNPLUGGED = (
169
+ PBElectricalComponentStateCode.ELECTRICAL_COMPONENT_STATE_CODE_EV_CHARGING_CABLE_UNPLUGGED
170
+ )
171
+ """The Electric Vehicle (EV) charging cable is unplugged from the charging station."""
172
+
173
+ EV_CHARGING_CABLE_PLUGGED_AT_STATION = (
174
+ PBElectricalComponentStateCode.ELECTRICAL_COMPONENT_STATE_CODE_EV_CHARGING_CABLE_PLUGGED_AT_STATION # noqa: E501
175
+ )
176
+ """The EV charging cable is plugged into the charging station."""
177
+
178
+ EV_CHARGING_CABLE_PLUGGED_AT_EV = (
179
+ PBElectricalComponentStateCode.ELECTRICAL_COMPONENT_STATE_CODE_EV_CHARGING_CABLE_PLUGGED_AT_EV # noqa: E501
180
+ )
181
+ """The EV charging cable is plugged into the vehicle."""
182
+
183
+ EV_CHARGING_CABLE_LOCKED_AT_STATION = (
184
+ PBElectricalComponentStateCode.ELECTRICAL_COMPONENT_STATE_CODE_EV_CHARGING_CABLE_LOCKED_AT_STATION # noqa: E501
185
+ )
186
+ """The EV charging cable is locked at the charging station end, indicating
187
+ readiness for charging."""
188
+
189
+ EV_CHARGING_CABLE_LOCKED_AT_EV = (
190
+ PBElectricalComponentStateCode.ELECTRICAL_COMPONENT_STATE_CODE_EV_CHARGING_CABLE_LOCKED_AT_EV # noqa: E501
191
+ )
192
+ """The EV charging cable is locked at the vehicle end, indicating that charging is active."""
193
+
194
+ RELAY_OPEN = (
195
+ PBElectricalComponentStateCode.ELECTRICAL_COMPONENT_STATE_CODE_RELAY_OPEN
196
+ )
197
+ """The relay is in an open state, meaning no current can flow through."""
198
+
199
+ RELAY_CLOSED = (
200
+ PBElectricalComponentStateCode.ELECTRICAL_COMPONENT_STATE_CODE_RELAY_CLOSED
201
+ )
202
+ """The relay is in a closed state, allowing current to flow."""
203
+
204
+ PRECHARGER_OPEN = (
205
+ PBElectricalComponentStateCode.ELECTRICAL_COMPONENT_STATE_CODE_PRECHARGER_OPEN
206
+ )
207
+ """The precharger circuit is open, meaning it's not currently active."""
208
+
209
+ PRECHARGER_PRECHARGING = (
210
+ PBElectricalComponentStateCode.ELECTRICAL_COMPONENT_STATE_CODE_PRECHARGER_PRECHARGING
211
+ )
212
+ """The precharger is in a precharging state, preparing the main circuit for activation."""
213
+
214
+ PRECHARGER_CLOSED = (
215
+ PBElectricalComponentStateCode.ELECTRICAL_COMPONENT_STATE_CODE_PRECHARGER_CLOSED
216
+ )
217
+ """The precharger circuit is closed, allowing full current to flow to the main circuit."""
218
+
219
+ @classmethod
220
+ @deprecated("Use `frequenz.client.common.enum_proto.enum_from_proto` instead.")
221
+ def from_proto(
222
+ cls, component_state: PBElectricalComponentStateCode.ValueType
223
+ ) -> ElectricalComponentStateCode:
224
+ """Convert a protobuf ElectricalComponentStateCode message to enum.
225
+
226
+ Args:
227
+ component_state: protobuf enum to convert
228
+
229
+ Returns:
230
+ Enum value corresponding to the protobuf message.
231
+ """
232
+ if not any(c.value == component_state for c in ElectricalComponentStateCode):
233
+ return ElectricalComponentStateCode.UNSPECIFIED
234
+ return cls(component_state)
235
+
236
+ def to_proto(self) -> PBElectricalComponentStateCode.ValueType:
237
+ """Convert a ElectricalComponentStateCode enum to protobuf message.
238
+
239
+ Returns:
240
+ Enum value corresponding to the protobuf message.
241
+ """
242
+ return self.value
243
+
244
+
245
+ @enum.unique
246
+ class ElectricalComponentDiagnosticCode(enum.Enum):
247
+ """All diagnostics that can occur across electrical component categories."""
248
+
249
+ UNSPECIFIED = (
250
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_UNSPECIFIED
251
+ )
252
+ """Default value. No specific error is specified."""
253
+
254
+ UNKNOWN = (
255
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_UNKNOWN
256
+ )
257
+ """The component is reporting an unknown or an undefined error, and the sender
258
+ cannot parse the component error to any of the variants below."""
259
+
260
+ SWITCH_ON_FAULT = (
261
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_SWITCH_ON_FAULT
262
+ )
263
+ """Error indicating that the component could not be switched on."""
264
+
265
+ UNDERVOLTAGE = (
266
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_UNDERVOLTAGE
267
+ )
268
+ """Error indicating that the component is operating under the minimum rated
269
+ voltage."""
270
+
271
+ OVERVOLTAGE = (
272
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_OVERVOLTAGE
273
+ )
274
+ """Error indicating that the component is operating over the maximum rated
275
+ voltage."""
276
+
277
+ OVERCURRENT = (
278
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_OVERCURRENT
279
+ )
280
+ """Error indicating that the component is drawing more current than the
281
+ maximum rated value."""
282
+
283
+ OVERCURRENT_CHARGING = (
284
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_OVERCURRENT_CHARGING # noqa: E501
285
+ )
286
+ """Error indicating that the component's consumption current is over the
287
+ maximum rated value during charging."""
288
+
289
+ OVERCURRENT_DISCHARGING = (
290
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_OVERCURRENT_DISCHARGING # noqa: E501
291
+ )
292
+ """Error indicating that the component's production current is over the
293
+ maximum rated value during discharging."""
294
+
295
+ OVERTEMPERATURE = (
296
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_OVERTEMPERATURE
297
+ )
298
+ """Error indicating that the component is operating over the maximum rated
299
+ temperature."""
300
+
301
+ UNDERTEMPERATURE = (
302
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_UNDERTEMPERATURE
303
+ )
304
+ """Error indicating that the component is operating under the minimum rated
305
+ temperature."""
306
+
307
+ HIGH_HUMIDITY = (
308
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_HIGH_HUMIDITY
309
+ )
310
+ """Error indicating that the component is exposed to high humidity levels over
311
+ the maximum rated value."""
312
+
313
+ FUSE_ERROR = (
314
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_FUSE_ERROR
315
+ )
316
+ """Error indicating that the component's fuse has blown."""
317
+
318
+ PRECHARGE_ERROR = (
319
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_PRECHARGE_ERROR
320
+ )
321
+ """Error indicating that the component's precharge unit has failed."""
322
+
323
+ PLAUSIBILITY_ERROR = (
324
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_PLAUSIBILITY_ERROR
325
+ )
326
+ """Error indicating plausibility issues within the system involving this
327
+ component."""
328
+
329
+ EV_UNEXPECTED_PILOT_FAILURE = (
330
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_EV_UNEXPECTED_PILOT_FAILURE # noqa: E501
331
+ )
332
+ """Error indicating unexpected pilot failure in an electric vehicle (EV)
333
+ component."""
334
+
335
+ FAULT_CURRENT = (
336
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_FAULT_CURRENT
337
+ )
338
+ """Error indicating fault current detected in the component."""
339
+
340
+ SHORT_CIRCUIT = (
341
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_SHORT_CIRCUIT
342
+ )
343
+ """Error indicating a short circuit detected in the component."""
344
+
345
+ CONFIG_ERROR = (
346
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_CONFIG_ERROR
347
+ )
348
+ """Error indicating a configuration error related to the component."""
349
+
350
+ ILLEGAL_COMPONENT_STATE_CODE_REQUESTED = (
351
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_ILLEGAL_COMPONENT_STATE_CODE_REQUESTED # noqa: E501
352
+ )
353
+ """Error indicating an illegal state requested for the component."""
354
+
355
+ HARDWARE_INACCESSIBLE = (
356
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_HARDWARE_INACCESSIBLE # noqa: E501
357
+ )
358
+ """Error indicating that the hardware of the component is inaccessible."""
359
+
360
+ INTERNAL = (
361
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_INTERNAL
362
+ )
363
+ """Error indicating an internal error within the component."""
364
+
365
+ UNAUTHORIZED = (
366
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_UNAUTHORIZED
367
+ )
368
+ """Error indicating that the component is unauthorized to perform the
369
+ last requested action."""
370
+
371
+ EV_CHARGING_CABLE_UNPLUGGED_FROM_STATION = (
372
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_EV_CHARGING_CABLE_UNPLUGGED_FROM_STATION # noqa: E501
373
+ )
374
+ """Error indicating electric vehicle (EV) cable was abruptly unplugged from
375
+ the charging station."""
376
+
377
+ EV_CHARGING_CABLE_UNPLUGGED_FROM_EV = (
378
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_EV_CHARGING_CABLE_UNPLUGGED_FROM_EV # noqa: E501
379
+ )
380
+ """Error indicating electric vehicle (EV) cable was abruptly unplugged from
381
+ the vehicle."""
382
+
383
+ EV_CHARGING_CABLE_LOCK_FAILED = (
384
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_EV_CHARGING_CABLE_LOCK_FAILED # noqa: E501
385
+ )
386
+ """Error indicating electric vehicle (EV) cable lock failure."""
387
+
388
+ EV_CHARGING_CABLE_INVALID = (
389
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_EV_CHARGING_CABLE_INVALID # noqa: E501
390
+ )
391
+ """Error indicating an invalid electric vehicle (EV) cable."""
392
+
393
+ EV_CONSUMER_INCOMPATIBLE = (
394
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_EV_CONSUMER_INCOMPATIBLE # noqa: E501
395
+ )
396
+ """Error indicating an incompatible electric vehicle (EV) plug."""
397
+
398
+ BATTERY_IMBALANCE = (
399
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_BATTERY_IMBALANCE
400
+ )
401
+ """Error indicating a battery system imbalance."""
402
+
403
+ BATTERY_LOW_SOH = (
404
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_BATTERY_LOW_SOH
405
+ )
406
+ """Error indicating a low state of health (SOH) detected in the battery."""
407
+
408
+ BATTERY_BLOCK_ERROR = (
409
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_BATTERY_BLOCK_ERROR
410
+ )
411
+ """Error indicating a battery block error."""
412
+
413
+ BATTERY_CONTROLLER_ERROR = (
414
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_BATTERY_CONTROLLER_ERROR # noqa: E501
415
+ )
416
+ """Error indicating a battery controller error."""
417
+
418
+ BATTERY_RELAY_ERROR = (
419
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_BATTERY_RELAY_ERROR
420
+ )
421
+ """Error indicating a battery relay error."""
422
+
423
+ BATTERY_CALIBRATION_NEEDED = (
424
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_BATTERY_CALIBRATION_NEEDED # noqa: E501
425
+ )
426
+ """Error indicating that battery calibration is needed."""
427
+
428
+ RELAY_CYCLE_LIMIT_REACHED = (
429
+ PBElectricalComponentDiagnosticCode.ELECTRICAL_COMPONENT_DIAGNOSTIC_CODE_RELAY_CYCLE_LIMIT_REACHED # noqa: E501
430
+ )
431
+ """Error indicating that the relays have been cycled for the maximum number of
432
+ times."""
433
+
434
+ @classmethod
435
+ @deprecated("Use `frequenz.client.common.enum_proto.enum_from_proto` instead.")
436
+ def from_proto(
437
+ cls, component_error_code: PBElectricalComponentDiagnosticCode.ValueType
438
+ ) -> ElectricalComponentDiagnosticCode:
439
+ """Convert a protobuf ElectricalComponentDiagnosticCode message to enum.
440
+
441
+ Args:
442
+ component_error_code: protobuf enum to convert
443
+
444
+ Returns:
445
+ Enum value corresponding to the protobuf message.
446
+ """
447
+ if not any(
448
+ c.value == component_error_code for c in ElectricalComponentDiagnosticCode
449
+ ):
450
+ return ElectricalComponentDiagnosticCode.UNSPECIFIED
451
+ return cls(component_error_code)
452
+
453
+ def to_proto(self) -> PBElectricalComponentDiagnosticCode.ValueType:
454
+ """Convert a ElectricalComponentDiagnosticCode enum to protobuf message.
455
+
456
+ Returns:
457
+ Enum value corresponding to the protobuf message.
458
+ """
459
+ return self.value
@@ -0,0 +1,13 @@
1
+ # License: MIT
2
+ # Copyright © 2025 Frequenz Energy-as-a-Service GmbH
3
+
4
+ """Microgrid sensors."""
5
+
6
+ from typing import final
7
+
8
+ from frequenz.core.id import BaseId
9
+
10
+
11
+ @final
12
+ class SensorId(BaseId, str_prefix="SID"):
13
+ """A unique identifier for a microgrid sensor."""
@@ -0,0 +1,91 @@
1
+ # License: MIT
2
+ # Copyright © 2024 Frequenz Energy-as-a-Service GmbH
3
+
4
+ """Module to define the pagination used with the common client."""
5
+
6
+ from __future__ import annotations # required for constructor type hinting
7
+
8
+ from dataclasses import dataclass
9
+ from typing import Self
10
+
11
+ # pylint: disable=no-name-in-module
12
+ from frequenz.api.common.v1alpha8.pagination.pagination_info_pb2 import (
13
+ PaginationInfo as PBPaginationInfo,
14
+ )
15
+ from frequenz.api.common.v1alpha8.pagination.pagination_params_pb2 import (
16
+ PaginationParams as PBPaginationParams,
17
+ )
18
+
19
+ # pylint: enable=no-name-in-module
20
+
21
+
22
+ @dataclass(frozen=True, kw_only=True)
23
+ class PaginationParams:
24
+ """Parameters for paginating list requests."""
25
+
26
+ page_size: int
27
+ """The maximum number of results to be returned per request."""
28
+
29
+ page_token: str
30
+ """The token identifying a specific page of the list results."""
31
+
32
+ @classmethod
33
+ def from_proto(cls, pagination_params: PBPaginationParams) -> Self:
34
+ """Convert a protobuf PaginationParams to python PaginationParams object.
35
+
36
+ Args:
37
+ pagination_params: Params to convert.
38
+ Returns:
39
+ Params object corresponding to the protobuf message.
40
+ """
41
+ return cls(
42
+ page_size=pagination_params.page_size,
43
+ page_token=pagination_params.page_token,
44
+ )
45
+
46
+ def to_proto(self) -> PBPaginationParams:
47
+ """Convert a Params object to protobuf PaginationParams.
48
+
49
+ Returns:
50
+ Protobuf message corresponding to the Params object.
51
+ """
52
+ return PBPaginationParams(
53
+ page_size=self.page_size,
54
+ page_token=self.page_token,
55
+ )
56
+
57
+
58
+ @dataclass(frozen=True, kw_only=True)
59
+ class PaginationInfo:
60
+ """Information about the pagination of a list request."""
61
+
62
+ total_items: int
63
+ """The total number of items that match the request."""
64
+
65
+ next_page_token: str | None = None
66
+ """The token identifying the next page of results."""
67
+
68
+ @classmethod
69
+ def from_proto(cls, pagination_info: PBPaginationInfo) -> Self:
70
+ """Convert a protobuf PBPaginationInfo to Info object.
71
+
72
+ Args:
73
+ pagination_info: Info to convert.
74
+ Returns:
75
+ Info object corresponding to the protobuf message.
76
+ """
77
+ return cls(
78
+ total_items=pagination_info.total_items,
79
+ next_page_token=pagination_info.next_page_token,
80
+ )
81
+
82
+ def to_proto(self) -> PBPaginationInfo:
83
+ """Convert a Info object to protobuf PBPaginationInfo.
84
+
85
+ Returns:
86
+ Protobuf message corresponding to the Info object.
87
+ """
88
+ return PBPaginationInfo(
89
+ total_items=self.total_items,
90
+ next_page_token=self.next_page_token,
91
+ )
@@ -0,0 +1,26 @@
1
+ # License: MIT
2
+ # Copyright © 2025 Frequenz Energy-as-a-Service GmbH
3
+
4
+ """Type wrappers for the generated protobuf messages."""
5
+
6
+
7
+ from enum import Enum
8
+
9
+ # pylint: disable-next=no-name-in-module
10
+ from frequenz.api.common.v1alpha8.streaming import event_pb2 as PBEvent
11
+
12
+
13
+ class Event(Enum):
14
+ """Enum representing the type of streaming event."""
15
+
16
+ EVENT_UNSPECIFIED = PBEvent.EVENT_UNSPECIFIED
17
+ """Unspecified event type."""
18
+
19
+ EVENT_CREATED = PBEvent.EVENT_CREATED
20
+ """Event when a new resource is created."""
21
+
22
+ EVENT_UPDATED = PBEvent.EVENT_UPDATED
23
+ """Event when an existing resource is updated."""
24
+
25
+ EVENT_DELETED = PBEvent.EVENT_DELETED
26
+ """Event when a resource is deleted."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: frequenz-client-common
3
- Version: 0.3.3
3
+ Version: 0.3.4
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
@@ -21,10 +21,10 @@ Requires-Python: <4,>=3.11
21
21
  Description-Content-Type: text/markdown
22
22
  License-File: LICENSE
23
23
  Requires-Dist: typing-extensions<5,>=4.13.0
24
- Requires-Dist: frequenz-api-common<7,>=0.6.1
24
+ Requires-Dist: frequenz-api-common<9,>=0.8.0
25
25
  Requires-Dist: frequenz-core<2,>=1.0.2
26
26
  Provides-Extra: dev-flake8
27
- Requires-Dist: flake8==7.2.0; extra == "dev-flake8"
27
+ Requires-Dist: flake8==7.3.0; extra == "dev-flake8"
28
28
  Requires-Dist: flake8-docstrings==1.7.0; extra == "dev-flake8"
29
29
  Requires-Dist: flake8-pyproject==1.2.3; extra == "dev-flake8"
30
30
  Requires-Dist: pydoclint==0.6.6; extra == "dev-flake8"
@@ -33,32 +33,32 @@ Provides-Extra: dev-formatting
33
33
  Requires-Dist: black==25.1.0; extra == "dev-formatting"
34
34
  Requires-Dist: isort==6.0.1; extra == "dev-formatting"
35
35
  Provides-Extra: dev-mkdocs
36
- Requires-Dist: Markdown==3.8; extra == "dev-mkdocs"
36
+ Requires-Dist: Markdown==3.8.2; extra == "dev-mkdocs"
37
37
  Requires-Dist: black==25.1.0; extra == "dev-mkdocs"
38
38
  Requires-Dist: mike==2.1.3; extra == "dev-mkdocs"
39
39
  Requires-Dist: mkdocs-gen-files==0.5.0; extra == "dev-mkdocs"
40
40
  Requires-Dist: mkdocs-literate-nav==0.6.2; extra == "dev-mkdocs"
41
41
  Requires-Dist: mkdocs-macros-plugin==1.3.7; extra == "dev-mkdocs"
42
- Requires-Dist: mkdocs-material==9.6.12; extra == "dev-mkdocs"
43
- Requires-Dist: mkdocstrings[python]==0.29.1; extra == "dev-mkdocs"
44
- Requires-Dist: mkdocstrings-python==1.16.10; extra == "dev-mkdocs"
45
- Requires-Dist: frequenz-repo-config[lib]==0.13.3; extra == "dev-mkdocs"
42
+ Requires-Dist: mkdocs-material==9.6.16; extra == "dev-mkdocs"
43
+ Requires-Dist: mkdocstrings[python]==0.30.0; extra == "dev-mkdocs"
44
+ Requires-Dist: mkdocstrings-python==1.16.12; extra == "dev-mkdocs"
45
+ Requires-Dist: frequenz-repo-config[lib]==0.13.5; extra == "dev-mkdocs"
46
46
  Provides-Extra: dev-mypy
47
- Requires-Dist: mypy==1.15.0; extra == "dev-mypy"
48
- Requires-Dist: types-Markdown==3.8.0.20250415; extra == "dev-mypy"
47
+ Requires-Dist: mypy==1.17.1; extra == "dev-mypy"
48
+ Requires-Dist: types-Markdown==3.8.0.20250708; extra == "dev-mypy"
49
49
  Requires-Dist: frequenz-client-common[dev-mkdocs,dev-noxfile,dev-pytest]; extra == "dev-mypy"
50
50
  Provides-Extra: dev-noxfile
51
51
  Requires-Dist: nox==2025.5.1; extra == "dev-noxfile"
52
- Requires-Dist: frequenz-repo-config[lib]==0.13.3; extra == "dev-noxfile"
52
+ Requires-Dist: frequenz-repo-config[lib]==0.13.5; extra == "dev-noxfile"
53
53
  Provides-Extra: dev-pylint
54
- Requires-Dist: pylint==3.3.6; extra == "dev-pylint"
54
+ Requires-Dist: pylint==3.3.7; extra == "dev-pylint"
55
55
  Requires-Dist: frequenz-client-common[dev-mkdocs,dev-noxfile,dev-pytest]; extra == "dev-pylint"
56
56
  Provides-Extra: dev-pytest
57
- Requires-Dist: pytest==8.3.5; extra == "dev-pytest"
58
- Requires-Dist: frequenz-repo-config[extra-lint-examples]==0.13.3; extra == "dev-pytest"
59
- Requires-Dist: pytest-mock==3.14.0; extra == "dev-pytest"
60
- Requires-Dist: pytest-asyncio==0.26.0; extra == "dev-pytest"
61
- Requires-Dist: async-solipsism==0.7; extra == "dev-pytest"
57
+ Requires-Dist: pytest==8.4.1; extra == "dev-pytest"
58
+ Requires-Dist: frequenz-repo-config[extra-lint-examples]==0.13.5; extra == "dev-pytest"
59
+ Requires-Dist: pytest-mock==3.14.1; extra == "dev-pytest"
60
+ Requires-Dist: pytest-asyncio==1.1.0; extra == "dev-pytest"
61
+ Requires-Dist: async-solipsism==0.8; extra == "dev-pytest"
62
62
  Provides-Extra: dev
63
63
  Requires-Dist: frequenz-client-common[dev-flake8,dev-formatting,dev-mkdocs,dev-mypy,dev-noxfile,dev-pylint,dev-pytest]; extra == "dev"
64
64
  Dynamic: license-file
@@ -12,6 +12,13 @@ src/frequenz/client/common/microgrid/__init__.py
12
12
  src/frequenz/client/common/microgrid/sensors.py
13
13
  src/frequenz/client/common/microgrid/components/__init__.py
14
14
  src/frequenz/client/common/pagination/__init__.py
15
+ src/frequenz/client/common/v1alpha8/__init__.py
16
+ src/frequenz/client/common/v1alpha8/metric/__init__.py
17
+ src/frequenz/client/common/v1alpha8/microgrid/__init__.py
18
+ src/frequenz/client/common/v1alpha8/microgrid/sensors.py
19
+ src/frequenz/client/common/v1alpha8/microgrid/electrical_components/__init__.py
20
+ src/frequenz/client/common/v1alpha8/pagination/__init__.py
21
+ src/frequenz/client/common/v1alpha8/streaming/__init__.py
15
22
  src/frequenz_client_common.egg-info/PKG-INFO
16
23
  src/frequenz_client_common.egg-info/SOURCES.txt
17
24
  src/frequenz_client_common.egg-info/dependency_links.txt
@@ -1,12 +1,12 @@
1
1
  typing-extensions<5,>=4.13.0
2
- frequenz-api-common<7,>=0.6.1
2
+ frequenz-api-common<9,>=0.8.0
3
3
  frequenz-core<2,>=1.0.2
4
4
 
5
5
  [dev]
6
6
  frequenz-client-common[dev-flake8,dev-formatting,dev-mkdocs,dev-mypy,dev-noxfile,dev-pylint,dev-pytest]
7
7
 
8
8
  [dev-flake8]
9
- flake8==7.2.0
9
+ flake8==7.3.0
10
10
  flake8-docstrings==1.7.0
11
11
  flake8-pyproject==1.2.3
12
12
  pydoclint==0.6.6
@@ -17,33 +17,33 @@ black==25.1.0
17
17
  isort==6.0.1
18
18
 
19
19
  [dev-mkdocs]
20
- Markdown==3.8
20
+ Markdown==3.8.2
21
21
  black==25.1.0
22
22
  mike==2.1.3
23
23
  mkdocs-gen-files==0.5.0
24
24
  mkdocs-literate-nav==0.6.2
25
25
  mkdocs-macros-plugin==1.3.7
26
- mkdocs-material==9.6.12
27
- mkdocstrings[python]==0.29.1
28
- mkdocstrings-python==1.16.10
29
- frequenz-repo-config[lib]==0.13.3
26
+ mkdocs-material==9.6.16
27
+ mkdocstrings[python]==0.30.0
28
+ mkdocstrings-python==1.16.12
29
+ frequenz-repo-config[lib]==0.13.5
30
30
 
31
31
  [dev-mypy]
32
- mypy==1.15.0
33
- types-Markdown==3.8.0.20250415
32
+ mypy==1.17.1
33
+ types-Markdown==3.8.0.20250708
34
34
  frequenz-client-common[dev-mkdocs,dev-noxfile,dev-pytest]
35
35
 
36
36
  [dev-noxfile]
37
37
  nox==2025.5.1
38
- frequenz-repo-config[lib]==0.13.3
38
+ frequenz-repo-config[lib]==0.13.5
39
39
 
40
40
  [dev-pylint]
41
- pylint==3.3.6
41
+ pylint==3.3.7
42
42
  frequenz-client-common[dev-mkdocs,dev-noxfile,dev-pytest]
43
43
 
44
44
  [dev-pytest]
45
- pytest==8.3.5
46
- frequenz-repo-config[extra-lint-examples]==0.13.3
47
- pytest-mock==3.14.0
48
- pytest-asyncio==0.26.0
49
- async-solipsism==0.7
45
+ pytest==8.4.1
46
+ frequenz-repo-config[extra-lint-examples]==0.13.5
47
+ pytest-mock==3.14.1
48
+ pytest-asyncio==1.1.0
49
+ async-solipsism==0.8
@@ -1,22 +0,0 @@
1
- # Frequenz Client Common Library Release Notes
2
-
3
- ## Summary
4
-
5
- <!-- Here goes a general summary of what this release is about -->
6
-
7
- ## Upgrading
8
-
9
- - The metrics and components enums `.from_proto()` are deprecated, please use the new `enum_from_proto()` instead.
10
- - Some minimum dependencies have been bumped, you might need to update your minimum dependencies too:
11
-
12
- * `frequenz-api-common` to 0.6.1
13
- * `frequenz-core` to 1.0.2
14
-
15
- ## New Features
16
-
17
- - A new module `frequenz.client.common.enum_proto` has been added, which provides a generic `enum_from_proto()` function to convert protobuf enums to Python enums.
18
- - The `frequenz.client.common.microgrid.ComponentCategory` was extended to include the missing categories.
19
-
20
- ## Bug Fixes
21
-
22
- <!-- Here goes notable bug fixes that are worth a special mention or explanation -->