s2-python 0.1.0__tar.gz → 0.2.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 (77) hide show
  1. {s2-python-0.1.0 → s2_python-0.2.0}/PKG-INFO +4 -2
  2. {s2-python-0.1.0 → s2_python-0.2.0}/setup.cfg +5 -3
  3. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2_python.egg-info/PKG-INFO +4 -2
  4. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2_python.egg-info/SOURCES.txt +4 -0
  5. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2_python.egg-info/requires.txt +2 -1
  6. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2python/common/duration.py +3 -3
  7. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2python/common/handshake.py +3 -3
  8. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2python/common/handshake_response.py +3 -3
  9. s2_python-0.2.0/src/s2python/common/instruction_status_update.py +18 -0
  10. s2_python-0.2.0/src/s2python/common/number_range.py +32 -0
  11. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2python/common/power_forecast.py +4 -6
  12. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2python/common/power_forecast_element.py +5 -5
  13. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2python/common/power_forecast_value.py +2 -2
  14. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2python/common/power_measurement.py +4 -4
  15. s2_python-0.2.0/src/s2python/common/power_range.py +22 -0
  16. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2python/common/power_value.py +2 -2
  17. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2python/common/reception_status.py +3 -5
  18. s2_python-0.2.0/src/s2python/common/resource_manager_details.py +25 -0
  19. s2_python-0.2.0/src/s2python/common/revoke_object.py +16 -0
  20. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2python/common/role.py +2 -2
  21. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2python/common/select_control_type.py +3 -3
  22. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2python/common/session_request.py +3 -3
  23. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2python/common/timer.py +4 -4
  24. s2_python-0.2.0/src/s2python/common/transition.py +24 -0
  25. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2python/frbc/frbc_actuator_description.py +52 -79
  26. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2python/frbc/frbc_actuator_status.py +8 -8
  27. s2_python-0.2.0/src/s2python/frbc/frbc_fill_level_target_profile.py +24 -0
  28. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2python/frbc/frbc_fill_level_target_profile_element.py +5 -7
  29. s2_python-0.2.0/src/s2python/frbc/frbc_instruction.py +18 -0
  30. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2python/frbc/frbc_leakage_behaviour.py +5 -5
  31. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2python/frbc/frbc_leakage_behaviour_element.py +5 -7
  32. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2python/frbc/frbc_operation_mode.py +16 -27
  33. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2python/frbc/frbc_operation_mode_element.py +10 -12
  34. s2_python-0.2.0/src/s2python/frbc/frbc_storage_description.py +18 -0
  35. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2python/frbc/frbc_storage_status.py +3 -3
  36. s2_python-0.2.0/src/s2python/frbc/frbc_system_description.py +22 -0
  37. s2_python-0.2.0/src/s2python/frbc/frbc_timer_status.py +17 -0
  38. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2python/frbc/frbc_usage_forecast.py +4 -6
  39. s2_python-0.2.0/src/s2python/frbc/frbc_usage_forecast_element.py +17 -0
  40. s2_python-0.2.0/src/s2python/generated/__init__.py +0 -0
  41. s2_python-0.2.0/src/s2python/generated/gen_s2.py +1611 -0
  42. s2_python-0.2.0/src/s2python/reception_status_awaiter.py +60 -0
  43. s2_python-0.2.0/src/s2python/s2_connection.py +470 -0
  44. s2_python-0.2.0/src/s2python/s2_control_type.py +56 -0
  45. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2python/s2_parser.py +8 -8
  46. s2_python-0.2.0/src/s2python/s2_validation_error.py +13 -0
  47. s2_python-0.2.0/src/s2python/validate_values_mixin.py +70 -0
  48. s2_python-0.2.0/src/s2python/version.py +3 -0
  49. s2-python-0.1.0/src/s2python/common/instruction_status_update.py +0 -22
  50. s2-python-0.1.0/src/s2python/common/number_range.py +0 -39
  51. s2-python-0.1.0/src/s2python/common/power_range.py +0 -27
  52. s2-python-0.1.0/src/s2python/common/resource_manager_details.py +0 -27
  53. s2-python-0.1.0/src/s2python/common/revoke_object.py +0 -16
  54. s2-python-0.1.0/src/s2python/common/transition.py +0 -26
  55. s2-python-0.1.0/src/s2python/frbc/frbc_fill_level_target_profile.py +0 -30
  56. s2-python-0.1.0/src/s2python/frbc/frbc_instruction.py +0 -18
  57. s2-python-0.1.0/src/s2python/frbc/frbc_storage_description.py +0 -20
  58. s2-python-0.1.0/src/s2python/frbc/frbc_system_description.py +0 -26
  59. s2-python-0.1.0/src/s2python/frbc/frbc_timer_status.py +0 -17
  60. s2-python-0.1.0/src/s2python/frbc/frbc_usage_forecast_element.py +0 -19
  61. s2-python-0.1.0/src/s2python/generated/gen_s2.py +0 -1591
  62. s2-python-0.1.0/src/s2python/s2_validation_error.py +0 -13
  63. s2-python-0.1.0/src/s2python/validate_values_mixin.py +0 -148
  64. s2-python-0.1.0/src/s2python/version.py +0 -1
  65. {s2-python-0.1.0 → s2_python-0.2.0}/README.rst +0 -0
  66. {s2-python-0.1.0 → s2_python-0.2.0}/pyproject.toml +0 -0
  67. {s2-python-0.1.0 → s2_python-0.2.0}/setup.py +0 -0
  68. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2_python.egg-info/dependency_links.txt +0 -0
  69. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2_python.egg-info/entry_points.txt +0 -0
  70. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2_python.egg-info/not-zip-safe +0 -0
  71. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2_python.egg-info/top_level.txt +0 -0
  72. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2python/__init__.py +0 -0
  73. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2python/common/__init__.py +1 -1
  74. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2python/common/support.py +0 -0
  75. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2python/frbc/__init__.py +0 -0
  76. /s2-python-0.1.0/src/s2python/generated/__init__.py → /s2_python-0.2.0/src/s2python/frbc/rm.py +0 -0
  77. {s2-python-0.1.0 → s2_python-0.2.0}/src/s2python/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: s2-python
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: S2 Protocol Python Wrapper
5
5
  Home-page: https://github.com/flexiblepower/s2-ws-json-python
6
6
  Author: Flexiblepower
@@ -12,10 +12,12 @@ Classifier: Programming Language :: Python :: 3.8
12
12
  Classifier: Programming Language :: Python :: 3.9
13
13
  Classifier: Programming Language :: Python :: 3.10
14
14
  Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
15
16
  Description-Content-Type: text/x-rst; charset=UTF-8
16
- Requires-Dist: pydantic~=1.10.7
17
+ Requires-Dist: pydantic~=2.8.2
17
18
  Requires-Dist: pytz
18
19
  Requires-Dist: click
20
+ Requires-Dist: websockets~=13.0.1
19
21
  Provides-Extra: testing
20
22
  Requires-Dist: pytest; extra == "testing"
21
23
  Requires-Dist: pytest-coverage; extra == "testing"
@@ -8,7 +8,7 @@ license_files = LICENSE.txt
8
8
  long_description = file: README.rst
9
9
  long_description_content_type = text/x-rst; charset=UTF-8
10
10
  url = https://github.com/flexiblepower/s2-ws-json-python
11
- version = 0.1.0
11
+ version = 0.2.0
12
12
  platforms = Linux
13
13
  classifiers =
14
14
  Development Status :: 4 - Beta
@@ -16,6 +16,7 @@ classifiers =
16
16
  Programming Language :: Python :: 3.9
17
17
  Programming Language :: Python :: 3.10
18
18
  Programming Language :: Python :: 3.11
19
+ Programming Language :: Python :: 3.12
19
20
 
20
21
  [options]
21
22
  zip_safe = False
@@ -23,11 +24,12 @@ packages = find_namespace:
23
24
  include_package_data = True
24
25
  package_dir =
25
26
  =src
26
- python_requires > = 3.8, <= 3.11
27
+ python_requires > = 3.8, <= 3.12
27
28
  install_requires =
28
- pydantic~=1.10.7
29
+ pydantic~=2.8.2
29
30
  pytz
30
31
  click
32
+ websockets~=13.0.1
31
33
 
32
34
  [options.packages.find]
33
35
  where = src
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: s2-python
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: S2 Protocol Python Wrapper
5
5
  Home-page: https://github.com/flexiblepower/s2-ws-json-python
6
6
  Author: Flexiblepower
@@ -12,10 +12,12 @@ Classifier: Programming Language :: Python :: 3.8
12
12
  Classifier: Programming Language :: Python :: 3.9
13
13
  Classifier: Programming Language :: Python :: 3.10
14
14
  Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
15
16
  Description-Content-Type: text/x-rst; charset=UTF-8
16
- Requires-Dist: pydantic~=1.10.7
17
+ Requires-Dist: pydantic~=2.8.2
17
18
  Requires-Dist: pytz
18
19
  Requires-Dist: click
20
+ Requires-Dist: websockets~=13.0.1
19
21
  Provides-Extra: testing
20
22
  Requires-Dist: pytest; extra == "testing"
21
23
  Requires-Dist: pytest-coverage; extra == "testing"
@@ -10,6 +10,9 @@ src/s2_python.egg-info/not-zip-safe
10
10
  src/s2_python.egg-info/requires.txt
11
11
  src/s2_python.egg-info/top_level.txt
12
12
  src/s2python/__init__.py
13
+ src/s2python/reception_status_awaiter.py
14
+ src/s2python/s2_connection.py
15
+ src/s2python/s2_control_type.py
13
16
  src/s2python/s2_parser.py
14
17
  src/s2python/s2_validation_error.py
15
18
  src/s2python/utils.py
@@ -52,5 +55,6 @@ src/s2python/frbc/frbc_system_description.py
52
55
  src/s2python/frbc/frbc_timer_status.py
53
56
  src/s2python/frbc/frbc_usage_forecast.py
54
57
  src/s2python/frbc/frbc_usage_forecast_element.py
58
+ src/s2python/frbc/rm.py
55
59
  src/s2python/generated/__init__.py
56
60
  src/s2python/generated/gen_s2.py
@@ -1,6 +1,7 @@
1
- pydantic~=1.10.7
1
+ pydantic~=2.8.2
2
2
  pytz
3
3
  click
4
+ websockets~=13.0.1
4
5
 
5
6
  [development]
6
7
  pip-tools
@@ -11,12 +11,12 @@ from s2python.validate_values_mixin import (
11
11
  @catch_and_convert_exceptions
12
12
  class Duration(GenDuration, S2Message["Duration"]):
13
13
  def to_timedelta(self) -> timedelta:
14
- return timedelta(milliseconds=self.__root__)
14
+ return timedelta(milliseconds=self.root)
15
15
 
16
16
  @staticmethod
17
17
  def from_timedelta(duration: timedelta) -> "Duration":
18
- return Duration(__root__=math.ceil(duration.total_seconds() * 1000))
18
+ return Duration(root=math.ceil(duration.total_seconds() * 1000))
19
19
 
20
20
  @staticmethod
21
21
  def from_milliseconds(milliseconds: int) -> "Duration":
22
- return Duration(__root__=milliseconds)
22
+ return Duration(root=milliseconds)
@@ -9,7 +9,7 @@ from s2python.validate_values_mixin import (
9
9
 
10
10
  @catch_and_convert_exceptions
11
11
  class Handshake(GenHandshake, S2Message["Handshake"]):
12
- class Config(GenHandshake.Config):
13
- validate_assignment = True
12
+ model_config = GenHandshake.model_config
13
+ model_config["validate_assignment"] = True
14
14
 
15
- message_id: uuid.UUID = GenHandshake.__fields__["message_id"].field_info # type: ignore[assignment]
15
+ message_id: uuid.UUID = GenHandshake.model_fields["message_id"] # type: ignore[assignment]
@@ -9,7 +9,7 @@ from s2python.validate_values_mixin import (
9
9
 
10
10
  @catch_and_convert_exceptions
11
11
  class HandshakeResponse(GenHandshakeResponse, S2Message["HandshakeResponse"]):
12
- class Config(GenHandshakeResponse.Config):
13
- validate_assignment = True
12
+ model_config = GenHandshakeResponse.model_config
13
+ model_config["validate_assignment"] = True
14
14
 
15
- message_id: uuid.UUID = GenHandshakeResponse.__fields__["message_id"].field_info # type: ignore[assignment]
15
+ message_id: uuid.UUID = GenHandshakeResponse.model_fields["message_id"] # type: ignore[assignment]
@@ -0,0 +1,18 @@
1
+ import uuid
2
+
3
+ from s2python.generated.gen_s2 import (
4
+ InstructionStatusUpdate as GenInstructionStatusUpdate,
5
+ )
6
+ from s2python.validate_values_mixin import (
7
+ catch_and_convert_exceptions,
8
+ S2Message,
9
+ )
10
+
11
+
12
+ @catch_and_convert_exceptions
13
+ class InstructionStatusUpdate(GenInstructionStatusUpdate, S2Message["InstructionStatusUpdate"]):
14
+ model_config = GenInstructionStatusUpdate.model_config
15
+ model_config["validate_assignment"] = True
16
+
17
+ message_id: uuid.UUID = GenInstructionStatusUpdate.model_fields["message_id"] # type: ignore[assignment]
18
+ instruction_id: uuid.UUID = GenInstructionStatusUpdate.model_fields["instruction_id"] # type: ignore[assignment]
@@ -0,0 +1,32 @@
1
+ from typing import Any
2
+ from typing_extensions import Self
3
+
4
+ from pydantic import model_validator
5
+
6
+ from s2python.validate_values_mixin import (
7
+ S2Message,
8
+ catch_and_convert_exceptions,
9
+ )
10
+ from s2python.generated.gen_s2 import NumberRange as GenNumberRange
11
+
12
+
13
+ @catch_and_convert_exceptions
14
+ class NumberRange(GenNumberRange, S2Message["NumberRange"]):
15
+ model_config = GenNumberRange.model_config
16
+ model_config["validate_assignment"] = True
17
+
18
+ @model_validator(mode="after")
19
+ def validate_start_end_order(self) -> Self: # pylint: disable=duplicate-code
20
+ if self.start_of_range > self.end_of_range:
21
+ raise ValueError(self, "start_of_range should not be higher than end_of_range")
22
+
23
+ return self
24
+
25
+ def __hash__(self) -> int:
26
+ return hash(f"{self.start_of_range}|{self.end_of_range}")
27
+
28
+ def __eq__(self, other: Any) -> bool:
29
+ if isinstance(other, NumberRange):
30
+ return self.start_of_range == other.start_of_range and self.end_of_range == other.end_of_range
31
+
32
+ return False
@@ -11,10 +11,8 @@ from s2python.validate_values_mixin import (
11
11
 
12
12
  @catch_and_convert_exceptions
13
13
  class PowerForecast(GenPowerForecast, S2Message["PowerForecast"]):
14
- class Config(GenPowerForecast.Config):
15
- validate_assignment = True
14
+ model_config = GenPowerForecast.model_config
15
+ model_config["validate_assignment"] = True
16
16
 
17
- message_id: uuid.UUID = GenPowerForecast.__fields__["message_id"].field_info # type: ignore[assignment]
18
- elements: List[PowerForecastElement] = GenPowerForecast.__fields__[
19
- "elements"
20
- ].field_info # type: ignore[assignment]
17
+ message_id: uuid.UUID = GenPowerForecast.model_fields["message_id"] # type: ignore[assignment]
18
+ elements: List[PowerForecastElement] = GenPowerForecast.model_fields["elements"] # type: ignore[assignment]
@@ -11,10 +11,10 @@ from s2python.common.power_forecast_value import PowerForecastValue
11
11
 
12
12
  @catch_and_convert_exceptions
13
13
  class PowerForecastElement(GenPowerForecastElement, S2Message["PowerForecastElement"]):
14
- class Config(GenPowerForecastElement.Config):
15
- validate_assignment = True
14
+ model_config = GenPowerForecastElement.model_config
15
+ model_config["validate_assignment"] = True
16
16
 
17
- duration: Duration = GenPowerForecastElement.__fields__["duration"].field_info # type: ignore[assignment]
18
- power_values: List[PowerForecastValue] = GenPowerForecastElement.__fields__[
17
+ duration: Duration = GenPowerForecastElement.model_fields["duration"] # type: ignore[assignment]
18
+ power_values: List[PowerForecastValue] = GenPowerForecastElement.model_fields[
19
19
  "power_values"
20
- ].field_info # type: ignore[assignment]
20
+ ] # type: ignore[assignment]
@@ -7,5 +7,5 @@ from s2python.validate_values_mixin import (
7
7
 
8
8
  @catch_and_convert_exceptions
9
9
  class PowerForecastValue(GenPowerForecastValue, S2Message["PowerForecastValue"]):
10
- class Config(GenPowerForecastValue.Config):
11
- validate_assignment = True
10
+ model_config = GenPowerForecastValue.model_config
11
+ model_config["validate_assignment"] = True
@@ -11,8 +11,8 @@ from s2python.validate_values_mixin import (
11
11
 
12
12
  @catch_and_convert_exceptions
13
13
  class PowerMeasurement(GenPowerMeasurement, S2Message["PowerMeasurement"]):
14
- class Config(GenPowerMeasurement.Config):
15
- validate_assignment = True
14
+ model_config = GenPowerMeasurement.model_config
15
+ model_config["validate_assignment"] = True
16
16
 
17
- message_id: uuid.UUID = GenPowerMeasurement.__fields__["message_id"].field_info # type: ignore[assignment]
18
- values: List[PowerValue] = GenPowerMeasurement.__fields__["values"].field_info # type: ignore[assignment]
17
+ message_id: uuid.UUID = GenPowerMeasurement.model_fields["message_id"] # type: ignore[assignment]
18
+ values: List[PowerValue] = GenPowerMeasurement.model_fields["values"] # type: ignore[assignment]
@@ -0,0 +1,22 @@
1
+ from typing_extensions import Self
2
+
3
+ from pydantic import model_validator
4
+
5
+ from s2python.generated.gen_s2 import PowerRange as GenPowerRange
6
+ from s2python.validate_values_mixin import (
7
+ S2Message,
8
+ catch_and_convert_exceptions,
9
+ )
10
+
11
+
12
+ @catch_and_convert_exceptions
13
+ class PowerRange(GenPowerRange, S2Message["PowerRange"]):
14
+ model_config = GenPowerRange.model_config
15
+ model_config["validate_assignment"] = True
16
+
17
+ @model_validator(mode="after")
18
+ def validate_start_end_order(self) -> Self:
19
+ if self.start_of_range > self.end_of_range:
20
+ raise ValueError(self, "start_of_range should not be higher than end_of_range")
21
+
22
+ return self
@@ -7,5 +7,5 @@ from s2python.validate_values_mixin import (
7
7
 
8
8
  @catch_and_convert_exceptions
9
9
  class PowerValue(GenPowerValue, S2Message["PowerValue"]):
10
- class Config(GenPowerValue.Config):
11
- validate_assignment = True
10
+ model_config = GenPowerValue.model_config
11
+ model_config["validate_assignment"] = True
@@ -9,9 +9,7 @@ from s2python.validate_values_mixin import (
9
9
 
10
10
  @catch_and_convert_exceptions
11
11
  class ReceptionStatus(GenReceptionStatus, S2Message["ReceptionStatus"]):
12
- class Config(GenReceptionStatus.Config):
13
- validate_assignment = True
12
+ model_config = GenReceptionStatus.model_config
13
+ model_config["validate_assignment"] = True
14
14
 
15
- subject_message_id: uuid.UUID = GenReceptionStatus.__fields__[
16
- "subject_message_id"
17
- ].field_info # type: ignore[assignment]
15
+ subject_message_id: uuid.UUID = GenReceptionStatus.model_fields["subject_message_id"] # type: ignore[assignment]
@@ -0,0 +1,25 @@
1
+ from typing import List
2
+ import uuid
3
+
4
+ from s2python.common.duration import Duration
5
+ from s2python.common.role import Role
6
+ from s2python.generated.gen_s2 import (
7
+ ResourceManagerDetails as GenResourceManagerDetails,
8
+ )
9
+ from s2python.validate_values_mixin import (
10
+ catch_and_convert_exceptions,
11
+ S2Message,
12
+ )
13
+
14
+
15
+ @catch_and_convert_exceptions
16
+ class ResourceManagerDetails(GenResourceManagerDetails, S2Message["ResourceManagerDetails"]):
17
+ model_config = GenResourceManagerDetails.model_config
18
+ model_config["validate_assignment"] = True
19
+
20
+ instruction_processing_delay: Duration = GenResourceManagerDetails.model_fields[
21
+ "instruction_processing_delay"
22
+ ] # type: ignore[assignment]
23
+ message_id: uuid.UUID = GenResourceManagerDetails.model_fields["message_id"] # type: ignore[assignment]
24
+ resource_id: uuid.UUID = GenResourceManagerDetails.model_fields["resource_id"] # type: ignore[assignment]
25
+ roles: List[Role] = GenResourceManagerDetails.model_fields["roles"] # type: ignore[assignment]
@@ -0,0 +1,16 @@
1
+ import uuid
2
+
3
+ from s2python.generated.gen_s2 import RevokeObject as GenRevokeObject
4
+ from s2python.validate_values_mixin import (
5
+ catch_and_convert_exceptions,
6
+ S2Message,
7
+ )
8
+
9
+
10
+ @catch_and_convert_exceptions
11
+ class RevokeObject(GenRevokeObject, S2Message["RevokeObject"]):
12
+ model_config = GenRevokeObject.model_config
13
+ model_config["validate_assignment"] = True
14
+
15
+ message_id: uuid.UUID = GenRevokeObject.model_fields["message_id"] # type: ignore[assignment]
16
+ object_id: uuid.UUID = GenRevokeObject.model_fields["object_id"] # type: ignore[assignment]
@@ -7,5 +7,5 @@ from s2python.validate_values_mixin import (
7
7
 
8
8
  @catch_and_convert_exceptions
9
9
  class Role(GenRole, S2Message["Role"]):
10
- class Config(GenRole.Config):
11
- validate_assignment = True
10
+ model_config = GenRole.model_config
11
+ model_config["validate_assignment"] = True
@@ -9,7 +9,7 @@ from s2python.validate_values_mixin import (
9
9
 
10
10
  @catch_and_convert_exceptions
11
11
  class SelectControlType(GenSelectControlType, S2Message["SelectControlType"]):
12
- class Config(GenSelectControlType.Config):
13
- validate_assignment = True
12
+ model_config = GenSelectControlType.model_config
13
+ model_config["validate_assignment"] = True
14
14
 
15
- message_id: uuid.UUID = GenSelectControlType.__fields__["message_id"].field_info # type: ignore[assignment]
15
+ message_id: uuid.UUID = GenSelectControlType.model_fields["message_id"] # type: ignore[assignment]
@@ -9,7 +9,7 @@ from s2python.validate_values_mixin import (
9
9
 
10
10
  @catch_and_convert_exceptions
11
11
  class SessionRequest(GenSessionRequest, S2Message["SessionRequest"]):
12
- class Config(GenSessionRequest.Config):
13
- validate_assignment = True
12
+ model_config = GenSessionRequest.model_config
13
+ model_config["validate_assignment"] = True
14
14
 
15
- message_id: uuid.UUID = GenSessionRequest.__fields__["message_id"].field_info # type: ignore[assignment]
15
+ message_id: uuid.UUID = GenSessionRequest.model_fields["message_id"] # type: ignore[assignment]
@@ -10,8 +10,8 @@ from s2python.validate_values_mixin import (
10
10
 
11
11
  @catch_and_convert_exceptions
12
12
  class Timer(GenTimer, S2Message["Timer"]):
13
- class Config(GenTimer.Config):
14
- validate_assignment = True
13
+ model_config = GenTimer.model_config
14
+ model_config["validate_assignment"] = True
15
15
 
16
- id: uuid.UUID = GenTimer.__fields__["id"].field_info # type: ignore[assignment]
17
- duration: Duration = GenTimer.__fields__["duration"].field_info # type: ignore[assignment]
16
+ id: uuid.UUID = GenTimer.model_fields["id"] # type: ignore[assignment]
17
+ duration: Duration = GenTimer.model_fields["duration"] # type: ignore[assignment]
@@ -0,0 +1,24 @@
1
+ import uuid
2
+ from typing import Optional, List
3
+
4
+ from s2python.common.duration import Duration
5
+ from s2python.generated.gen_s2 import Transition as GenTransition
6
+ from s2python.validate_values_mixin import (
7
+ S2Message,
8
+ catch_and_convert_exceptions,
9
+ )
10
+
11
+
12
+ @catch_and_convert_exceptions
13
+ class Transition(GenTransition, S2Message["Transition"]):
14
+ model_config = GenTransition.model_config
15
+ model_config["validate_assignment"] = True
16
+
17
+ id: uuid.UUID = GenTransition.model_fields["id"] # type: ignore[assignment]
18
+ from_: uuid.UUID = GenTransition.model_fields["from_"] # type: ignore[assignment]
19
+ to: uuid.UUID = GenTransition.model_fields["to"] # type: ignore[assignment]
20
+ start_timers: List[uuid.UUID] = GenTransition.model_fields["start_timers"] # type: ignore[assignment]
21
+ blocking_timers: List[uuid.UUID] = GenTransition.model_fields["blocking_timers"] # type: ignore[assignment]
22
+ transition_duration: Optional[Duration] = GenTransition.model_fields[
23
+ "transition_duration"
24
+ ] # type: ignore[assignment]
@@ -1,15 +1,15 @@
1
1
  import uuid
2
2
 
3
- from typing import List, Any, Dict
3
+ from typing import List
4
+ from typing_extensions import Self
4
5
 
5
- from pydantic import root_validator
6
+ from pydantic import model_validator
6
7
 
7
8
  from s2python.common import Transition, Timer, Commodity
8
9
  from s2python.common.support import commodity_has_quantity
9
10
  from s2python.frbc.frbc_operation_mode import FRBCOperationMode
10
11
  from s2python.generated.gen_s2 import (
11
12
  FRBCActuatorDescription as GenFRBCActuatorDescription,
12
- CommodityQuantity,
13
13
  )
14
14
  from s2python.validate_values_mixin import (
15
15
  S2Message,
@@ -18,34 +18,29 @@ from s2python.validate_values_mixin import (
18
18
 
19
19
 
20
20
  @catch_and_convert_exceptions
21
- class FRBCActuatorDescription(
22
- GenFRBCActuatorDescription, S2Message["FRBCActuatorDescription"]
23
- ):
24
- class Config(GenFRBCActuatorDescription.Config):
25
- validate_assignment = True
26
-
27
- id: uuid.UUID = GenFRBCActuatorDescription.__fields__["id"].field_info # type: ignore[assignment]
28
- operation_modes: List[FRBCOperationMode] = GenFRBCActuatorDescription.__fields__[
21
+ class FRBCActuatorDescription(GenFRBCActuatorDescription, S2Message["FRBCActuatorDescription"]):
22
+ model_config = GenFRBCActuatorDescription.model_config
23
+ model_config["validate_assignment"] = True
24
+
25
+ id: uuid.UUID = GenFRBCActuatorDescription.model_fields["id"] # type: ignore[assignment]
26
+ operation_modes: List[FRBCOperationMode] = GenFRBCActuatorDescription.model_fields[
29
27
  "operation_modes"
30
- ].field_info # type: ignore[assignment]
31
- transitions: List[Transition] = GenFRBCActuatorDescription.__fields__[
32
- "transitions"
33
- ].field_info # type: ignore[assignment]
34
- timers: List[Timer] = GenFRBCActuatorDescription.__fields__["timers"].field_info # type: ignore[assignment]
35
- supported_commodities: List[Commodity] = GenFRBCActuatorDescription.__fields__[
28
+ ] # type: ignore[assignment]
29
+ transitions: List[Transition] = GenFRBCActuatorDescription.model_fields["transitions"] # type: ignore[assignment]
30
+ timers: List[Timer] = GenFRBCActuatorDescription.model_fields["timers"] # type: ignore[assignment]
31
+ supported_commodities: List[Commodity] = GenFRBCActuatorDescription.model_fields[
36
32
  "supported_commodities"
37
- ].field_info # type: ignore[assignment]
33
+ ] # type: ignore[assignment]
38
34
 
39
- @root_validator(pre=False)
40
- @classmethod
41
- def validate_timers_in_transitions(cls, values: Dict[str, Any]) -> Dict[str, Any]:
42
- timers_by_id = {timer.id: timer for timer in values.get("timers", {})}
35
+ @model_validator(mode="after")
36
+ def validate_timers_in_transitions(self) -> Self:
37
+ timers_by_id = {timer.id: timer for timer in self.timers}
43
38
  transition: Transition
44
- for transition in values.get("transitions", []):
39
+ for transition in self.transitions:
45
40
  for start_timer_id in transition.start_timers:
46
41
  if start_timer_id not in timers_by_id:
47
42
  raise ValueError(
48
- cls,
43
+ self,
49
44
  f"{start_timer_id} was referenced as start timer in transition "
50
45
  f"{transition.id} but was not defined in 'timers'.",
51
46
  )
@@ -53,118 +48,96 @@ class FRBCActuatorDescription(
53
48
  for blocking_timer_id in transition.blocking_timers:
54
49
  if blocking_timer_id not in timers_by_id:
55
50
  raise ValueError(
56
- cls,
51
+ self,
57
52
  f"{blocking_timer_id} was referenced as blocking timer in transition "
58
53
  f"{transition.id} but was not defined in 'timers'.",
59
54
  )
60
55
 
61
- return values
56
+ return self
62
57
 
63
- @root_validator(pre=False)
64
- @classmethod
65
- def validate_timers_unique_ids(cls, values: Dict[str, Any]) -> Dict[str, Any]:
58
+ @model_validator(mode="after")
59
+ def validate_timers_unique_ids(self) -> Self:
66
60
  ids = []
67
61
  timer: Timer
68
- for timer in values.get("timers", []):
62
+ for timer in self.timers:
69
63
  if timer.id in ids:
70
- raise ValueError(
71
- cls, f"Id {timer.id} was found multiple times in 'timers'."
72
- )
64
+ raise ValueError(self, f"Id {timer.id} was found multiple times in 'timers'.")
73
65
  ids.append(timer.id)
74
66
 
75
- return values
76
-
77
- @root_validator(pre=False)
78
- @classmethod
79
- def validate_operation_modes_in_transitions(
80
- cls, values: Dict[str, Any]
81
- ) -> Dict[str, Any]:
82
- operation_mode_by_id = {
83
- operation_mode.id: operation_mode
84
- for operation_mode in values.get("operation_modes", [])
85
- }
67
+ return self
68
+
69
+ @model_validator(mode="after")
70
+ def validate_operation_modes_in_transitions(self) -> Self:
71
+ operation_mode_by_id = {operation_mode.id: operation_mode for operation_mode in self.operation_modes}
86
72
  transition: Transition
87
- for transition in values.get("transitions", []):
73
+ for transition in self.transitions:
88
74
  if transition.from_ not in operation_mode_by_id:
89
75
  raise ValueError(
90
- cls,
76
+ self,
91
77
  f"Operation mode {transition.from_} was referenced as 'from' in transition "
92
78
  f"{transition.id} but was not defined in 'operation_modes'.",
93
79
  )
94
80
 
95
81
  if transition.to not in operation_mode_by_id:
96
82
  raise ValueError(
97
- cls,
83
+ self,
98
84
  f"Operation mode {transition.to} was referenced as 'to' in transition "
99
85
  f"{transition.id} but was not defined in 'operation_modes'.",
100
86
  )
101
87
 
102
- return values
88
+ return self
103
89
 
104
- @root_validator(pre=False)
105
- @classmethod
106
- def validate_operation_modes_unique_ids(
107
- cls, values: Dict[str, Any]
108
- ) -> Dict[str, Any]:
90
+ @model_validator(mode="after")
91
+ def validate_operation_modes_unique_ids(self) -> Self:
109
92
  ids = []
110
93
  operation_mode: FRBCOperationMode
111
- for operation_mode in values.get("operation_modes", []):
94
+ for operation_mode in self.operation_modes:
112
95
  if operation_mode.id in ids:
113
96
  raise ValueError(
114
- cls,
97
+ self,
115
98
  f"Id {operation_mode.id} was found multiple times in 'operation_modes'.",
116
99
  )
117
100
  ids.append(operation_mode.id)
118
101
 
119
- return values
102
+ return self
120
103
 
121
- @root_validator(pre=False)
122
- @classmethod
123
- def validate_operation_mode_elements_have_all_supported_commodities(
124
- cls, values: Dict[str, Any]
125
- ) -> Dict[str, Any]:
126
- supported_commodities = values.get("supported_commodities", [])
104
+ @model_validator(mode="after")
105
+ def validate_operation_mode_elements_have_all_supported_commodities(self) -> Self:
106
+ supported_commodities = self.supported_commodities
127
107
  operation_mode: FRBCOperationMode
128
- for operation_mode in values.get("operation_modes", []):
108
+ for operation_mode in self.operation_modes:
129
109
  for operation_mode_element in operation_mode.elements:
130
110
  for commodity in supported_commodities:
131
111
  power_ranges_for_commodity = [
132
112
  power_range
133
113
  for power_range in operation_mode_element.power_ranges
134
- if commodity_has_quantity(
135
- commodity, power_range.commodity_quantity
136
- )
114
+ if commodity_has_quantity(commodity, power_range.commodity_quantity)
137
115
  ]
138
116
 
139
117
  if len(power_ranges_for_commodity) > 1:
140
118
  raise ValueError(
141
- cls,
119
+ self,
142
120
  f"Multiple power ranges defined for commodity {commodity} in operation "
143
121
  f"mode {operation_mode.id} and element with fill_level_range "
144
122
  f"{operation_mode_element.fill_level_range}",
145
123
  )
146
124
  if not power_ranges_for_commodity:
147
125
  raise ValueError(
148
- cls,
126
+ self,
149
127
  f"No power ranges defined for commodity {commodity} in operation "
150
128
  f"mode {operation_mode.id} and element with fill_level_range "
151
129
  f"{operation_mode_element.fill_level_range}",
152
130
  )
153
- return values
131
+ return self
154
132
 
155
- @root_validator(pre=False)
156
- @classmethod
157
- def validate_unique_supported_commodities(
158
- cls, values: Dict[str, Any]
159
- ) -> Dict[str, Any]:
160
- supported_commodities: List[CommodityQuantity] = values.get(
161
- "supported_commodities", []
162
- )
133
+ @model_validator(mode="after")
134
+ def validate_unique_supported_commodities(self) -> Self:
135
+ supported_commodities: List[Commodity] = self.supported_commodities
163
136
 
164
137
  for supported_commodity in supported_commodities:
165
138
  if supported_commodities.count(supported_commodity) > 1:
166
139
  raise ValueError(
167
- cls,
140
+ self,
168
141
  f"Found duplicate {supported_commodity} commodity in 'supported_commodities'",
169
142
  )
170
- return values
143
+ return self