frequenz-client-common 0.2.0__tar.gz → 0.3.0__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 (21) hide show
  1. {frequenz-client-common-0.2.0/src/frequenz_client_common.egg-info → frequenz_client_common-0.3.0}/PKG-INFO +34 -2
  2. frequenz_client_common-0.3.0/RELEASE_NOTES.md +19 -0
  3. {frequenz-client-common-0.2.0 → frequenz_client_common-0.3.0}/pyproject.toml +30 -22
  4. {frequenz-client-common-0.2.0 → frequenz_client_common-0.3.0}/src/frequenz/client/common/metric/__init__.py +13 -2
  5. frequenz_client_common-0.3.0/src/frequenz/client/common/microgrid/components/__init__.py +354 -0
  6. {frequenz-client-common-0.2.0 → frequenz_client_common-0.3.0}/src/frequenz/client/common/pagination/__init__.py +2 -2
  7. {frequenz-client-common-0.2.0 → frequenz_client_common-0.3.0/src/frequenz_client_common.egg-info}/PKG-INFO +34 -2
  8. {frequenz-client-common-0.2.0 → frequenz_client_common-0.3.0}/src/frequenz_client_common.egg-info/requires.txt +20 -19
  9. frequenz-client-common-0.2.0/RELEASE_NOTES.md +0 -5
  10. frequenz-client-common-0.2.0/src/frequenz/client/common/microgrid/components/__init__.py +0 -67
  11. {frequenz-client-common-0.2.0 → frequenz_client_common-0.3.0}/LICENSE +0 -0
  12. {frequenz-client-common-0.2.0 → frequenz_client_common-0.3.0}/MANIFEST.in +0 -0
  13. {frequenz-client-common-0.2.0 → frequenz_client_common-0.3.0}/README.md +0 -0
  14. {frequenz-client-common-0.2.0 → frequenz_client_common-0.3.0}/setup.cfg +0 -0
  15. {frequenz-client-common-0.2.0 → frequenz_client_common-0.3.0}/src/frequenz/client/common/__init__.py +0 -0
  16. {frequenz-client-common-0.2.0 → frequenz_client_common-0.3.0}/src/frequenz/client/common/conftest.py +0 -0
  17. {frequenz-client-common-0.2.0 → frequenz_client_common-0.3.0}/src/frequenz/client/common/microgrid/__init__.py +0 -0
  18. {frequenz-client-common-0.2.0 → frequenz_client_common-0.3.0}/src/frequenz/client/common/py.typed +0 -0
  19. {frequenz-client-common-0.2.0 → frequenz_client_common-0.3.0}/src/frequenz_client_common.egg-info/SOURCES.txt +0 -0
  20. {frequenz-client-common-0.2.0 → frequenz_client_common-0.3.0}/src/frequenz_client_common.egg-info/dependency_links.txt +0 -0
  21. {frequenz-client-common-0.2.0 → frequenz_client_common-0.3.0}/src/frequenz_client_common.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: frequenz-client-common
3
- Version: 0.2.0
3
+ Version: 0.3.0
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
@@ -19,15 +19,47 @@ Classifier: Topic :: Software Development :: Libraries
19
19
  Classifier: Typing :: Typed
20
20
  Requires-Python: <4,>=3.11
21
21
  Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: typing-extensions<5,>=4.5.0
24
+ Requires-Dist: frequenz-api-common<7,>=0.6.0
22
25
  Provides-Extra: dev-flake8
26
+ Requires-Dist: flake8==7.1.1; extra == "dev-flake8"
27
+ Requires-Dist: flake8-docstrings==1.7.0; extra == "dev-flake8"
28
+ Requires-Dist: flake8-pyproject==1.2.3; extra == "dev-flake8"
29
+ Requires-Dist: pydoclint==0.5.9; extra == "dev-flake8"
30
+ Requires-Dist: pydocstyle==6.3.0; extra == "dev-flake8"
23
31
  Provides-Extra: dev-formatting
32
+ Requires-Dist: black==24.10.0; extra == "dev-formatting"
33
+ Requires-Dist: isort==5.13.2; extra == "dev-formatting"
24
34
  Provides-Extra: dev-mkdocs
35
+ Requires-Dist: black==24.10.0; extra == "dev-mkdocs"
36
+ Requires-Dist: Markdown==3.7; extra == "dev-mkdocs"
37
+ Requires-Dist: mike==2.1.3; extra == "dev-mkdocs"
38
+ Requires-Dist: mkdocs-gen-files==0.5.0; extra == "dev-mkdocs"
39
+ Requires-Dist: mkdocs-literate-nav==0.6.1; extra == "dev-mkdocs"
40
+ Requires-Dist: mkdocs-macros-plugin==1.3.7; extra == "dev-mkdocs"
41
+ Requires-Dist: mkdocs-material==9.5.47; extra == "dev-mkdocs"
42
+ Requires-Dist: mkdocstrings[python]==0.27.0; extra == "dev-mkdocs"
43
+ Requires-Dist: mkdocstrings-python==1.12.2; extra == "dev-mkdocs"
44
+ Requires-Dist: frequenz-repo-config[lib]==0.11.0; extra == "dev-mkdocs"
25
45
  Provides-Extra: dev-mypy
46
+ Requires-Dist: mypy==1.13.0; extra == "dev-mypy"
47
+ Requires-Dist: types-Markdown==3.7.0.20241204; extra == "dev-mypy"
48
+ Requires-Dist: frequenz-client-common[dev-mkdocs,dev-noxfile,dev-pytest]; extra == "dev-mypy"
26
49
  Provides-Extra: dev-noxfile
50
+ Requires-Dist: nox==2024.10.9; extra == "dev-noxfile"
51
+ Requires-Dist: frequenz-repo-config[lib]==0.11.0; extra == "dev-noxfile"
27
52
  Provides-Extra: dev-pylint
53
+ Requires-Dist: pylint==3.3.2; extra == "dev-pylint"
54
+ Requires-Dist: frequenz-client-common[dev-mkdocs,dev-noxfile,dev-pytest]; extra == "dev-pylint"
28
55
  Provides-Extra: dev-pytest
56
+ Requires-Dist: pytest==8.3.4; extra == "dev-pytest"
57
+ Requires-Dist: frequenz-repo-config[extra-lint-examples]==0.11.0; extra == "dev-pytest"
58
+ Requires-Dist: pytest-mock==3.14.0; extra == "dev-pytest"
59
+ Requires-Dist: pytest-asyncio==0.24.0; extra == "dev-pytest"
60
+ Requires-Dist: async-solipsism==0.7; extra == "dev-pytest"
29
61
  Provides-Extra: dev
30
- License-File: LICENSE
62
+ Requires-Dist: frequenz-client-common[dev-flake8,dev-formatting,dev-mkdocs,dev-mypy,dev-noxfile,dev-pylint,dev-pytest]; extra == "dev"
31
63
 
32
64
  # Frequenz Client Common Library
33
65
 
@@ -0,0 +1,19 @@
1
+ # Frequenz Client Common Library Release Notes
2
+
3
+ ## Summary
4
+
5
+ Update of the Pagination `Params` data class.
6
+
7
+ ## Upgrading
8
+
9
+ * Pagination `Params` has been changed such that the `page_size` and `page_token` fields are now no longer optional.
10
+
11
+ ## New Features
12
+
13
+ * Additional information for energy metric.
14
+ * Add component state codes.
15
+ * Add component error codes.
16
+
17
+ ## Bug Fixes
18
+
19
+ <!-- Here goes notable bug fixes that are worth a special mention or explanation -->
@@ -3,9 +3,9 @@
3
3
 
4
4
  [build-system]
5
5
  requires = [
6
- "setuptools == 68.1.0",
7
- "setuptools_scm[toml] == 7.1.0",
8
- "frequenz-repo-config[lib] == 0.9.1",
6
+ "setuptools == 75.6.0",
7
+ "setuptools_scm[toml] == 8.1.0",
8
+ "frequenz-repo-config[lib] == 0.11.0",
9
9
  ]
10
10
  build-backend = "setuptools.build_meta"
11
11
 
@@ -37,45 +37,46 @@ email = "floss@frequenz.com"
37
37
 
38
38
  [project.optional-dependencies]
39
39
  dev-flake8 = [
40
- "flake8 == 7.0.0",
40
+ "flake8 == 7.1.1",
41
41
  "flake8-docstrings == 1.7.0",
42
42
  "flake8-pyproject == 1.2.3", # For reading the flake8 config from pyproject.toml
43
- "pydoclint == 0.4.1",
43
+ "pydoclint == 0.5.9",
44
44
  "pydocstyle == 6.3.0",
45
45
  ]
46
- dev-formatting = ["black == 24.4.2", "isort == 5.13.2"]
46
+ dev-formatting = ["black == 24.10.0", "isort == 5.13.2"]
47
47
  dev-mkdocs = [
48
- "black == 24.4.2",
49
- "Markdown==3.6",
50
- "mike == 2.0.0",
48
+ "black == 24.10.0",
49
+ "Markdown==3.7",
50
+ "mike == 2.1.3",
51
51
  "mkdocs-gen-files == 0.5.0",
52
52
  "mkdocs-literate-nav == 0.6.1",
53
- "mkdocs-macros-plugin == 1.0.5",
54
- "mkdocs-material == 9.5.20",
55
- "mkdocstrings[python] == 0.25.0",
56
- "frequenz-repo-config[lib] == 0.9.1",
53
+ "mkdocs-macros-plugin == 1.3.7",
54
+ "mkdocs-material == 9.5.47",
55
+ "mkdocstrings[python] == 0.27.0",
56
+ "mkdocstrings-python == 1.12.2",
57
+ "frequenz-repo-config[lib] == 0.11.0",
57
58
  ]
58
59
  dev-mypy = [
59
- "mypy == 1.10.0",
60
- "types-Markdown == 3.6.0.20240316",
60
+ "mypy == 1.13.0",
61
+ "types-Markdown == 3.7.0.20241204",
61
62
  # For checking the noxfile, docs/ script, and tests
62
63
  "frequenz-client-common[dev-mkdocs,dev-noxfile,dev-pytest]",
63
64
  ]
64
65
  dev-noxfile = [
65
- "nox == 2024.4.15",
66
- "frequenz-repo-config[lib] == 0.9.1",
66
+ "nox == 2024.10.9",
67
+ "frequenz-repo-config[lib] == 0.11.0",
67
68
  ]
68
69
  dev-pylint = [
69
- "pylint == 3.1.0",
70
+ "pylint == 3.3.2",
70
71
  # For checking the noxfile, docs/ script, and tests
71
72
  "frequenz-client-common[dev-mkdocs,dev-noxfile,dev-pytest]",
72
73
  ]
73
74
  dev-pytest = [
74
- "pytest == 8.2.0",
75
- "frequenz-repo-config[extra-lint-examples] == 0.9.1",
75
+ "pytest == 8.3.4",
76
+ "frequenz-repo-config[extra-lint-examples] == 0.11.0",
76
77
  "pytest-mock == 3.14.0",
77
- "pytest-asyncio == 0.23.6",
78
- "async-solipsism == 0.6",
78
+ "pytest-asyncio == 0.24.0",
79
+ "async-solipsism == 0.7",
79
80
  ]
80
81
  dev = [
81
82
  "frequenz-client-common[dev-mkdocs,dev-flake8,dev-formatting,dev-mkdocs,dev-mypy,dev-noxfile,dev-pylint,dev-pytest]",
@@ -131,10 +132,16 @@ disable = [
131
132
  # pylint's unsubscriptable check is buggy and is not needed because
132
133
  # it is a type-check, for which we already have mypy.
133
134
  "unsubscriptable-object",
135
+ # Checked by mypy
136
+ "no-member",
137
+ "possibly-used-before-assignment",
138
+ "no-name-in-module",
134
139
  # Checked by flake8
140
+ "f-string-without-interpolation",
135
141
  "redefined-outer-name",
136
142
  "unused-import",
137
143
  "line-too-long",
144
+ "missing-function-docstring",
138
145
  "unused-variable",
139
146
  "unnecessary-lambda-assignment",
140
147
  ]
@@ -142,6 +149,7 @@ disable = [
142
149
  [tool.pytest.ini_options]
143
150
  testpaths = ["tests", "src"]
144
151
  asyncio_mode = "auto"
152
+ asyncio_default_fixture_loop_scope = "function"
145
153
  required_plugins = ["pytest-asyncio", "pytest-mock"]
146
154
 
147
155
  [tool.mypy]
@@ -13,7 +13,18 @@ from frequenz.api.common.v1.metrics.metric_sample_pb2 import Metric as PBMetric
13
13
 
14
14
 
15
15
  class Metric(Enum):
16
- """List of supported metrics."""
16
+ """List of supported metrics.
17
+
18
+ AC energy metrics information:
19
+ * This energy metric is reported directly from the component, and not a
20
+ result of aggregations in our systems. If a component does not have this
21
+ metric, this field cannot be populated.
22
+ * Components that provide energy metrics reset this metric from time to
23
+ time. This behaviour is specific to each component model. E.g., some
24
+ components reset it on UTC 00:00:00.
25
+ * This energy metric does not specify the timestamp since when the energy
26
+ was being accumulated, and therefore can be inconsistent.
27
+ """
17
28
 
18
29
  # Default value
19
30
  UNSPECIFIED = PBMetric.METRIC_UNSPECIFIED
@@ -57,7 +68,7 @@ class Metric(Enum):
57
68
  AC_POWER_FACTOR_PHASE_2 = PBMetric.METRIC_AC_POWER_FACTOR_PHASE_2
58
69
  AC_POWER_FACTOR_PHASE_3 = PBMetric.METRIC_AC_POWER_FACTOR_PHASE_3
59
70
 
60
- # AC energy metrics
71
+ # AC energy metrics - Please be careful when using and check Enum docs
61
72
  AC_APPARENT_ENERGY = PBMetric.METRIC_AC_APPARENT_ENERGY
62
73
  AC_APPARENT_ENERGY_PHASE_1 = PBMetric.METRIC_AC_APPARENT_ENERGY_PHASE_1
63
74
  AC_APPARENT_ENERGY_PHASE_2 = PBMetric.METRIC_AC_APPARENT_ENERGY_PHASE_2
@@ -0,0 +1,354 @@
1
+ # License: MIT
2
+ # Copyright © 2022 Frequenz Energy-as-a-Service GmbH
3
+
4
+ """Defines the components that can be used in a microgrid."""
5
+ from __future__ import annotations
6
+
7
+ from enum import Enum
8
+
9
+ # pylint: disable=no-name-in-module
10
+ from frequenz.api.common.v1.microgrid.components.components_pb2 import (
11
+ ComponentCategory as PBComponentCategory,
12
+ )
13
+ from frequenz.api.common.v1.microgrid.components.components_pb2 import (
14
+ ComponentErrorCode as PBComponentErrorCode,
15
+ )
16
+ from frequenz.api.common.v1.microgrid.components.components_pb2 import (
17
+ ComponentStateCode as PBComponentStateCode,
18
+ )
19
+
20
+ # pylint: enable=no-name-in-module
21
+
22
+
23
+ class ComponentCategory(Enum):
24
+ """Possible types of microgrid component."""
25
+
26
+ UNSPECIFIED = PBComponentCategory.COMPONENT_CATEGORY_UNSPECIFIED
27
+ """An unknown component category.
28
+
29
+ Useful for error handling, and marking unknown components in
30
+ a list of components with otherwise known categories.
31
+ """
32
+
33
+ GRID = PBComponentCategory.COMPONENT_CATEGORY_GRID
34
+ """The point where the local microgrid is connected to the grid."""
35
+
36
+ METER = PBComponentCategory.COMPONENT_CATEGORY_METER
37
+ """A meter, for measuring electrical metrics, e.g., current, voltage, etc."""
38
+
39
+ INVERTER = PBComponentCategory.COMPONENT_CATEGORY_INVERTER
40
+ """An electricity generator, with batteries or solar energy."""
41
+
42
+ BATTERY = PBComponentCategory.COMPONENT_CATEGORY_BATTERY
43
+ """A storage system for electrical energy, used by inverters."""
44
+
45
+ EV_CHARGER = PBComponentCategory.COMPONENT_CATEGORY_EV_CHARGER
46
+ """A station for charging electrical vehicles."""
47
+
48
+ CHP = PBComponentCategory.COMPONENT_CATEGORY_CHP
49
+ """A heat and power combustion plant (CHP stands for combined heat and power)."""
50
+
51
+ @classmethod
52
+ def from_proto(
53
+ cls, component_category: PBComponentCategory.ValueType
54
+ ) -> ComponentCategory:
55
+ """Convert a protobuf ComponentCategory message to ComponentCategory enum.
56
+
57
+ Args:
58
+ component_category: protobuf enum to convert
59
+
60
+ Returns:
61
+ Enum value corresponding to the protobuf message.
62
+ """
63
+ if not any(t.value == component_category for t in ComponentCategory):
64
+ return ComponentCategory.UNSPECIFIED
65
+ return cls(component_category)
66
+
67
+ def to_proto(self) -> PBComponentCategory.ValueType:
68
+ """Convert a ComponentCategory enum to protobuf ComponentCategory message.
69
+
70
+ Returns:
71
+ Enum value corresponding to the protobuf message.
72
+ """
73
+ return self.value
74
+
75
+
76
+ class ComponentStateCode(Enum):
77
+ """All possible states of a microgrid component."""
78
+
79
+ UNSPECIFIED = PBComponentStateCode.COMPONENT_STATE_CODE_UNSPECIFIED
80
+ """Default value when the component state is not explicitly set."""
81
+
82
+ UNKNOWN = PBComponentStateCode.COMPONENT_STATE_CODE_UNKNOWN
83
+ """State when the component is in an unknown or undefined condition.
84
+
85
+ This is used when the sender is unable to classify the component into any
86
+ other state.
87
+ """
88
+ SWITCHING_OFF = PBComponentStateCode.COMPONENT_STATE_CODE_SWITCHING_OFF
89
+ """State when the component is in the process of switching off."""
90
+
91
+ OFF = PBComponentStateCode.COMPONENT_STATE_CODE_OFF
92
+ """State when the component has successfully switched off."""
93
+
94
+ SWITCHING_ON = PBComponentStateCode.COMPONENT_STATE_CODE_SWITCHING_ON
95
+ """State when the component is in the process of switching on from an off state."""
96
+
97
+ STANDBY = PBComponentStateCode.COMPONENT_STATE_CODE_STANDBY
98
+ """State when the component is in standby mode, and not immediately ready for operation."""
99
+
100
+ READY = PBComponentStateCode.COMPONENT_STATE_CODE_READY
101
+ """State when the component is fully operational and ready for use."""
102
+
103
+ CHARGING = PBComponentStateCode.COMPONENT_STATE_CODE_CHARGING
104
+ """State when the component is actively consuming energy."""
105
+
106
+ DISCHARGING = PBComponentStateCode.COMPONENT_STATE_CODE_DISCHARGING
107
+ """State when the component is actively producing or releasing energy."""
108
+
109
+ ERROR = PBComponentStateCode.COMPONENT_STATE_CODE_ERROR
110
+ """State when the component is in an error state and may need attention."""
111
+
112
+ EV_CHARGING_CABLE_UNPLUGGED = (
113
+ PBComponentStateCode.COMPONENT_STATE_CODE_EV_CHARGING_CABLE_UNPLUGGED
114
+ )
115
+ """The Electric Vehicle (EV) charging cable is unplugged from the charging station."""
116
+
117
+ EV_CHARGING_CABLE_PLUGGED_AT_STATION = (
118
+ PBComponentStateCode.COMPONENT_STATE_CODE_EV_CHARGING_CABLE_PLUGGED_AT_STATION
119
+ )
120
+ """The EV charging cable is plugged into the charging station."""
121
+
122
+ EV_CHARGING_CABLE_PLUGGED_AT_EV = (
123
+ PBComponentStateCode.COMPONENT_STATE_CODE_EV_CHARGING_CABLE_PLUGGED_AT_EV
124
+ )
125
+ """The EV charging cable is plugged into the vehicle."""
126
+
127
+ EV_CHARGING_CABLE_LOCKED_AT_STATION = (
128
+ PBComponentStateCode.COMPONENT_STATE_CODE_EV_CHARGING_CABLE_LOCKED_AT_STATION
129
+ )
130
+ """The EV charging cable is locked at the charging station end, indicating
131
+ readiness for charging."""
132
+
133
+ EV_CHARGING_CABLE_LOCKED_AT_EV = (
134
+ PBComponentStateCode.COMPONENT_STATE_CODE_EV_CHARGING_CABLE_LOCKED_AT_EV
135
+ )
136
+ """The EV charging cable is locked at the vehicle end, indicating that charging is active."""
137
+
138
+ RELAY_OPEN = PBComponentStateCode.COMPONENT_STATE_CODE_RELAY_OPEN
139
+ """The relay is in an open state, meaning no current can flow through."""
140
+
141
+ RELAY_CLOSED = PBComponentStateCode.COMPONENT_STATE_CODE_RELAY_CLOSED
142
+ """The relay is in a closed state, allowing current to flow."""
143
+
144
+ PRECHARGER_OPEN = PBComponentStateCode.COMPONENT_STATE_CODE_PRECHARGER_OPEN
145
+ """The precharger circuit is open, meaning it's not currently active."""
146
+
147
+ PRECHARGER_PRECHARGING = (
148
+ PBComponentStateCode.COMPONENT_STATE_CODE_PRECHARGER_PRECHARGING
149
+ )
150
+ """The precharger is in a precharging state, preparing the main circuit for activation."""
151
+
152
+ PRECHARGER_CLOSED = PBComponentStateCode.COMPONENT_STATE_CODE_PRECHARGER_CLOSED
153
+ """The precharger circuit is closed, allowing full current to flow to the main circuit."""
154
+
155
+ @classmethod
156
+ def from_proto(
157
+ cls, component_state: PBComponentStateCode.ValueType
158
+ ) -> ComponentStateCode:
159
+ """Convert a protobuf ComponentStateCode message to ComponentStateCode enum.
160
+
161
+ Args:
162
+ component_state: protobuf enum to convert
163
+
164
+ Returns:
165
+ Enum value corresponding to the protobuf message.
166
+ """
167
+ if not any(c.value == component_state for c in ComponentStateCode):
168
+ return ComponentStateCode.UNSPECIFIED
169
+ return cls(component_state)
170
+
171
+ def to_proto(self) -> PBComponentStateCode.ValueType:
172
+ """Convert a ComponentStateCode enum to protobuf ComponentStateCode message.
173
+
174
+ Returns:
175
+ Enum value corresponding to the protobuf message.
176
+ """
177
+ return self.value
178
+
179
+
180
+ class ComponentErrorCode(Enum):
181
+ """All possible errors that can occur across all microgrid component categories."""
182
+
183
+ UNSPECIFIED = PBComponentErrorCode.COMPONENT_ERROR_CODE_UNSPECIFIED
184
+ """Default value. No specific error is specified."""
185
+
186
+ UNKNOWN = PBComponentErrorCode.COMPONENT_ERROR_CODE_UNKNOWN
187
+ """The component is reporting an unknown or an undefined error, and the sender
188
+ cannot parse the component error to any of the variants below."""
189
+
190
+ SWITCH_ON_FAULT = PBComponentErrorCode.COMPONENT_ERROR_CODE_SWITCH_ON_FAULT
191
+ """Error indicating that the component could not be switched on."""
192
+
193
+ UNDERVOLTAGE = PBComponentErrorCode.COMPONENT_ERROR_CODE_UNDERVOLTAGE
194
+ """Error indicating that the component is operating under the minimum rated
195
+ voltage."""
196
+
197
+ OVERVOLTAGE = PBComponentErrorCode.COMPONENT_ERROR_CODE_OVERVOLTAGE
198
+ """Error indicating that the component is operating over the maximum rated
199
+ voltage."""
200
+
201
+ OVERCURRENT = PBComponentErrorCode.COMPONENT_ERROR_CODE_OVERCURRENT
202
+ """Error indicating that the component is drawing more current than the
203
+ maximum rated value."""
204
+
205
+ OVERCURRENT_CHARGING = (
206
+ PBComponentErrorCode.COMPONENT_ERROR_CODE_OVERCURRENT_CHARGING
207
+ )
208
+ """Error indicating that the component's consumption current is over the
209
+ maximum rated value during charging."""
210
+
211
+ OVERCURRENT_DISCHARGING = (
212
+ PBComponentErrorCode.COMPONENT_ERROR_CODE_OVERCURRENT_DISCHARGING
213
+ )
214
+ """Error indicating that the component's production current is over the
215
+ maximum rated value during discharging."""
216
+
217
+ OVERTEMPERATURE = PBComponentErrorCode.COMPONENT_ERROR_CODE_OVERTEMPERATURE
218
+ """Error indicating that the component is operating over the maximum rated
219
+ temperature."""
220
+
221
+ UNDERTEMPERATURE = PBComponentErrorCode.COMPONENT_ERROR_CODE_UNDERTEMPERATURE
222
+ """Error indicating that the component is operating under the minimum rated
223
+ temperature."""
224
+
225
+ HIGH_HUMIDITY = PBComponentErrorCode.COMPONENT_ERROR_CODE_HIGH_HUMIDITY
226
+ """Error indicating that the component is exposed to high humidity levels over
227
+ the maximum rated value."""
228
+
229
+ FUSE_ERROR = PBComponentErrorCode.COMPONENT_ERROR_CODE_FUSE_ERROR
230
+ """Error indicating that the component's fuse has blown."""
231
+
232
+ PRECHARGE_ERROR = PBComponentErrorCode.COMPONENT_ERROR_CODE_PRECHARGE_ERROR
233
+ """Error indicating that the component's precharge unit has failed."""
234
+
235
+ PLAUSIBILITY_ERROR = PBComponentErrorCode.COMPONENT_ERROR_CODE_PLAUSIBILITY_ERROR
236
+ """Error indicating plausibility issues within the system involving this
237
+ component."""
238
+
239
+ UNDERVOLTAGE_SHUTDOWN = (
240
+ PBComponentErrorCode.COMPONENT_ERROR_CODE_UNDERVOLTAGE_SHUTDOWN
241
+ )
242
+ """Error indicating system shutdown due to undervoltage involving this
243
+ component."""
244
+
245
+ EV_UNEXPECTED_PILOT_FAILURE = (
246
+ PBComponentErrorCode.COMPONENT_ERROR_CODE_EV_UNEXPECTED_PILOT_FAILURE
247
+ )
248
+ """Error indicating unexpected pilot failure in an electric vehicle (EV)
249
+ component."""
250
+
251
+ FAULT_CURRENT = PBComponentErrorCode.COMPONENT_ERROR_CODE_FAULT_CURRENT
252
+ """Error indicating fault current detected in the component."""
253
+
254
+ SHORT_CIRCUIT = PBComponentErrorCode.COMPONENT_ERROR_CODE_SHORT_CIRCUIT
255
+ """Error indicating a short circuit detected in the component."""
256
+
257
+ CONFIG_ERROR = PBComponentErrorCode.COMPONENT_ERROR_CODE_CONFIG_ERROR
258
+ """Error indicating a configuration error related to the component."""
259
+
260
+ ILLEGAL_COMPONENT_STATE_CODE_REQUESTED = (
261
+ PBComponentErrorCode.COMPONENT_ERROR_CODE_ILLEGAL_COMPONENT_STATE_CODE_REQUESTED
262
+ )
263
+ """Error indicating an illegal state requested for the component."""
264
+
265
+ HARDWARE_INACCESSIBLE = (
266
+ PBComponentErrorCode.COMPONENT_ERROR_CODE_HARDWARE_INACCESSIBLE
267
+ )
268
+ """Error indicating that the hardware of the component is inaccessible."""
269
+
270
+ INTERNAL = PBComponentErrorCode.COMPONENT_ERROR_CODE_INTERNAL
271
+ """Error indicating an internal error within the component."""
272
+
273
+ UNAUTHORIZED = PBComponentErrorCode.COMPONENT_ERROR_CODE_UNAUTHORIZED
274
+ """Error indicating that the component is unauthorized to perform the
275
+ last requested action."""
276
+
277
+ EV_CHARGING_CABLE_UNPLUGGED_FROM_STATION = (
278
+ PBComponentErrorCode.COMPONENT_ERROR_CODE_EV_CHARGING_CABLE_UNPLUGGED_FROM_STATION
279
+ )
280
+ """Error indicating electric vehicle (EV) cable was abruptly unplugged from
281
+ the charging station."""
282
+
283
+ EV_CHARGING_CABLE_UNPLUGGED_FROM_EV = (
284
+ PBComponentErrorCode.COMPONENT_ERROR_CODE_EV_CHARGING_CABLE_UNPLUGGED_FROM_EV
285
+ )
286
+ """Error indicating electric vehicle (EV) cable was abruptly unplugged from
287
+ the vehicle."""
288
+
289
+ EV_CHARGING_CABLE_LOCK_FAILED = (
290
+ PBComponentErrorCode.COMPONENT_ERROR_CODE_EV_CHARGING_CABLE_LOCK_FAILED
291
+ )
292
+ """Error indicating electric vehicle (EV) cable lock failure."""
293
+
294
+ EV_CHARGING_CABLE_INVALID = (
295
+ PBComponentErrorCode.COMPONENT_ERROR_CODE_EV_CHARGING_CABLE_INVALID
296
+ )
297
+ """Error indicating an invalid electric vehicle (EV) cable."""
298
+
299
+ EV_CONSUMER_INCOMPATIBLE = (
300
+ PBComponentErrorCode.COMPONENT_ERROR_CODE_EV_CONSUMER_INCOMPATIBLE
301
+ )
302
+ """Error indicating an incompatible electric vehicle (EV) plug."""
303
+
304
+ BATTERY_IMBALANCE = PBComponentErrorCode.COMPONENT_ERROR_CODE_BATTERY_IMBALANCE
305
+ """Error indicating a battery system imbalance."""
306
+
307
+ BATTERY_LOW_SOH = PBComponentErrorCode.COMPONENT_ERROR_CODE_BATTERY_LOW_SOH
308
+ """Error indicating a low state of health (SOH) detected in the battery."""
309
+
310
+ BATTERY_BLOCK_ERROR = PBComponentErrorCode.COMPONENT_ERROR_CODE_BATTERY_BLOCK_ERROR
311
+ """Error indicating a battery block error."""
312
+
313
+ BATTERY_CONTROLLER_ERROR = (
314
+ PBComponentErrorCode.COMPONENT_ERROR_CODE_BATTERY_CONTROLLER_ERROR
315
+ )
316
+ """Error indicating a battery controller error."""
317
+
318
+ BATTERY_RELAY_ERROR = PBComponentErrorCode.COMPONENT_ERROR_CODE_BATTERY_RELAY_ERROR
319
+ """Error indicating a battery relay error."""
320
+
321
+ BATTERY_CALIBRATION_NEEDED = (
322
+ PBComponentErrorCode.COMPONENT_ERROR_CODE_BATTERY_CALIBRATION_NEEDED
323
+ )
324
+ """Error indicating that battery calibration is needed."""
325
+
326
+ RELAY_CYCLE_LIMIT_REACHED = (
327
+ PBComponentErrorCode.COMPONENT_ERROR_CODE_RELAY_CYCLE_LIMIT_REACHED
328
+ )
329
+ """Error indicating that the relays have been cycled for the maximum number of
330
+ times."""
331
+
332
+ @classmethod
333
+ def from_proto(
334
+ cls, component_error_code: PBComponentErrorCode.ValueType
335
+ ) -> ComponentErrorCode:
336
+ """Convert a protobuf ComponentErrorCode message to ComponentErrorCode enum.
337
+
338
+ Args:
339
+ component_error_code: protobuf enum to convert
340
+
341
+ Returns:
342
+ Enum value corresponding to the protobuf message.
343
+ """
344
+ if not any(c.value == component_error_code for c in ComponentErrorCode):
345
+ return ComponentErrorCode.UNSPECIFIED
346
+ return cls(component_error_code)
347
+
348
+ def to_proto(self) -> PBComponentErrorCode.ValueType:
349
+ """Convert a ComponentErrorCode enum to protobuf ComponentErrorCode message.
350
+
351
+ Returns:
352
+ Enum value corresponding to the protobuf message.
353
+ """
354
+ return self.value
@@ -19,10 +19,10 @@ from frequenz.api.common.v1.pagination.pagination_params_pb2 import PaginationPa
19
19
  class Params:
20
20
  """Parameters for paginating list requests."""
21
21
 
22
- page_size: int | None = None
22
+ page_size: int
23
23
  """The maximum number of results to be returned per request."""
24
24
 
25
- page_token: str | None = None
25
+ page_token: str
26
26
  """The token identifying a specific page of the list results."""
27
27
 
28
28
  @classmethod
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: frequenz-client-common
3
- Version: 0.2.0
3
+ Version: 0.3.0
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
@@ -19,15 +19,47 @@ Classifier: Topic :: Software Development :: Libraries
19
19
  Classifier: Typing :: Typed
20
20
  Requires-Python: <4,>=3.11
21
21
  Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: typing-extensions<5,>=4.5.0
24
+ Requires-Dist: frequenz-api-common<7,>=0.6.0
22
25
  Provides-Extra: dev-flake8
26
+ Requires-Dist: flake8==7.1.1; extra == "dev-flake8"
27
+ Requires-Dist: flake8-docstrings==1.7.0; extra == "dev-flake8"
28
+ Requires-Dist: flake8-pyproject==1.2.3; extra == "dev-flake8"
29
+ Requires-Dist: pydoclint==0.5.9; extra == "dev-flake8"
30
+ Requires-Dist: pydocstyle==6.3.0; extra == "dev-flake8"
23
31
  Provides-Extra: dev-formatting
32
+ Requires-Dist: black==24.10.0; extra == "dev-formatting"
33
+ Requires-Dist: isort==5.13.2; extra == "dev-formatting"
24
34
  Provides-Extra: dev-mkdocs
35
+ Requires-Dist: black==24.10.0; extra == "dev-mkdocs"
36
+ Requires-Dist: Markdown==3.7; extra == "dev-mkdocs"
37
+ Requires-Dist: mike==2.1.3; extra == "dev-mkdocs"
38
+ Requires-Dist: mkdocs-gen-files==0.5.0; extra == "dev-mkdocs"
39
+ Requires-Dist: mkdocs-literate-nav==0.6.1; extra == "dev-mkdocs"
40
+ Requires-Dist: mkdocs-macros-plugin==1.3.7; extra == "dev-mkdocs"
41
+ Requires-Dist: mkdocs-material==9.5.47; extra == "dev-mkdocs"
42
+ Requires-Dist: mkdocstrings[python]==0.27.0; extra == "dev-mkdocs"
43
+ Requires-Dist: mkdocstrings-python==1.12.2; extra == "dev-mkdocs"
44
+ Requires-Dist: frequenz-repo-config[lib]==0.11.0; extra == "dev-mkdocs"
25
45
  Provides-Extra: dev-mypy
46
+ Requires-Dist: mypy==1.13.0; extra == "dev-mypy"
47
+ Requires-Dist: types-Markdown==3.7.0.20241204; extra == "dev-mypy"
48
+ Requires-Dist: frequenz-client-common[dev-mkdocs,dev-noxfile,dev-pytest]; extra == "dev-mypy"
26
49
  Provides-Extra: dev-noxfile
50
+ Requires-Dist: nox==2024.10.9; extra == "dev-noxfile"
51
+ Requires-Dist: frequenz-repo-config[lib]==0.11.0; extra == "dev-noxfile"
27
52
  Provides-Extra: dev-pylint
53
+ Requires-Dist: pylint==3.3.2; extra == "dev-pylint"
54
+ Requires-Dist: frequenz-client-common[dev-mkdocs,dev-noxfile,dev-pytest]; extra == "dev-pylint"
28
55
  Provides-Extra: dev-pytest
56
+ Requires-Dist: pytest==8.3.4; extra == "dev-pytest"
57
+ Requires-Dist: frequenz-repo-config[extra-lint-examples]==0.11.0; extra == "dev-pytest"
58
+ Requires-Dist: pytest-mock==3.14.0; extra == "dev-pytest"
59
+ Requires-Dist: pytest-asyncio==0.24.0; extra == "dev-pytest"
60
+ Requires-Dist: async-solipsism==0.7; extra == "dev-pytest"
29
61
  Provides-Extra: dev
30
- License-File: LICENSE
62
+ Requires-Dist: frequenz-client-common[dev-flake8,dev-formatting,dev-mkdocs,dev-mypy,dev-noxfile,dev-pylint,dev-pytest]; extra == "dev"
31
63
 
32
64
  # Frequenz Client Common Library
33
65
 
@@ -5,43 +5,44 @@ frequenz-api-common<7,>=0.6.0
5
5
  frequenz-client-common[dev-flake8,dev-formatting,dev-mkdocs,dev-mypy,dev-noxfile,dev-pylint,dev-pytest]
6
6
 
7
7
  [dev-flake8]
8
- flake8==7.0.0
8
+ flake8==7.1.1
9
9
  flake8-docstrings==1.7.0
10
10
  flake8-pyproject==1.2.3
11
- pydoclint==0.4.1
11
+ pydoclint==0.5.9
12
12
  pydocstyle==6.3.0
13
13
 
14
14
  [dev-formatting]
15
- black==24.4.2
15
+ black==24.10.0
16
16
  isort==5.13.2
17
17
 
18
18
  [dev-mkdocs]
19
- black==24.4.2
20
- Markdown==3.6
21
- mike==2.0.0
19
+ black==24.10.0
20
+ Markdown==3.7
21
+ mike==2.1.3
22
22
  mkdocs-gen-files==0.5.0
23
23
  mkdocs-literate-nav==0.6.1
24
- mkdocs-macros-plugin==1.0.5
25
- mkdocs-material==9.5.20
26
- mkdocstrings[python]==0.25.0
27
- frequenz-repo-config[lib]==0.9.1
24
+ mkdocs-macros-plugin==1.3.7
25
+ mkdocs-material==9.5.47
26
+ mkdocstrings[python]==0.27.0
27
+ mkdocstrings-python==1.12.2
28
+ frequenz-repo-config[lib]==0.11.0
28
29
 
29
30
  [dev-mypy]
30
- mypy==1.10.0
31
- types-Markdown==3.6.0.20240316
31
+ mypy==1.13.0
32
+ types-Markdown==3.7.0.20241204
32
33
  frequenz-client-common[dev-mkdocs,dev-noxfile,dev-pytest]
33
34
 
34
35
  [dev-noxfile]
35
- nox==2024.4.15
36
- frequenz-repo-config[lib]==0.9.1
36
+ nox==2024.10.9
37
+ frequenz-repo-config[lib]==0.11.0
37
38
 
38
39
  [dev-pylint]
39
- pylint==3.1.0
40
+ pylint==3.3.2
40
41
  frequenz-client-common[dev-mkdocs,dev-noxfile,dev-pytest]
41
42
 
42
43
  [dev-pytest]
43
- pytest==8.2.0
44
- frequenz-repo-config[extra-lint-examples]==0.9.1
44
+ pytest==8.3.4
45
+ frequenz-repo-config[extra-lint-examples]==0.11.0
45
46
  pytest-mock==3.14.0
46
- pytest-asyncio==0.23.6
47
- async-solipsism==0.6
47
+ pytest-asyncio==0.24.0
48
+ async-solipsism==0.7
@@ -1,5 +0,0 @@
1
- # Frequenz Client Common Library Release Notes
2
-
3
- ## Upgrading
4
-
5
- * Upgrading metric `__init__` to names from api-common release [v0.6.0](https://github.com/frequenz-floss/frequenz-api-common/releases/tag/v0.6.0)
@@ -1,67 +0,0 @@
1
- # License: MIT
2
- # Copyright © 2022 Frequenz Energy-as-a-Service GmbH
3
-
4
- """Defines the components that can be used in a microgrid."""
5
- from __future__ import annotations
6
-
7
- from enum import Enum
8
-
9
- # pylint: disable=no-name-in-module
10
- from frequenz.api.common.v1.microgrid.components.components_pb2 import (
11
- ComponentCategory as PBComponentCategory,
12
- )
13
-
14
- # pylint: enable=no-name-in-module
15
-
16
-
17
- class ComponentCategory(Enum):
18
- """Possible types of microgrid component."""
19
-
20
- UNSPECIFIED = PBComponentCategory.COMPONENT_CATEGORY_UNSPECIFIED
21
- """An unknown component category.
22
-
23
- Useful for error handling, and marking unknown components in
24
- a list of components with otherwise known categories.
25
- """
26
-
27
- GRID = PBComponentCategory.COMPONENT_CATEGORY_GRID
28
- """The point where the local microgrid is connected to the grid."""
29
-
30
- METER = PBComponentCategory.COMPONENT_CATEGORY_METER
31
- """A meter, for measuring electrical metrics, e.g., current, voltage, etc."""
32
-
33
- INVERTER = PBComponentCategory.COMPONENT_CATEGORY_INVERTER
34
- """An electricity generator, with batteries or solar energy."""
35
-
36
- BATTERY = PBComponentCategory.COMPONENT_CATEGORY_BATTERY
37
- """A storage system for electrical energy, used by inverters."""
38
-
39
- EV_CHARGER = PBComponentCategory.COMPONENT_CATEGORY_EV_CHARGER
40
- """A station for charging electrical vehicles."""
41
-
42
- CHP = PBComponentCategory.COMPONENT_CATEGORY_CHP
43
- """A heat and power combustion plant (CHP stands for combined heat and power)."""
44
-
45
- @classmethod
46
- def from_proto(
47
- cls, component_category: PBComponentCategory.ValueType
48
- ) -> ComponentCategory:
49
- """Convert a protobuf ComponentCategory message to ComponentCategory enum.
50
-
51
- Args:
52
- component_category: protobuf enum to convert
53
-
54
- Returns:
55
- Enum value corresponding to the protobuf message.
56
- """
57
- if not any(t.value == component_category for t in ComponentCategory):
58
- return ComponentCategory.UNSPECIFIED
59
- return cls(component_category)
60
-
61
- def to_proto(self) -> PBComponentCategory.ValueType:
62
- """Convert a ComponentCategory enum to protobuf ComponentCategory message.
63
-
64
- Returns:
65
- Enum value corresponding to the protobuf message.
66
- """
67
- return self.value