s2-python 0.0.1__py3-none-any.whl → 0.1.0__py3-none-any.whl
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.
- {s2_python-0.0.1.dist-info → s2_python-0.1.0.dist-info}/METADATA +20 -4
- s2_python-0.1.0.dist-info/RECORD +50 -0
- {s2_python-0.0.1.dist-info → s2_python-0.1.0.dist-info}/WHEEL +1 -1
- s2python/__init__.py +1 -1
- s2python/common/duration.py +2 -2
- s2python/common/handshake.py +2 -2
- s2python/common/handshake_response.py +2 -2
- s2python/common/instruction_status_update.py +2 -2
- s2python/common/number_range.py +10 -7
- s2python/common/power_forecast.py +3 -3
- s2python/common/power_forecast_element.py +4 -5
- s2python/common/power_forecast_value.py +2 -4
- s2python/common/power_measurement.py +3 -3
- s2python/common/power_range.py +6 -3
- s2python/common/power_value.py +2 -2
- s2python/common/reception_status.py +2 -2
- s2python/common/resource_manager_details.py +4 -3
- s2python/common/revoke_object.py +2 -2
- s2python/common/role.py +2 -2
- s2python/common/select_control_type.py +2 -2
- s2python/common/session_request.py +2 -2
- s2python/common/support.py +6 -4
- s2python/common/timer.py +2 -2
- s2python/common/transition.py +3 -3
- s2python/frbc/frbc_actuator_description.py +10 -4
- s2python/frbc/frbc_actuator_status.py +2 -4
- s2python/frbc/frbc_fill_level_target_profile.py +5 -3
- s2python/frbc/frbc_fill_level_target_profile_element.py +2 -2
- s2python/frbc/frbc_instruction.py +2 -2
- s2python/frbc/frbc_leakage_behaviour.py +3 -5
- s2python/frbc/frbc_leakage_behaviour_element.py +2 -2
- s2python/frbc/frbc_operation_mode.py +5 -4
- s2python/frbc/frbc_operation_mode_element.py +2 -2
- s2python/frbc/frbc_storage_description.py +2 -2
- s2python/frbc/frbc_storage_status.py +2 -2
- s2python/frbc/frbc_system_description.py +4 -3
- s2python/frbc/frbc_timer_status.py +2 -2
- s2python/frbc/frbc_usage_forecast.py +3 -3
- s2python/frbc/frbc_usage_forecast_element.py +2 -2
- s2python/s2_parser.py +113 -0
- s2python/s2_validation_error.py +3 -1
- s2python/utils.py +7 -2
- s2python/validate_values_mixin.py +38 -17
- s2_python-0.0.1.dist-info/RECORD +0 -49
- {s2_python-0.0.1.dist-info → s2_python-0.1.0.dist-info}/entry_points.txt +0 -0
- {s2_python-0.0.1.dist-info → s2_python-0.1.0.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: s2-python
|
3
|
-
Version: 0.0
|
3
|
+
Version: 0.1.0
|
4
4
|
Summary: S2 Protocol Python Wrapper
|
5
5
|
Home-page: https://github.com/flexiblepower/s2-ws-json-python
|
6
6
|
Author: Flexiblepower
|
@@ -13,7 +13,7 @@ Classifier: Programming Language :: Python :: 3.9
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.10
|
14
14
|
Classifier: Programming Language :: Python :: 3.11
|
15
15
|
Description-Content-Type: text/x-rst; charset=UTF-8
|
16
|
-
Requires-Dist: pydantic
|
16
|
+
Requires-Dist: pydantic ~=1.10.7
|
17
17
|
Requires-Dist: pytz
|
18
18
|
Requires-Dist: click
|
19
19
|
Provides-Extra: development
|
@@ -33,13 +33,14 @@ Requires-Dist: pytest ; extra == 'testing'
|
|
33
33
|
Requires-Dist: pytest-coverage ; extra == 'testing'
|
34
34
|
Requires-Dist: pytest-timer ; extra == 'testing'
|
35
35
|
Requires-Dist: mypy ; extra == 'testing'
|
36
|
+
Requires-Dist: types-pytz ; extra == 'testing'
|
36
37
|
Requires-Dist: pylint ; extra == 'testing'
|
37
38
|
|
38
39
|
Python Wrapper for S2 Flexibility Protocol
|
39
40
|
===========================================
|
40
41
|
.. image:: https://img.shields.io/pypi/v/s2-python
|
41
42
|
:alt: PyPI - Version
|
42
|
-
.. image:: https://img.shields.io/pypi/pyversions/
|
43
|
+
.. image:: https://img.shields.io/pypi/pyversions/s2-python
|
43
44
|
:alt: PyPI - Python Version
|
44
45
|
.. image:: https://img.shields.io/pypi/l/s2-python
|
45
46
|
:alt: PyPI - License
|
@@ -49,14 +50,29 @@ is based on the asyncapi description of the protocol provided in the `s2-ws-json
|
|
49
50
|
|
50
51
|
Currently, the package supports the *common* and *FILL RATE BASED CONTROL* types and messages.
|
51
52
|
|
53
|
+
To Install
|
54
|
+
-----------
|
55
|
+
You can install this package using pip or any Python dependency manager that collects the packages from Pypi:
|
56
|
+
|
57
|
+
.. code-block:: bash
|
58
|
+
|
59
|
+
pip install s2-python
|
60
|
+
|
61
|
+
The packages on Pypi may be found `here <https://pypi.org/project/s2-python/>`_
|
52
62
|
|
53
63
|
Example
|
54
64
|
---------
|
55
65
|
|
56
66
|
.. code-block:: python
|
57
67
|
|
68
|
+
from s2python.common import PowerRange, CommodityQuantity
|
69
|
+
|
58
70
|
# create s2 messages as Python objects
|
59
|
-
number_range = PowerRange(
|
71
|
+
number_range = PowerRange(
|
72
|
+
start_of_range=4.0,
|
73
|
+
end_of_range=5.0,
|
74
|
+
commodity_quantity=CommodityQuantity.ELECTRIC_POWER_L1,
|
75
|
+
)
|
60
76
|
# serialize s2 messages
|
61
77
|
number_range.to_json()
|
62
78
|
# deserialize s2 messages
|
@@ -0,0 +1,50 @@
|
|
1
|
+
s2python/__init__.py,sha256=e5lwvqsPl-z7IfEd0hRQhLBRKBYcuw2eqrecXnMfLdg,384
|
2
|
+
s2python/s2_parser.py,sha256=4oN4qBeW7RVNcXQ8GVib_oodK1_gszCrcXMQjPqRGUI,4088
|
3
|
+
s2python/s2_validation_error.py,sha256=fdV2tdRhYslDStTw8Cvb3mly7PpLiCbXbrkfOe3n2_w,295
|
4
|
+
s2python/utils.py,sha256=QX9b-mi-H_YUGTmGmJsrAbaWWM3dgaoaRLRXHHlaZDE,212
|
5
|
+
s2python/validate_values_mixin.py,sha256=RbhxqqhfhsNoTSeRxb7msQ6nEZWwAoUH6EQKkZkzH4k,4109
|
6
|
+
s2python/version.py,sha256=w9Iw7QVvd8lme2wKwEbCo5IgetVjSfFBOOYAcA_Q0Ns,18
|
7
|
+
s2python/common/__init__.py,sha256=fVJ0n13kRzzAtJcOxZHz3CEDexWXnyueJMcEXGdq_88,1345
|
8
|
+
s2python/common/duration.py,sha256=fMuftby-8wLeqpLKXd7VQqcmgTUUhTmWSW53R2b2vHM,661
|
9
|
+
s2python/common/handshake.py,sha256=IsbA41wBN4n0jopHn-vNDf2y1HP47p2kahM3NSwxAfc,440
|
10
|
+
s2python/common/handshake_response.py,sha256=Pa7kwRUFiecvPU84-z3D9_woxGqM4-_G9XtLgVmzMKA,496
|
11
|
+
s2python/common/instruction_status_update.py,sha256=w3bbVZ8jF3VBLKe3Q3fhWK9WhldxkkNgSzXuXyPzklA,694
|
12
|
+
s2python/common/number_range.py,sha256=NRND5K1-_U_6S4lVxfszI4A9o8hFYCrFQieska_ELgU,1163
|
13
|
+
s2python/common/power_forecast.py,sha256=-i1Z4JMGpmoo4N2DfmzMYiEh7o25xxsesKkUxhSWjAw,700
|
14
|
+
s2python/common/power_forecast_element.py,sha256=nQopGR0-uuE9jGyg2L-zusvkVACWqMJNxOyjm3PJYI4,787
|
15
|
+
s2python/common/power_forecast_value.py,sha256=UHiP8Go64RW6VzszzmAZ3JIyaGf2WOMGyx_PTmdmBoY,375
|
16
|
+
s2python/common/power_measurement.py,sha256=l_Na6Yw6twQveLw6j6FsX6BQh0fbmveHdHdsmnDzegs,675
|
17
|
+
s2python/common/power_range.py,sha256=Pazitj5zPzH2rz0gnKAzinwEhM28Dftglf3z6sHjIqA,796
|
18
|
+
s2python/common/power_value.py,sha256=xpu-MV_lkFYksfVDRRFbWiha8fA7KAF_p3CBoNNoyyg,327
|
19
|
+
s2python/common/reception_status.py,sha256=yd3tzG8UNMCjPy3WXpgMHjYnuFW3wyCv82tnq2kgEME,512
|
20
|
+
s2python/common/resource_manager_details.py,sha256=YOKnw7wMAX5JIt3LAnxfCvG0kTZjshHF8Yotfzyqbew,1050
|
21
|
+
s2python/common/revoke_object.py,sha256=EWuTqHoVyaPO-eIcFSCE7zROJXyR6RWkajX60IL8aM8,567
|
22
|
+
s2python/common/role.py,sha256=PV0noDy3D30dIodJgIWfGWcz-4hwZyBnpsWkyjc8c7g,291
|
23
|
+
s2python/common/select_control_type.py,sha256=y6yXcuCGPsm-QKSg6jJTzfUzAbZqvMkWepMhXERVQlM,496
|
24
|
+
s2python/common/session_request.py,sha256=bCnyAjSdeLShAC513x7ifaNRKZLAdzoJF2rU_zXxZEI,475
|
25
|
+
s2python/common/support.py,sha256=Kbrf_KGB45Wfr8j2pqDe1lLde6CIr3nl_LYkWnilmV0,1015
|
26
|
+
s2python/common/timer.py,sha256=-KhxxyJwK0pfVrpLBg9thYzOb2-LB5FgRBznwKCu76Y,538
|
27
|
+
s2python/common/transition.py,sha256=pYfo4sfWdnBR2Tvn3cW34zVT53d4PZSc3Ee3mubAYAg,1096
|
28
|
+
s2python/frbc/__init__.py,sha256=ROV3qZoldPkdgVFfMQr5Mf3GDfBzXaMfhNNCuXY6T0s,1104
|
29
|
+
s2python/frbc/frbc_actuator_description.py,sha256=9Zzzjhii3vABsLPOIN6qGavs0YyWthNV7whjcJadyGY,6801
|
30
|
+
s2python/frbc/frbc_actuator_status.py,sha256=xnTqGyh_h03BsBWRQfV7SMHn1yZV2KLV02FpIgojzr4,973
|
31
|
+
s2python/frbc/frbc_fill_level_target_profile.py,sha256=0kGB-uD0mqOZPdRBn_EJ8rMrA6DfTHMk7_nsSm7icRA,896
|
32
|
+
s2python/frbc/frbc_fill_level_target_profile_element.py,sha256=fqYwvbfEAM-e_hbUB6MN9NjGoCCdBcd-VGtmB9UyLbc,832
|
33
|
+
s2python/frbc/frbc_instruction.py,sha256=y8hZqh1jDKWVwehweWHQnbkFiSHlY87T4Al5kxEH9rQ,809
|
34
|
+
s2python/frbc/frbc_leakage_behaviour.py,sha256=CAuIAgaBDv82rPHmjJYchuVQilKLLjIOfI71UDnKXYk,776
|
35
|
+
s2python/frbc/frbc_leakage_behaviour_element.py,sha256=Bvw_4zuS5PgoZu_Pwy9kFCst75JbQyGKSvxOU7owYCA,636
|
36
|
+
s2python/frbc/frbc_operation_mode.py,sha256=bkMxQMP1pxF4rb0plUzBnFv7IG261lDq3FDf0HId0uE,2030
|
37
|
+
s2python/frbc/frbc_operation_mode_element.py,sha256=Bc5pJDwd83SbJiFYT2GA6sTzeLtsa8ohAM8LuY3uRc4,1079
|
38
|
+
s2python/frbc/frbc_storage_description.py,sha256=bxFVxYPhNCejMjBJtIiGjCCS7fyoOXHc3TUeWho7CYM,601
|
39
|
+
s2python/frbc/frbc_storage_status.py,sha256=PZCs-fh43in7LlYjalygW57iRQWwBp51tVEoZemS9-Y,496
|
40
|
+
s2python/frbc/frbc_system_description.py,sha256=RefubMI735vDV-cp6FEAEDe4bfcEYwY_EhCu5rC1oSs,991
|
41
|
+
s2python/frbc/frbc_timer_status.py,sha256=tyhjNia_I2j6rSggFiXp8i6QcZRiqhcOkMtn_TkXQ0Q,702
|
42
|
+
s2python/frbc/frbc_usage_forecast.py,sha256=8zWLBYpRfjiPKRz5x0QiZ2IF8HDGA8qlUgbOofAsQPA,743
|
43
|
+
s2python/frbc/frbc_usage_forecast_element.py,sha256=OuwrN4KarVe4tq6R4qkNz5j-sQstQDzLWP4g5B6L-iw,580
|
44
|
+
s2python/generated/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
45
|
+
s2python/generated/gen_s2.py,sha256=DXLCNE1gUS7XnRTgWlBpy73szr5HrHcrN0TZXvq8N_g,61928
|
46
|
+
s2_python-0.1.0.dist-info/METADATA,sha256=-V9F_j0oh6IkAVzrcX5oFFyY7bON8FwRwc7NUsLjIM4,3257
|
47
|
+
s2_python-0.1.0.dist-info/WHEEL,sha256=Xo9-1PvkuimrydujYJAjF7pCkriuXBpUPEjma1nZyJ0,92
|
48
|
+
s2_python-0.1.0.dist-info/entry_points.txt,sha256=feX-xmgJZgSe5-jxMgFKPKCJz4Ys3eQcGrsXsirNZyM,61
|
49
|
+
s2_python-0.1.0.dist-info/top_level.txt,sha256=OLFq0oDhr77Mp-EYLEcWk5P3jvooOt4IHkTI5KYJMc8,9
|
50
|
+
s2_python-0.1.0.dist-info/RECORD,,
|
s2python/__init__.py
CHANGED
@@ -2,7 +2,7 @@ from importlib.metadata import PackageNotFoundError, version # pragma: no cover
|
|
2
2
|
|
3
3
|
try:
|
4
4
|
# Change here if project is renamed and does not equal the package name
|
5
|
-
dist_name = "s2-python"
|
5
|
+
dist_name = "s2-python" # pylint: disable=invalid-name
|
6
6
|
__version__ = version(dist_name)
|
7
7
|
except PackageNotFoundError: # pragma: no cover
|
8
8
|
__version__ = "unknown"
|
s2python/common/duration.py
CHANGED
@@ -4,12 +4,12 @@ import math
|
|
4
4
|
from s2python.generated.gen_s2 import Duration as GenDuration
|
5
5
|
from s2python.validate_values_mixin import (
|
6
6
|
catch_and_convert_exceptions,
|
7
|
-
|
7
|
+
S2Message,
|
8
8
|
)
|
9
9
|
|
10
10
|
|
11
11
|
@catch_and_convert_exceptions
|
12
|
-
class Duration(GenDuration,
|
12
|
+
class Duration(GenDuration, S2Message["Duration"]):
|
13
13
|
def to_timedelta(self) -> timedelta:
|
14
14
|
return timedelta(milliseconds=self.__root__)
|
15
15
|
|
s2python/common/handshake.py
CHANGED
@@ -3,12 +3,12 @@ import uuid
|
|
3
3
|
from s2python.generated.gen_s2 import Handshake as GenHandshake
|
4
4
|
from s2python.validate_values_mixin import (
|
5
5
|
catch_and_convert_exceptions,
|
6
|
-
|
6
|
+
S2Message,
|
7
7
|
)
|
8
8
|
|
9
9
|
|
10
10
|
@catch_and_convert_exceptions
|
11
|
-
class Handshake(GenHandshake,
|
11
|
+
class Handshake(GenHandshake, S2Message["Handshake"]):
|
12
12
|
class Config(GenHandshake.Config):
|
13
13
|
validate_assignment = True
|
14
14
|
|
@@ -3,12 +3,12 @@ import uuid
|
|
3
3
|
from s2python.generated.gen_s2 import HandshakeResponse as GenHandshakeResponse
|
4
4
|
from s2python.validate_values_mixin import (
|
5
5
|
catch_and_convert_exceptions,
|
6
|
-
|
6
|
+
S2Message,
|
7
7
|
)
|
8
8
|
|
9
9
|
|
10
10
|
@catch_and_convert_exceptions
|
11
|
-
class HandshakeResponse(GenHandshakeResponse,
|
11
|
+
class HandshakeResponse(GenHandshakeResponse, S2Message["HandshakeResponse"]):
|
12
12
|
class Config(GenHandshakeResponse.Config):
|
13
13
|
validate_assignment = True
|
14
14
|
|
@@ -5,13 +5,13 @@ from s2python.generated.gen_s2 import (
|
|
5
5
|
)
|
6
6
|
from s2python.validate_values_mixin import (
|
7
7
|
catch_and_convert_exceptions,
|
8
|
-
|
8
|
+
S2Message,
|
9
9
|
)
|
10
10
|
|
11
11
|
|
12
12
|
@catch_and_convert_exceptions
|
13
13
|
class InstructionStatusUpdate(
|
14
|
-
GenInstructionStatusUpdate,
|
14
|
+
GenInstructionStatusUpdate, S2Message["InstructionStatusUpdate"]
|
15
15
|
):
|
16
16
|
class Config(GenInstructionStatusUpdate.Config):
|
17
17
|
validate_assignment = True
|
s2python/common/number_range.py
CHANGED
@@ -3,19 +3,22 @@ from typing import Any, Dict
|
|
3
3
|
from pydantic import root_validator
|
4
4
|
|
5
5
|
from s2python.validate_values_mixin import (
|
6
|
-
|
6
|
+
S2Message,
|
7
7
|
catch_and_convert_exceptions,
|
8
8
|
)
|
9
9
|
from s2python.generated.gen_s2 import NumberRange as GenNumberRange
|
10
10
|
|
11
11
|
|
12
12
|
@catch_and_convert_exceptions
|
13
|
-
class NumberRange(GenNumberRange,
|
13
|
+
class NumberRange(GenNumberRange, S2Message["NumberRange"]):
|
14
14
|
class Config(GenNumberRange.Config):
|
15
15
|
validate_assignment = True
|
16
16
|
|
17
17
|
@root_validator(pre=False)
|
18
|
-
|
18
|
+
@classmethod
|
19
|
+
def validate_start_end_order( # pylint: disable=duplicate-code
|
20
|
+
cls, values: Dict[str, Any]
|
21
|
+
) -> Dict[str, Any]:
|
19
22
|
if values.get("start_of_range", 0.0) > values.get("end_of_range", 0.0):
|
20
23
|
raise ValueError(
|
21
24
|
cls, "start_of_range should not be higher than end_of_range"
|
@@ -23,14 +26,14 @@ class NumberRange(GenNumberRange, ValidateValuesMixin["NumberRange"]):
|
|
23
26
|
|
24
27
|
return values
|
25
28
|
|
26
|
-
def __hash__(self):
|
29
|
+
def __hash__(self) -> int:
|
27
30
|
return hash(f"{self.start_of_range}|{self.end_of_range}")
|
28
31
|
|
29
|
-
def __eq__(self, other):
|
32
|
+
def __eq__(self, other: Any) -> bool:
|
30
33
|
if isinstance(other, NumberRange):
|
31
34
|
return (
|
32
35
|
self.start_of_range == other.start_of_range
|
33
36
|
and self.end_of_range == other.end_of_range
|
34
37
|
)
|
35
|
-
|
36
|
-
|
38
|
+
|
39
|
+
return False
|
@@ -1,16 +1,16 @@
|
|
1
1
|
from typing import List
|
2
2
|
import uuid
|
3
3
|
|
4
|
-
from s2python.common import PowerForecastElement
|
4
|
+
from s2python.common.power_forecast_element import PowerForecastElement
|
5
5
|
from s2python.generated.gen_s2 import PowerForecast as GenPowerForecast
|
6
6
|
from s2python.validate_values_mixin import (
|
7
7
|
catch_and_convert_exceptions,
|
8
|
-
|
8
|
+
S2Message,
|
9
9
|
)
|
10
10
|
|
11
11
|
|
12
12
|
@catch_and_convert_exceptions
|
13
|
-
class PowerForecast(GenPowerForecast,
|
13
|
+
class PowerForecast(GenPowerForecast, S2Message["PowerForecast"]):
|
14
14
|
class Config(GenPowerForecast.Config):
|
15
15
|
validate_assignment = True
|
16
16
|
|
@@ -3,15 +3,14 @@ from typing import List
|
|
3
3
|
from s2python.generated.gen_s2 import PowerForecastElement as GenPowerForecastElement
|
4
4
|
from s2python.validate_values_mixin import (
|
5
5
|
catch_and_convert_exceptions,
|
6
|
-
|
6
|
+
S2Message,
|
7
7
|
)
|
8
|
-
from s2python.common import Duration
|
8
|
+
from s2python.common.duration import Duration
|
9
|
+
from s2python.common.power_forecast_value import PowerForecastValue
|
9
10
|
|
10
11
|
|
11
12
|
@catch_and_convert_exceptions
|
12
|
-
class PowerForecastElement(
|
13
|
-
GenPowerForecastElement, ValidateValuesMixin["PowerForecastElement"]
|
14
|
-
):
|
13
|
+
class PowerForecastElement(GenPowerForecastElement, S2Message["PowerForecastElement"]):
|
15
14
|
class Config(GenPowerForecastElement.Config):
|
16
15
|
validate_assignment = True
|
17
16
|
|
@@ -1,13 +1,11 @@
|
|
1
1
|
from s2python.generated.gen_s2 import PowerForecastValue as GenPowerForecastValue
|
2
2
|
from s2python.validate_values_mixin import (
|
3
3
|
catch_and_convert_exceptions,
|
4
|
-
|
4
|
+
S2Message,
|
5
5
|
)
|
6
6
|
|
7
7
|
|
8
8
|
@catch_and_convert_exceptions
|
9
|
-
class PowerForecastValue(
|
10
|
-
GenPowerForecastValue, ValidateValuesMixin["PowerForecastValue"]
|
11
|
-
):
|
9
|
+
class PowerForecastValue(GenPowerForecastValue, S2Message["PowerForecastValue"]):
|
12
10
|
class Config(GenPowerForecastValue.Config):
|
13
11
|
validate_assignment = True
|
@@ -1,16 +1,16 @@
|
|
1
1
|
from typing import List
|
2
2
|
import uuid
|
3
3
|
|
4
|
-
from s2python.common import PowerValue
|
4
|
+
from s2python.common.power_value import PowerValue
|
5
5
|
from s2python.generated.gen_s2 import PowerMeasurement as GenPowerMeasurement
|
6
6
|
from s2python.validate_values_mixin import (
|
7
7
|
catch_and_convert_exceptions,
|
8
|
-
|
8
|
+
S2Message,
|
9
9
|
)
|
10
10
|
|
11
11
|
|
12
12
|
@catch_and_convert_exceptions
|
13
|
-
class PowerMeasurement(GenPowerMeasurement,
|
13
|
+
class PowerMeasurement(GenPowerMeasurement, S2Message["PowerMeasurement"]):
|
14
14
|
class Config(GenPowerMeasurement.Config):
|
15
15
|
validate_assignment = True
|
16
16
|
|
s2python/common/power_range.py
CHANGED
@@ -4,18 +4,21 @@ from pydantic import root_validator
|
|
4
4
|
|
5
5
|
from s2python.generated.gen_s2 import PowerRange as GenPowerRange
|
6
6
|
from s2python.validate_values_mixin import (
|
7
|
-
|
7
|
+
S2Message,
|
8
8
|
catch_and_convert_exceptions,
|
9
9
|
)
|
10
10
|
|
11
11
|
|
12
12
|
@catch_and_convert_exceptions
|
13
|
-
class PowerRange(GenPowerRange,
|
13
|
+
class PowerRange(GenPowerRange, S2Message["PowerRange"]):
|
14
14
|
class Config(GenPowerRange.Config):
|
15
15
|
validate_assignment = True
|
16
16
|
|
17
17
|
@root_validator(pre=False)
|
18
|
-
|
18
|
+
@classmethod
|
19
|
+
def validate_start_end_order(
|
20
|
+
cls, values: Dict[str, Any]
|
21
|
+
) -> Dict[str, Any]: # pylint: disable=duplicate-code
|
19
22
|
if values.get("start_of_range", 0.0) > values.get("end_of_range", 0.0):
|
20
23
|
raise ValueError(
|
21
24
|
cls, "start_of_range should not be higher than end_of_range"
|
s2python/common/power_value.py
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
from s2python.generated.gen_s2 import PowerValue as GenPowerValue
|
2
2
|
from s2python.validate_values_mixin import (
|
3
3
|
catch_and_convert_exceptions,
|
4
|
-
|
4
|
+
S2Message,
|
5
5
|
)
|
6
6
|
|
7
7
|
|
8
8
|
@catch_and_convert_exceptions
|
9
|
-
class PowerValue(GenPowerValue,
|
9
|
+
class PowerValue(GenPowerValue, S2Message["PowerValue"]):
|
10
10
|
class Config(GenPowerValue.Config):
|
11
11
|
validate_assignment = True
|
@@ -3,12 +3,12 @@ import uuid
|
|
3
3
|
from s2python.generated.gen_s2 import ReceptionStatus as GenReceptionStatus
|
4
4
|
from s2python.validate_values_mixin import (
|
5
5
|
catch_and_convert_exceptions,
|
6
|
-
|
6
|
+
S2Message,
|
7
7
|
)
|
8
8
|
|
9
9
|
|
10
10
|
@catch_and_convert_exceptions
|
11
|
-
class ReceptionStatus(GenReceptionStatus,
|
11
|
+
class ReceptionStatus(GenReceptionStatus, S2Message["ReceptionStatus"]):
|
12
12
|
class Config(GenReceptionStatus.Config):
|
13
13
|
validate_assignment = True
|
14
14
|
|
@@ -1,19 +1,20 @@
|
|
1
1
|
from typing import List
|
2
2
|
import uuid
|
3
3
|
|
4
|
-
from s2python.common import Duration
|
4
|
+
from s2python.common.duration import Duration
|
5
|
+
from s2python.common.role import Role
|
5
6
|
from s2python.generated.gen_s2 import (
|
6
7
|
ResourceManagerDetails as GenResourceManagerDetails,
|
7
8
|
)
|
8
9
|
from s2python.validate_values_mixin import (
|
9
10
|
catch_and_convert_exceptions,
|
10
|
-
|
11
|
+
S2Message,
|
11
12
|
)
|
12
13
|
|
13
14
|
|
14
15
|
@catch_and_convert_exceptions
|
15
16
|
class ResourceManagerDetails(
|
16
|
-
GenResourceManagerDetails,
|
17
|
+
GenResourceManagerDetails, S2Message["ResourceManagerDetails"]
|
17
18
|
):
|
18
19
|
class Config(GenResourceManagerDetails.Config):
|
19
20
|
validate_assignment = True
|
s2python/common/revoke_object.py
CHANGED
@@ -3,12 +3,12 @@ import uuid
|
|
3
3
|
from s2python.generated.gen_s2 import RevokeObject as GenRevokeObject
|
4
4
|
from s2python.validate_values_mixin import (
|
5
5
|
catch_and_convert_exceptions,
|
6
|
-
|
6
|
+
S2Message,
|
7
7
|
)
|
8
8
|
|
9
9
|
|
10
10
|
@catch_and_convert_exceptions
|
11
|
-
class RevokeObject(GenRevokeObject,
|
11
|
+
class RevokeObject(GenRevokeObject, S2Message["RevokeObject"]):
|
12
12
|
class Config(GenRevokeObject.Config):
|
13
13
|
validate_assignment = True
|
14
14
|
|
s2python/common/role.py
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
from s2python.generated.gen_s2 import Role as GenRole
|
2
2
|
from s2python.validate_values_mixin import (
|
3
|
-
|
3
|
+
S2Message,
|
4
4
|
catch_and_convert_exceptions,
|
5
5
|
)
|
6
6
|
|
7
7
|
|
8
8
|
@catch_and_convert_exceptions
|
9
|
-
class Role(GenRole,
|
9
|
+
class Role(GenRole, S2Message["Role"]):
|
10
10
|
class Config(GenRole.Config):
|
11
11
|
validate_assignment = True
|
@@ -3,12 +3,12 @@ import uuid
|
|
3
3
|
from s2python.generated.gen_s2 import SelectControlType as GenSelectControlType
|
4
4
|
from s2python.validate_values_mixin import (
|
5
5
|
catch_and_convert_exceptions,
|
6
|
-
|
6
|
+
S2Message,
|
7
7
|
)
|
8
8
|
|
9
9
|
|
10
10
|
@catch_and_convert_exceptions
|
11
|
-
class SelectControlType(GenSelectControlType,
|
11
|
+
class SelectControlType(GenSelectControlType, S2Message["SelectControlType"]):
|
12
12
|
class Config(GenSelectControlType.Config):
|
13
13
|
validate_assignment = True
|
14
14
|
|
@@ -3,12 +3,12 @@ import uuid
|
|
3
3
|
from s2python.generated.gen_s2 import SessionRequest as GenSessionRequest
|
4
4
|
from s2python.validate_values_mixin import (
|
5
5
|
catch_and_convert_exceptions,
|
6
|
-
|
6
|
+
S2Message,
|
7
7
|
)
|
8
8
|
|
9
9
|
|
10
10
|
@catch_and_convert_exceptions
|
11
|
-
class SessionRequest(GenSessionRequest,
|
11
|
+
class SessionRequest(GenSessionRequest, S2Message["SessionRequest"]):
|
12
12
|
class Config(GenSessionRequest.Config):
|
13
13
|
validate_assignment = True
|
14
14
|
|
s2python/common/support.py
CHANGED
@@ -3,23 +3,25 @@ from s2python.common import CommodityQuantity, Commodity
|
|
3
3
|
|
4
4
|
def commodity_has_quantity(commodity: "Commodity", quantity: CommodityQuantity) -> bool:
|
5
5
|
if commodity == Commodity.HEAT:
|
6
|
-
|
6
|
+
result = quantity in [
|
7
7
|
CommodityQuantity.HEAT_THERMAL_POWER,
|
8
8
|
CommodityQuantity.HEAT_TEMPERATURE,
|
9
9
|
CommodityQuantity.HEAT_FLOW_RATE,
|
10
10
|
]
|
11
11
|
elif commodity == Commodity.ELECTRICITY:
|
12
|
-
|
12
|
+
result = quantity in [
|
13
13
|
CommodityQuantity.ELECTRIC_POWER_3_PHASE_SYMMETRIC,
|
14
14
|
CommodityQuantity.ELECTRIC_POWER_L1,
|
15
15
|
CommodityQuantity.ELECTRIC_POWER_L2,
|
16
16
|
CommodityQuantity.ELECTRIC_POWER_L3,
|
17
17
|
]
|
18
18
|
elif commodity == Commodity.GAS:
|
19
|
-
|
19
|
+
result = quantity in [CommodityQuantity.NATURAL_GAS_FLOW_RATE]
|
20
20
|
elif commodity == Commodity.OIL:
|
21
|
-
|
21
|
+
result = quantity in [CommodityQuantity.OIL_FLOW_RATE]
|
22
22
|
else:
|
23
23
|
raise RuntimeError(
|
24
24
|
f"Unsupported commodity {commodity}. Missing implementation."
|
25
25
|
)
|
26
|
+
|
27
|
+
return result
|
s2python/common/timer.py
CHANGED
@@ -3,13 +3,13 @@ import uuid
|
|
3
3
|
from s2python.common.duration import Duration
|
4
4
|
from s2python.generated.gen_s2 import Timer as GenTimer
|
5
5
|
from s2python.validate_values_mixin import (
|
6
|
-
|
6
|
+
S2Message,
|
7
7
|
catch_and_convert_exceptions,
|
8
8
|
)
|
9
9
|
|
10
10
|
|
11
11
|
@catch_and_convert_exceptions
|
12
|
-
class Timer(GenTimer,
|
12
|
+
class Timer(GenTimer, S2Message["Timer"]):
|
13
13
|
class Config(GenTimer.Config):
|
14
14
|
validate_assignment = True
|
15
15
|
|
s2python/common/transition.py
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
import uuid
|
2
2
|
from typing import Optional, List
|
3
3
|
|
4
|
-
from s2python.common import Duration
|
4
|
+
from s2python.common.duration import Duration
|
5
5
|
from s2python.generated.gen_s2 import Transition as GenTransition
|
6
6
|
from s2python.validate_values_mixin import (
|
7
|
-
|
7
|
+
S2Message,
|
8
8
|
catch_and_convert_exceptions,
|
9
9
|
)
|
10
10
|
|
11
11
|
|
12
12
|
@catch_and_convert_exceptions
|
13
|
-
class Transition(GenTransition,
|
13
|
+
class Transition(GenTransition, S2Message["Transition"]):
|
14
14
|
class Config(GenTransition.Config):
|
15
15
|
validate_assignment = True
|
16
16
|
|
@@ -6,20 +6,20 @@ from pydantic import root_validator
|
|
6
6
|
|
7
7
|
from s2python.common import Transition, Timer, Commodity
|
8
8
|
from s2python.common.support import commodity_has_quantity
|
9
|
-
from s2python.frbc import FRBCOperationMode
|
9
|
+
from s2python.frbc.frbc_operation_mode import FRBCOperationMode
|
10
10
|
from s2python.generated.gen_s2 import (
|
11
11
|
FRBCActuatorDescription as GenFRBCActuatorDescription,
|
12
12
|
CommodityQuantity,
|
13
13
|
)
|
14
14
|
from s2python.validate_values_mixin import (
|
15
|
-
|
15
|
+
S2Message,
|
16
16
|
catch_and_convert_exceptions,
|
17
17
|
)
|
18
18
|
|
19
19
|
|
20
20
|
@catch_and_convert_exceptions
|
21
21
|
class FRBCActuatorDescription(
|
22
|
-
GenFRBCActuatorDescription,
|
22
|
+
GenFRBCActuatorDescription, S2Message["FRBCActuatorDescription"]
|
23
23
|
):
|
24
24
|
class Config(GenFRBCActuatorDescription.Config):
|
25
25
|
validate_assignment = True
|
@@ -37,6 +37,7 @@ class FRBCActuatorDescription(
|
|
37
37
|
].field_info # type: ignore[assignment]
|
38
38
|
|
39
39
|
@root_validator(pre=False)
|
40
|
+
@classmethod
|
40
41
|
def validate_timers_in_transitions(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
41
42
|
timers_by_id = {timer.id: timer for timer in values.get("timers", {})}
|
42
43
|
transition: Transition
|
@@ -60,6 +61,7 @@ class FRBCActuatorDescription(
|
|
60
61
|
return values
|
61
62
|
|
62
63
|
@root_validator(pre=False)
|
64
|
+
@classmethod
|
63
65
|
def validate_timers_unique_ids(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
64
66
|
ids = []
|
65
67
|
timer: Timer
|
@@ -73,6 +75,7 @@ class FRBCActuatorDescription(
|
|
73
75
|
return values
|
74
76
|
|
75
77
|
@root_validator(pre=False)
|
78
|
+
@classmethod
|
76
79
|
def validate_operation_modes_in_transitions(
|
77
80
|
cls, values: Dict[str, Any]
|
78
81
|
) -> Dict[str, Any]:
|
@@ -99,6 +102,7 @@ class FRBCActuatorDescription(
|
|
99
102
|
return values
|
100
103
|
|
101
104
|
@root_validator(pre=False)
|
105
|
+
@classmethod
|
102
106
|
def validate_operation_modes_unique_ids(
|
103
107
|
cls, values: Dict[str, Any]
|
104
108
|
) -> Dict[str, Any]:
|
@@ -115,6 +119,7 @@ class FRBCActuatorDescription(
|
|
115
119
|
return values
|
116
120
|
|
117
121
|
@root_validator(pre=False)
|
122
|
+
@classmethod
|
118
123
|
def validate_operation_mode_elements_have_all_supported_commodities(
|
119
124
|
cls, values: Dict[str, Any]
|
120
125
|
) -> Dict[str, Any]:
|
@@ -148,10 +153,11 @@ class FRBCActuatorDescription(
|
|
148
153
|
return values
|
149
154
|
|
150
155
|
@root_validator(pre=False)
|
156
|
+
@classmethod
|
151
157
|
def validate_unique_supported_commodities(
|
152
158
|
cls, values: Dict[str, Any]
|
153
159
|
) -> Dict[str, Any]:
|
154
|
-
supported_commodities:
|
160
|
+
supported_commodities: List[CommodityQuantity] = values.get(
|
155
161
|
"supported_commodities", []
|
156
162
|
)
|
157
163
|
|
@@ -4,14 +4,12 @@ import uuid
|
|
4
4
|
from s2python.generated.gen_s2 import FRBCActuatorStatus as GenFRBCActuatorStatus
|
5
5
|
from s2python.validate_values_mixin import (
|
6
6
|
catch_and_convert_exceptions,
|
7
|
-
|
7
|
+
S2Message,
|
8
8
|
)
|
9
9
|
|
10
10
|
|
11
11
|
@catch_and_convert_exceptions
|
12
|
-
class FRBCActuatorStatus(
|
13
|
-
GenFRBCActuatorStatus, ValidateValuesMixin["FRBCActuatorStatus"]
|
14
|
-
):
|
12
|
+
class FRBCActuatorStatus(GenFRBCActuatorStatus, S2Message["FRBCActuatorStatus"]):
|
15
13
|
class Config(GenFRBCActuatorStatus.Config):
|
16
14
|
validate_assignment = True
|
17
15
|
|
@@ -1,19 +1,21 @@
|
|
1
1
|
from typing import List
|
2
2
|
import uuid
|
3
3
|
|
4
|
-
from s2python.frbc import
|
4
|
+
from s2python.frbc.frbc_fill_level_target_profile_element import (
|
5
|
+
FRBCFillLevelTargetProfileElement,
|
6
|
+
)
|
5
7
|
from s2python.generated.gen_s2 import (
|
6
8
|
FRBCFillLevelTargetProfile as GenFRBCFillLevelTargetProfile,
|
7
9
|
)
|
8
10
|
from s2python.validate_values_mixin import (
|
9
11
|
catch_and_convert_exceptions,
|
10
|
-
|
12
|
+
S2Message,
|
11
13
|
)
|
12
14
|
|
13
15
|
|
14
16
|
@catch_and_convert_exceptions
|
15
17
|
class FRBCFillLevelTargetProfile(
|
16
|
-
GenFRBCFillLevelTargetProfile,
|
18
|
+
GenFRBCFillLevelTargetProfile, S2Message["FRBCFillLevelTargetProfile"]
|
17
19
|
):
|
18
20
|
class Config(GenFRBCFillLevelTargetProfile.Config):
|
19
21
|
validate_assignment = True
|
@@ -5,14 +5,14 @@ from s2python.generated.gen_s2 import (
|
|
5
5
|
)
|
6
6
|
from s2python.validate_values_mixin import (
|
7
7
|
catch_and_convert_exceptions,
|
8
|
-
|
8
|
+
S2Message,
|
9
9
|
)
|
10
10
|
|
11
11
|
|
12
12
|
@catch_and_convert_exceptions
|
13
13
|
class FRBCFillLevelTargetProfileElement(
|
14
14
|
GenFRBCFillLevelTargetProfileElement,
|
15
|
-
|
15
|
+
S2Message["FRBCFillLevelTargetProfileElement"],
|
16
16
|
):
|
17
17
|
class Config(GenFRBCFillLevelTargetProfileElement.Config):
|
18
18
|
validate_assignment = True
|
@@ -3,12 +3,12 @@ import uuid
|
|
3
3
|
from s2python.generated.gen_s2 import FRBCInstruction as GenFRBCInstruction
|
4
4
|
from s2python.validate_values_mixin import (
|
5
5
|
catch_and_convert_exceptions,
|
6
|
-
|
6
|
+
S2Message,
|
7
7
|
)
|
8
8
|
|
9
9
|
|
10
10
|
@catch_and_convert_exceptions
|
11
|
-
class FRBCInstruction(GenFRBCInstruction,
|
11
|
+
class FRBCInstruction(GenFRBCInstruction, S2Message["FRBCInstruction"]):
|
12
12
|
class Config(GenFRBCInstruction.Config):
|
13
13
|
validate_assignment = True
|
14
14
|
|
@@ -1,18 +1,16 @@
|
|
1
1
|
from typing import List
|
2
2
|
import uuid
|
3
3
|
|
4
|
-
from s2python.frbc import FRBCLeakageBehaviourElement
|
4
|
+
from s2python.frbc.frbc_leakage_behaviour_element import FRBCLeakageBehaviourElement
|
5
5
|
from s2python.generated.gen_s2 import FRBCLeakageBehaviour as GenFRBCLeakageBehaviour
|
6
6
|
from s2python.validate_values_mixin import (
|
7
7
|
catch_and_convert_exceptions,
|
8
|
-
|
8
|
+
S2Message,
|
9
9
|
)
|
10
10
|
|
11
11
|
|
12
12
|
@catch_and_convert_exceptions
|
13
|
-
class FRBCLeakageBehaviour(
|
14
|
-
GenFRBCLeakageBehaviour, ValidateValuesMixin["FRBCLeakageBehaviour"]
|
15
|
-
):
|
13
|
+
class FRBCLeakageBehaviour(GenFRBCLeakageBehaviour, S2Message["FRBCLeakageBehaviour"]):
|
16
14
|
class Config(GenFRBCLeakageBehaviour.Config):
|
17
15
|
validate_assignment = True
|
18
16
|
|
@@ -4,13 +4,13 @@ from s2python.generated.gen_s2 import (
|
|
4
4
|
)
|
5
5
|
from s2python.validate_values_mixin import (
|
6
6
|
catch_and_convert_exceptions,
|
7
|
-
|
7
|
+
S2Message,
|
8
8
|
)
|
9
9
|
|
10
10
|
|
11
11
|
@catch_and_convert_exceptions
|
12
12
|
class FRBCLeakageBehaviourElement(
|
13
|
-
GenFRBCLeakageBehaviourElement,
|
13
|
+
GenFRBCLeakageBehaviourElement, S2Message["FRBCLeakageBehaviourElement"]
|
14
14
|
):
|
15
15
|
class Config(GenFRBCLeakageBehaviourElement.Config):
|
16
16
|
validate_assignment = True
|
@@ -1,21 +1,21 @@
|
|
1
1
|
# from itertools import pairwise
|
2
2
|
import uuid
|
3
|
-
from typing import List, Dict, Any
|
3
|
+
from typing import List, Dict, Any
|
4
4
|
|
5
5
|
from pydantic import root_validator
|
6
6
|
|
7
7
|
from s2python.common import NumberRange
|
8
|
-
from s2python.frbc import FRBCOperationModeElement
|
8
|
+
from s2python.frbc.frbc_operation_mode_element import FRBCOperationModeElement
|
9
9
|
from s2python.generated.gen_s2 import FRBCOperationMode as GenFRBCOperationMode
|
10
10
|
from s2python.validate_values_mixin import (
|
11
|
-
|
11
|
+
S2Message,
|
12
12
|
catch_and_convert_exceptions,
|
13
13
|
)
|
14
14
|
from s2python.utils import pairwise
|
15
15
|
|
16
16
|
|
17
17
|
@catch_and_convert_exceptions
|
18
|
-
class FRBCOperationMode(GenFRBCOperationMode,
|
18
|
+
class FRBCOperationMode(GenFRBCOperationMode, S2Message["FRBCOperationMode"]):
|
19
19
|
class Config(GenFRBCOperationMode.Config):
|
20
20
|
validate_assignment = True
|
21
21
|
|
@@ -25,6 +25,7 @@ class FRBCOperationMode(GenFRBCOperationMode, ValidateValuesMixin["FRBCOperation
|
|
25
25
|
].field_info # type: ignore[assignment]
|
26
26
|
|
27
27
|
@root_validator(pre=False)
|
28
|
+
@classmethod
|
28
29
|
def validate_contiguous_fill_levels_operation_mode_elements(
|
29
30
|
cls, values: Dict[str, Any]
|
30
31
|
) -> Dict[str, Any]:
|
@@ -5,14 +5,14 @@ from s2python.generated.gen_s2 import (
|
|
5
5
|
FRBCOperationModeElement as GenFRBCOperationModeElement,
|
6
6
|
)
|
7
7
|
from s2python.validate_values_mixin import (
|
8
|
-
|
8
|
+
S2Message,
|
9
9
|
catch_and_convert_exceptions,
|
10
10
|
)
|
11
11
|
|
12
12
|
|
13
13
|
@catch_and_convert_exceptions
|
14
14
|
class FRBCOperationModeElement(
|
15
|
-
GenFRBCOperationModeElement,
|
15
|
+
GenFRBCOperationModeElement, S2Message["FRBCOperationModeElement"]
|
16
16
|
):
|
17
17
|
class Config(GenFRBCOperationModeElement.Config):
|
18
18
|
validate_assignment = True
|
@@ -4,13 +4,13 @@ from s2python.generated.gen_s2 import (
|
|
4
4
|
)
|
5
5
|
from s2python.validate_values_mixin import (
|
6
6
|
catch_and_convert_exceptions,
|
7
|
-
|
7
|
+
S2Message,
|
8
8
|
)
|
9
9
|
|
10
10
|
|
11
11
|
@catch_and_convert_exceptions
|
12
12
|
class FRBCStorageDescription(
|
13
|
-
GenFRBCStorageDescription,
|
13
|
+
GenFRBCStorageDescription, S2Message["FRBCStorageDescription"]
|
14
14
|
):
|
15
15
|
class Config(GenFRBCStorageDescription.Config):
|
16
16
|
validate_assignment = True
|
@@ -3,12 +3,12 @@ import uuid
|
|
3
3
|
from s2python.generated.gen_s2 import FRBCStorageStatus as GenFRBCStorageStatus
|
4
4
|
from s2python.validate_values_mixin import (
|
5
5
|
catch_and_convert_exceptions,
|
6
|
-
|
6
|
+
S2Message,
|
7
7
|
)
|
8
8
|
|
9
9
|
|
10
10
|
@catch_and_convert_exceptions
|
11
|
-
class FRBCStorageStatus(GenFRBCStorageStatus,
|
11
|
+
class FRBCStorageStatus(GenFRBCStorageStatus, S2Message["FRBCStorageStatus"]):
|
12
12
|
class Config(GenFRBCStorageStatus.Config):
|
13
13
|
validate_assignment = True
|
14
14
|
|
@@ -4,14 +4,15 @@ import uuid
|
|
4
4
|
from s2python.generated.gen_s2 import FRBCSystemDescription as GenFRBCSystemDescription
|
5
5
|
from s2python.validate_values_mixin import (
|
6
6
|
catch_and_convert_exceptions,
|
7
|
-
|
7
|
+
S2Message,
|
8
8
|
)
|
9
|
-
from s2python.frbc import FRBCActuatorDescription
|
9
|
+
from s2python.frbc.frbc_actuator_description import FRBCActuatorDescription
|
10
|
+
from s2python.frbc.frbc_storage_description import FRBCStorageDescription
|
10
11
|
|
11
12
|
|
12
13
|
@catch_and_convert_exceptions
|
13
14
|
class FRBCSystemDescription(
|
14
|
-
GenFRBCSystemDescription,
|
15
|
+
GenFRBCSystemDescription, S2Message["FRBCSystemDescription"]
|
15
16
|
):
|
16
17
|
class Config(GenFRBCSystemDescription.Config):
|
17
18
|
validate_assignment = True
|
@@ -3,12 +3,12 @@ import uuid
|
|
3
3
|
from s2python.generated.gen_s2 import FRBCTimerStatus as GenFRBCTimerStatus
|
4
4
|
from s2python.validate_values_mixin import (
|
5
5
|
catch_and_convert_exceptions,
|
6
|
-
|
6
|
+
S2Message,
|
7
7
|
)
|
8
8
|
|
9
9
|
|
10
10
|
@catch_and_convert_exceptions
|
11
|
-
class FRBCTimerStatus(GenFRBCTimerStatus,
|
11
|
+
class FRBCTimerStatus(GenFRBCTimerStatus, S2Message["FRBCTimerStatus"]):
|
12
12
|
class Config(GenFRBCTimerStatus.Config):
|
13
13
|
validate_assignment = True
|
14
14
|
|
@@ -4,13 +4,13 @@ import uuid
|
|
4
4
|
from s2python.generated.gen_s2 import FRBCUsageForecast as GenFRBCUsageForecast
|
5
5
|
from s2python.validate_values_mixin import (
|
6
6
|
catch_and_convert_exceptions,
|
7
|
-
|
7
|
+
S2Message,
|
8
8
|
)
|
9
|
-
from s2python.frbc import FRBCUsageForecastElement
|
9
|
+
from s2python.frbc.frbc_usage_forecast_element import FRBCUsageForecastElement
|
10
10
|
|
11
11
|
|
12
12
|
@catch_and_convert_exceptions
|
13
|
-
class FRBCUsageForecast(GenFRBCUsageForecast,
|
13
|
+
class FRBCUsageForecast(GenFRBCUsageForecast, S2Message["FRBCUsageForecast"]):
|
14
14
|
class Config(GenFRBCUsageForecast.Config):
|
15
15
|
validate_assignment = True
|
16
16
|
|
@@ -5,13 +5,13 @@ from s2python.generated.gen_s2 import (
|
|
5
5
|
)
|
6
6
|
from s2python.validate_values_mixin import (
|
7
7
|
catch_and_convert_exceptions,
|
8
|
-
|
8
|
+
S2Message,
|
9
9
|
)
|
10
10
|
|
11
11
|
|
12
12
|
@catch_and_convert_exceptions
|
13
13
|
class FRBCUsageForecastElement(
|
14
|
-
GenFRBCUsageForecastElement,
|
14
|
+
GenFRBCUsageForecastElement, S2Message["FRBCUsageForecastElement"]
|
15
15
|
):
|
16
16
|
class Config(GenFRBCUsageForecastElement.Config):
|
17
17
|
validate_assignment = True
|
s2python/s2_parser.py
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
import json
|
2
|
+
import logging
|
3
|
+
from typing import Optional, TypeVar, Union, Type, Dict
|
4
|
+
|
5
|
+
from s2python.common import (
|
6
|
+
Handshake,
|
7
|
+
HandshakeResponse,
|
8
|
+
InstructionStatusUpdate,
|
9
|
+
PowerForecast,
|
10
|
+
PowerMeasurement,
|
11
|
+
ReceptionStatus,
|
12
|
+
ResourceManagerDetails,
|
13
|
+
RevokeObject,
|
14
|
+
SelectControlType,
|
15
|
+
SessionRequest,
|
16
|
+
)
|
17
|
+
from s2python.frbc import (
|
18
|
+
FRBCActuatorStatus,
|
19
|
+
FRBCFillLevelTargetProfile,
|
20
|
+
FRBCInstruction,
|
21
|
+
FRBCLeakageBehaviour,
|
22
|
+
FRBCStorageStatus,
|
23
|
+
FRBCSystemDescription,
|
24
|
+
FRBCTimerStatus,
|
25
|
+
FRBCUsageForecast,
|
26
|
+
)
|
27
|
+
from s2python.validate_values_mixin import S2Message
|
28
|
+
from s2python.s2_validation_error import S2ValidationError
|
29
|
+
|
30
|
+
|
31
|
+
LOGGER = logging.getLogger(__name__)
|
32
|
+
S2MessageType = str
|
33
|
+
|
34
|
+
M = TypeVar("M", bound=S2Message)
|
35
|
+
|
36
|
+
|
37
|
+
# May be generated with development_utilities/generate_s2_message_type_to_class.py
|
38
|
+
TYPE_TO_MESSAGE_CLASS: Dict[str, Type[S2Message]] = {
|
39
|
+
"FRBC.ActuatorStatus": FRBCActuatorStatus,
|
40
|
+
"FRBC.FillLevelTargetProfile": FRBCFillLevelTargetProfile,
|
41
|
+
"FRBC.Instruction": FRBCInstruction,
|
42
|
+
"FRBC.LeakageBehaviour": FRBCLeakageBehaviour,
|
43
|
+
"FRBC.StorageStatus": FRBCStorageStatus,
|
44
|
+
"FRBC.SystemDescription": FRBCSystemDescription,
|
45
|
+
"FRBC.TimerStatus": FRBCTimerStatus,
|
46
|
+
"FRBC.UsageForecast": FRBCUsageForecast,
|
47
|
+
"Handshake": Handshake,
|
48
|
+
"HandshakeResponse": HandshakeResponse,
|
49
|
+
"InstructionStatusUpdate": InstructionStatusUpdate,
|
50
|
+
"PowerForecast": PowerForecast,
|
51
|
+
"PowerMeasurement": PowerMeasurement,
|
52
|
+
"ReceptionStatus": ReceptionStatus,
|
53
|
+
"ResourceManagerDetails": ResourceManagerDetails,
|
54
|
+
"RevokeObject": RevokeObject,
|
55
|
+
"SelectControlType": SelectControlType,
|
56
|
+
"SessionRequest": SessionRequest,
|
57
|
+
}
|
58
|
+
|
59
|
+
|
60
|
+
class S2Parser:
|
61
|
+
@staticmethod
|
62
|
+
def _parse_json_if_required(unparsed_message: Union[dict, str]) -> dict:
|
63
|
+
if isinstance(unparsed_message, str):
|
64
|
+
return json.loads(unparsed_message)
|
65
|
+
return unparsed_message
|
66
|
+
|
67
|
+
@staticmethod
|
68
|
+
def parse_as_any_message(unparsed_message: Union[dict, str]) -> S2Message:
|
69
|
+
"""Parse the message as any S2 python message regardless of message type.
|
70
|
+
|
71
|
+
:param unparsed_message: The message as a JSON-formatted string or as a json-parsed dictionary.
|
72
|
+
:raises: S2ValidationError, json.JSONDecodeError
|
73
|
+
:return: The parsed S2 message if no errors were found.
|
74
|
+
"""
|
75
|
+
message_json = S2Parser._parse_json_if_required(unparsed_message)
|
76
|
+
message_type = S2Parser.parse_message_type(message_json)
|
77
|
+
|
78
|
+
if message_type not in TYPE_TO_MESSAGE_CLASS:
|
79
|
+
raise S2ValidationError(
|
80
|
+
message_json,
|
81
|
+
f"Unable to parse {message_type} as an S2 message. Type unknown.",
|
82
|
+
)
|
83
|
+
|
84
|
+
return TYPE_TO_MESSAGE_CLASS[message_type].parse_obj(message_json)
|
85
|
+
|
86
|
+
@staticmethod
|
87
|
+
def parse_as_message(unparsed_message: Union[dict, str], as_message: Type[M]) -> M:
|
88
|
+
"""Parse the message to a specific S2 python message.
|
89
|
+
|
90
|
+
:param unparsed_message: The message as a JSON-formatted string or as a JSON-parsed dictionary.
|
91
|
+
:param as_message: The type of message that is expected within the `message`
|
92
|
+
:raises: S2ValidationError, json.JSONDecodeError
|
93
|
+
:return: The parsed S2 message if no errors were found.
|
94
|
+
"""
|
95
|
+
message_json = S2Parser._parse_json_if_required(unparsed_message)
|
96
|
+
return as_message.from_dict(message_json)
|
97
|
+
|
98
|
+
@staticmethod
|
99
|
+
def parse_message_type(
|
100
|
+
unparsed_message: Union[dict, str]
|
101
|
+
) -> Optional[S2MessageType]:
|
102
|
+
"""Parse only the message type from the unparsed message.
|
103
|
+
|
104
|
+
This is useful to call before `parse_as_message` to retrieve the message type and allows for strictly-typed
|
105
|
+
parsing.
|
106
|
+
|
107
|
+
:param unparsed_message: The message as a JSON-formatted string or as a JSON-parsed dictionary.
|
108
|
+
:raises: json.JSONDecodeError
|
109
|
+
:return: The parsed S2 message type if no errors were found.
|
110
|
+
"""
|
111
|
+
message_json = S2Parser._parse_json_if_required(unparsed_message)
|
112
|
+
|
113
|
+
return message_json.get("message_type")
|
s2python/s2_validation_error.py
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
+
from typing import Union
|
2
|
+
|
1
3
|
from pydantic import ValidationError
|
2
4
|
|
3
5
|
|
4
6
|
class S2ValidationError(Exception):
|
5
7
|
obj: object
|
6
8
|
msg: str
|
7
|
-
pydantic_validation_error:
|
9
|
+
pydantic_validation_error: Union[ValidationError, TypeError, None]
|
8
10
|
|
9
11
|
def __init__(self, obj: object, msg: str):
|
10
12
|
self.obj = obj
|
s2python/utils.py
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
-
|
1
|
+
from typing import Generator, Tuple, List, TypeVar
|
2
|
+
|
3
|
+
P = TypeVar("P")
|
4
|
+
|
5
|
+
|
6
|
+
def pairwise(arr: List[P]) -> Generator[Tuple[P, P], None, None]:
|
2
7
|
for i in range(max(len(arr) - 1, 0)):
|
3
|
-
yield
|
8
|
+
yield arr[i], arr[i + 1]
|
@@ -3,10 +3,8 @@ from typing import (
|
|
3
3
|
Generic,
|
4
4
|
Protocol,
|
5
5
|
Type,
|
6
|
-
Tuple,
|
7
6
|
Optional,
|
8
7
|
Callable,
|
9
|
-
cast,
|
10
8
|
Any,
|
11
9
|
Union,
|
12
10
|
AbstractSet,
|
@@ -15,31 +13,41 @@ from typing import (
|
|
15
13
|
Dict,
|
16
14
|
)
|
17
15
|
|
18
|
-
from pydantic import
|
16
|
+
from pydantic import ( # pylint: disable=no-name-in-module
|
17
|
+
BaseModel,
|
18
|
+
StrBytes,
|
19
|
+
Protocol as PydanticProtocol,
|
20
|
+
ValidationError,
|
21
|
+
)
|
22
|
+
from pydantic.error_wrappers import display_errors # pylint: disable=no-name-in-module
|
19
23
|
|
20
24
|
from s2python.s2_validation_error import S2ValidationError
|
21
25
|
|
22
|
-
|
26
|
+
B_co = TypeVar("B_co", bound=BaseModel, covariant=True)
|
23
27
|
|
24
28
|
IntStr = Union[int, str]
|
25
29
|
AbstractSetIntStr = AbstractSet[IntStr]
|
26
30
|
MappingIntStrAny = Mapping[IntStr, Any]
|
27
31
|
|
28
32
|
|
29
|
-
class SupportsValidation(Protocol[
|
33
|
+
class SupportsValidation(Protocol[B_co]):
|
30
34
|
# ValidateValuesMixin methods
|
31
35
|
def to_json(self) -> str:
|
32
36
|
...
|
33
37
|
|
34
|
-
def to_dict(self) ->
|
38
|
+
def to_dict(self) -> Dict:
|
39
|
+
...
|
40
|
+
|
41
|
+
@classmethod
|
42
|
+
def from_json(cls, json_str: str) -> B_co:
|
35
43
|
...
|
36
44
|
|
37
45
|
@classmethod
|
38
|
-
def
|
46
|
+
def from_dict(cls, json_dict: Dict) -> B_co:
|
39
47
|
...
|
40
48
|
|
41
49
|
# Pydantic methods
|
42
|
-
def json(
|
50
|
+
def json( # pylint: disable=too-many-arguments
|
43
51
|
self,
|
44
52
|
*,
|
45
53
|
include: Optional[Union["AbstractSetIntStr", "MappingIntStrAny"]] = None,
|
@@ -55,7 +63,7 @@ class SupportsValidation(Protocol[B]):
|
|
55
63
|
) -> str:
|
56
64
|
...
|
57
65
|
|
58
|
-
def dict(
|
66
|
+
def dict( # pylint: disable=too-many-arguments
|
59
67
|
self,
|
60
68
|
*,
|
61
69
|
include: Optional[Union["AbstractSetIntStr", "MappingIntStrAny"]] = None,
|
@@ -69,7 +77,7 @@ class SupportsValidation(Protocol[B]):
|
|
69
77
|
...
|
70
78
|
|
71
79
|
@classmethod
|
72
|
-
def parse_raw(
|
80
|
+
def parse_raw( # pylint: disable=too-many-arguments
|
73
81
|
cls,
|
74
82
|
b: StrBytes,
|
75
83
|
*,
|
@@ -77,7 +85,11 @@ class SupportsValidation(Protocol[B]):
|
|
77
85
|
encoding: str = ...,
|
78
86
|
proto: PydanticProtocol = ...,
|
79
87
|
allow_pickle: bool = ...,
|
80
|
-
) ->
|
88
|
+
) -> B_co:
|
89
|
+
...
|
90
|
+
|
91
|
+
@classmethod
|
92
|
+
def parse_obj(cls, obj: Any) -> "B_co":
|
81
93
|
...
|
82
94
|
|
83
95
|
|
@@ -101,15 +113,24 @@ class ValidateValuesMixin(Generic[C]):
|
|
101
113
|
gen_model: C = cls.parse_raw(json_str)
|
102
114
|
return gen_model
|
103
115
|
|
116
|
+
@classmethod
|
117
|
+
def from_dict(cls: Type[C], json_dict: dict) -> C:
|
118
|
+
gen_model: C = cls.parse_obj(json_dict)
|
119
|
+
return gen_model
|
120
|
+
|
121
|
+
|
122
|
+
class S2Message(Generic[C], ValidateValuesMixin[C], BaseModel):
|
123
|
+
pass
|
124
|
+
|
104
125
|
|
105
126
|
def convert_to_s2exception(f: Callable) -> Callable:
|
106
127
|
def inner(*args: List[Any], **kwargs: Dict[str, Any]) -> Any:
|
107
128
|
try:
|
108
129
|
return f(*args, **kwargs)
|
109
|
-
except
|
110
|
-
raise S2ValidationError(
|
111
|
-
|
112
|
-
) from e
|
130
|
+
except ValidationError as e:
|
131
|
+
raise S2ValidationError(args, display_errors(e.errors())) from e
|
132
|
+
except TypeError as e:
|
133
|
+
raise S2ValidationError(args, str(e)) from e
|
113
134
|
|
114
135
|
inner.__doc__ = f.__doc__
|
115
136
|
inner.__annotations__ = f.__annotations__
|
@@ -118,8 +139,8 @@ def convert_to_s2exception(f: Callable) -> Callable:
|
|
118
139
|
|
119
140
|
|
120
141
|
def catch_and_convert_exceptions(
|
121
|
-
input_class: Type[SupportsValidation[
|
122
|
-
) -> Type[SupportsValidation[
|
142
|
+
input_class: Type[SupportsValidation[B_co]],
|
143
|
+
) -> Type[SupportsValidation[B_co]]:
|
123
144
|
input_class.__init__ = convert_to_s2exception(input_class.__init__) # type: ignore[method-assign]
|
124
145
|
input_class.__setattr__ = convert_to_s2exception(input_class.__setattr__) # type: ignore[method-assign]
|
125
146
|
input_class.parse_raw = convert_to_s2exception(input_class.parse_raw) # type: ignore[method-assign]
|
s2_python-0.0.1.dist-info/RECORD
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
s2python/__init__.py,sha256=aLCMCipFsPGFEsc8ritsDiYDSUBTW5kA34N_3po08p8,352
|
2
|
-
s2python/s2_validation_error.py,sha256=Veij_ReS0VCTC8fCRhxTgmZVVMCUiBu2VmtzYjJ6NBc,266
|
3
|
-
s2python/utils.py,sha256=YJw3-i4fD_ud7rbm68VWE3PRjp-EgsnS_YtMxf6UnhA,102
|
4
|
-
s2python/validate_values_mixin.py,sha256=CfRXeSkAOBBcS8zy4eNl3dx-01Sm6Wgn0bgTEhsdZks,3448
|
5
|
-
s2python/version.py,sha256=w9Iw7QVvd8lme2wKwEbCo5IgetVjSfFBOOYAcA_Q0Ns,18
|
6
|
-
s2python/common/__init__.py,sha256=fVJ0n13kRzzAtJcOxZHz3CEDexWXnyueJMcEXGdq_88,1345
|
7
|
-
s2python/common/duration.py,sha256=-0_llJYXD5Z6Sx96XgY_unH3vcyCfhddxERAM7-8CGg,681
|
8
|
-
s2python/common/handshake.py,sha256=v1JoZaYIk1faZFCAuf8sINq0xR_W03RaHhjkLODYLg4,460
|
9
|
-
s2python/common/handshake_response.py,sha256=0o7miKQCWJ8cXFtvblQM81nUznyxZ2zrNrI22XAzTJg,516
|
10
|
-
s2python/common/instruction_status_update.py,sha256=AzhgyIdcgtwbCAqNtUamFDttrMbyoMEqGD3qB-bFAgc,714
|
11
|
-
s2python/common/number_range.py,sha256=b9KQ2XDyrcyqiHzN2rI7ldG-rsNk3b5os1BLDZOqTf4,1115
|
12
|
-
s2python/common/power_forecast.py,sha256=zrFzR7Apg8OBkP_GQo4kseT2ZMjlinYRnh_KXe1e8vw,697
|
13
|
-
s2python/common/power_forecast_element.py,sha256=MU6ndeMAkubJDrLfFON4IwyykCWHHqloQ_GvZp1Y-bo,756
|
14
|
-
s2python/common/power_forecast_value.py,sha256=UP3IoyZVpkVhYrpN4CZvQHC8EQq7H_Q_S9BTs5us1KU,401
|
15
|
-
s2python/common/power_measurement.py,sha256=Tiyb8ROub8m-tGCBQuZ8JTYV3d4HlyhqapP5Upvssms,683
|
16
|
-
s2python/common/power_range.py,sha256=EQgFppktiusyZ6Ib7CKhx1-C167YQddgvVeu49xVY7o,751
|
17
|
-
s2python/common/power_value.py,sha256=rqKXBrBwNCRpF13fl8zVhacxUQYPYPC2WbeP0OXZwdM,347
|
18
|
-
s2python/common/reception_status.py,sha256=Vkj6ZzTkl-WYprszRStBuHIyKfoJW-gYp6NK6MuEwRo,532
|
19
|
-
s2python/common/resource_manager_details.py,sha256=tDbR8hfaQ4Nz8po954HNm0YSJW95C7JomwTW1t5q33A,1029
|
20
|
-
s2python/common/revoke_object.py,sha256=0KHb8klzsREE5oB1XwdXxBP_MIb3cQUDAz8V-Uv3moQ,587
|
21
|
-
s2python/common/role.py,sha256=Vk732JKk05jOb6wPkG18me34kFT1MngKnLg1a8VWq5I,311
|
22
|
-
s2python/common/select_control_type.py,sha256=bgZw9oePLBLAN7TEWwNsqMvO2zQMj3PdFUZ-KuqZfJk,516
|
23
|
-
s2python/common/session_request.py,sha256=iDjW5HwDbAuwaJmpJROQAW3vqgNJddsLOKejWDPdbVc,495
|
24
|
-
s2python/common/support.py,sha256=L08puzgMLvslKRqVQAnXH_Q5YRT5HTOPj8vDDNyzNYc,988
|
25
|
-
s2python/common/timer.py,sha256=o2L48hefqC8cu6FAgjavjWMMnI8OxOHizP5zfL1abHY,558
|
26
|
-
s2python/common/transition.py,sha256=k34bSvf8eU1Ys9SZkZKSye-NcxdSAqKjoWCNiT-8uxM,1107
|
27
|
-
s2python/frbc/__init__.py,sha256=ROV3qZoldPkdgVFfMQr5Mf3GDfBzXaMfhNNCuXY6T0s,1104
|
28
|
-
s2python/frbc/frbc_actuator_description.py,sha256=v2pWCUSGaw4IftMhNOjeLXE8B86XZNCyiZr3dQkziuo,6699
|
29
|
-
s2python/frbc/frbc_actuator_status.py,sha256=Y8VUF0AA52tCG32qVb6jn93DMq0GPeaA9T5UPOm3m1c,999
|
30
|
-
s2python/frbc/frbc_fill_level_target_profile.py,sha256=s-SqjWCEFc9oDm4zUW4RiFEnyWXh6HNlZgSF5P9kHHc,868
|
31
|
-
s2python/frbc/frbc_fill_level_target_profile_element.py,sha256=0R2rJ8-rm-2igLgIdZI0SXMt450Ah0i54CBzehVxyI0,852
|
32
|
-
s2python/frbc/frbc_instruction.py,sha256=uXKec7nUsQBmAkS6slBiyZ_1lo2i6cpuljRC_eV7LK8,829
|
33
|
-
s2python/frbc/frbc_leakage_behaviour.py,sha256=4TnFHsP-wdtHGpWJ1xauE3H2Q_N5FLflG6YJvuKYpcA,771
|
34
|
-
s2python/frbc/frbc_leakage_behaviour_element.py,sha256=Z7d8rELLnQDx-qGAVVtuoNnWHyj1CUYG_FOliBOpqwk,656
|
35
|
-
s2python/frbc/frbc_operation_mode.py,sha256=DlQa4cRQKmPRoWmabpa9j3A8U0dBQRkEQHG5r7Y4VoM,2023
|
36
|
-
s2python/frbc/frbc_operation_mode_element.py,sha256=8Cfp7sTHT4n0KQmFdnWCdzUgPW09NDUm3NL3RBBl2Uc,1099
|
37
|
-
s2python/frbc/frbc_storage_description.py,sha256=AMuVZpRk5Pvxx6SnKg9WyELD8kqRJbAmJ1JL5tT0gdk,621
|
38
|
-
s2python/frbc/frbc_storage_status.py,sha256=zMgdLYrAgv6Jne5oKWgGMFhUIbJegX501Rskaz_a5-g,516
|
39
|
-
s2python/frbc/frbc_system_description.py,sha256=SGxtRNTlBw3-SU5A8J6Y2cxdYLSZiztR2RdrstUwCSc,935
|
40
|
-
s2python/frbc/frbc_timer_status.py,sha256=RxbnLzAFJy-OXwwFbQ0QpzRcJ2awmysLcapzjDEU0K8,722
|
41
|
-
s2python/frbc/frbc_usage_forecast.py,sha256=-bm6XSDq_wkbGeBj_d1i-C1RdaZpIfD1yJqZ6mWX4bw,735
|
42
|
-
s2python/frbc/frbc_usage_forecast_element.py,sha256=bgFG01udYSizOyoGZPIPom0vj_dB3qokffU8hZ7BbC8,600
|
43
|
-
s2python/generated/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
44
|
-
s2python/generated/gen_s2.py,sha256=DXLCNE1gUS7XnRTgWlBpy73szr5HrHcrN0TZXvq8N_g,61928
|
45
|
-
s2_python-0.0.1.dist-info/METADATA,sha256=7PixoPcZdw86h9LfGGX2ithyEEhyipz2IlP0-b3LWmw,2855
|
46
|
-
s2_python-0.0.1.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
|
47
|
-
s2_python-0.0.1.dist-info/entry_points.txt,sha256=feX-xmgJZgSe5-jxMgFKPKCJz4Ys3eQcGrsXsirNZyM,61
|
48
|
-
s2_python-0.0.1.dist-info/top_level.txt,sha256=OLFq0oDhr77Mp-EYLEcWk5P3jvooOt4IHkTI5KYJMc8,9
|
49
|
-
s2_python-0.0.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|