s2-python 0.0.0__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.
Files changed (51) hide show
  1. s2_python-0.1.0.dist-info/METADATA +99 -0
  2. s2_python-0.1.0.dist-info/RECORD +50 -0
  3. {s2_python-0.0.0.dist-info → s2_python-0.1.0.dist-info}/WHEEL +1 -1
  4. s2python/__init__.py +1 -1
  5. s2python/common/__init__.py +12 -2
  6. s2python/common/duration.py +7 -4
  7. s2python/common/handshake.py +6 -3
  8. s2python/common/handshake_response.py +6 -3
  9. s2python/common/instruction_status_update.py +14 -5
  10. s2python/common/number_range.py +22 -10
  11. s2python/common/power_forecast.py +10 -5
  12. s2python/common/power_forecast_element.py +11 -5
  13. s2python/common/power_forecast_value.py +5 -2
  14. s2python/common/power_measurement.py +8 -5
  15. s2python/common/power_range.py +12 -4
  16. s2python/common/power_value.py +5 -2
  17. s2python/common/reception_status.py +8 -3
  18. s2python/common/resource_manager_details.py +18 -8
  19. s2python/common/revoke_object.py +7 -4
  20. s2python/common/role.py +5 -2
  21. s2python/common/select_control_type.py +6 -3
  22. s2python/common/session_request.py +6 -3
  23. s2python/common/support.py +19 -11
  24. s2python/common/timer.py +7 -4
  25. s2python/common/transition.py +16 -9
  26. s2python/frbc/__init__.py +3 -1
  27. s2python/frbc/frbc_actuator_description.py +99 -37
  28. s2python/frbc/frbc_actuator_status.py +13 -6
  29. s2python/frbc/frbc_fill_level_target_profile.py +21 -6
  30. s2python/frbc/frbc_fill_level_target_profile_element.py +17 -5
  31. s2python/frbc/frbc_instruction.py +9 -6
  32. s2python/frbc/frbc_leakage_behaviour.py +10 -5
  33. s2python/frbc/frbc_leakage_behaviour_element.py +13 -4
  34. s2python/frbc/frbc_operation_mode.py +32 -13
  35. s2python/frbc/frbc_operation_mode_element.py +20 -7
  36. s2python/frbc/frbc_storage_description.py +13 -4
  37. s2python/frbc/frbc_storage_status.py +6 -3
  38. s2python/frbc/frbc_system_description.py +16 -6
  39. s2python/frbc/frbc_timer_status.py +8 -5
  40. s2python/frbc/frbc_usage_forecast.py +10 -5
  41. s2python/frbc/frbc_usage_forecast_element.py +11 -4
  42. s2python/generated/gen_s2.py +476 -476
  43. s2python/s2_parser.py +113 -0
  44. s2python/s2_validation_error.py +4 -1
  45. s2python/utils.py +8 -3
  46. s2python/validate_values_mixin.py +90 -37
  47. s2python/version.py +1 -1
  48. s2_python-0.0.0.dist-info/METADATA +0 -50
  49. s2_python-0.0.0.dist-info/RECORD +0 -49
  50. {s2_python-0.0.0.dist-info → s2_python-0.1.0.dist-info}/entry_points.txt +0 -0
  51. {s2_python-0.0.0.dist-info → s2_python-0.1.0.dist-info}/top_level.txt +0 -0
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")
@@ -1,9 +1,12 @@
1
+ from typing import Union
2
+
1
3
  from pydantic import ValidationError
2
4
 
5
+
3
6
  class S2ValidationError(Exception):
4
7
  obj: object
5
8
  msg: str
6
- pydantic_validation_error: 'ValidationError | TypeError | None'
9
+ pydantic_validation_error: Union[ValidationError, TypeError, None]
7
10
 
8
11
  def __init__(self, obj: object, msg: str):
9
12
  self.obj = obj
s2python/utils.py CHANGED
@@ -1,3 +1,8 @@
1
- def pairwise(arr : list):
2
- for i in range(max(len(arr) - 1,0)):
3
- yield (arr[i], arr[i+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]:
7
+ for i in range(max(len(arr) - 1, 0)):
8
+ yield arr[i], arr[i + 1]
@@ -1,28 +1,57 @@
1
- from typing import TypeVar, Generic, Protocol, Type, Tuple, Optional, Callable, cast, Any, Union, AbstractSet, Mapping, List, Dict
2
-
3
- from pydantic import BaseModel, StrBytes, Protocol as PydanticProtocol, ValidationError
1
+ from typing import (
2
+ TypeVar,
3
+ Generic,
4
+ Protocol,
5
+ Type,
6
+ Optional,
7
+ Callable,
8
+ Any,
9
+ Union,
10
+ AbstractSet,
11
+ Mapping,
12
+ List,
13
+ Dict,
14
+ )
15
+
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
4
23
 
5
24
  from s2python.s2_validation_error import S2ValidationError
6
25
 
7
- B = TypeVar('B', bound=BaseModel, covariant=True)
26
+ B_co = TypeVar("B_co", bound=BaseModel, covariant=True)
8
27
 
9
28
  IntStr = Union[int, str]
10
29
  AbstractSetIntStr = AbstractSet[IntStr]
11
30
  MappingIntStrAny = Mapping[IntStr, Any]
12
31
 
13
- class SupportsValidation(Protocol[B]):
32
+
33
+ class SupportsValidation(Protocol[B_co]):
14
34
  # ValidateValuesMixin methods
15
- def to_json(self) -> str: ...
16
- def to_dict(self) -> dict: ...
35
+ def to_json(self) -> str:
36
+ ...
37
+
38
+ def to_dict(self) -> Dict:
39
+ ...
17
40
 
18
41
  @classmethod
19
- def from_json(cls, json_str: str) -> B: ...
42
+ def from_json(cls, json_str: str) -> B_co:
43
+ ...
44
+
45
+ @classmethod
46
+ def from_dict(cls, json_dict: Dict) -> B_co:
47
+ ...
20
48
 
21
49
  # Pydantic methods
22
- def json(self,
50
+ def json( # pylint: disable=too-many-arguments
51
+ self,
23
52
  *,
24
- include: Optional[Union['AbstractSetIntStr', 'MappingIntStrAny']] = None,
25
- exclude: Optional[Union['AbstractSetIntStr', 'MappingIntStrAny']] = None,
53
+ include: Optional[Union["AbstractSetIntStr", "MappingIntStrAny"]] = None,
54
+ exclude: Optional[Union["AbstractSetIntStr", "MappingIntStrAny"]] = None,
26
55
  by_alias: bool = False,
27
56
  skip_defaults: Optional[bool] = None,
28
57
  exclude_unset: bool = False,
@@ -31,31 +60,40 @@ class SupportsValidation(Protocol[B]):
31
60
  encoder: Optional[Callable[[Any], Any]] = None,
32
61
  models_as_dict: bool = True,
33
62
  **dumps_kwargs: Any,
34
- ) -> str: ...
35
-
36
- def dict(
37
- self,
38
- *,
39
- include: Optional[Union['AbstractSetIntStr', 'MappingIntStrAny']] = None,
40
- exclude: Optional[Union['AbstractSetIntStr', 'MappingIntStrAny']] = None,
41
- by_alias: bool = False,
42
- skip_defaults: Optional[bool] = None,
43
- exclude_unset: bool = False,
44
- exclude_defaults: bool = False,
45
- exclude_none: bool = False,
46
- ) -> Dict[str, Any]: ...
63
+ ) -> str:
64
+ ...
65
+
66
+ def dict( # pylint: disable=too-many-arguments
67
+ self,
68
+ *,
69
+ include: Optional[Union["AbstractSetIntStr", "MappingIntStrAny"]] = None,
70
+ exclude: Optional[Union["AbstractSetIntStr", "MappingIntStrAny"]] = None,
71
+ by_alias: bool = False,
72
+ skip_defaults: Optional[bool] = None,
73
+ exclude_unset: bool = False,
74
+ exclude_defaults: bool = False,
75
+ exclude_none: bool = False,
76
+ ) -> Dict[str, Any]:
77
+ ...
47
78
 
48
79
  @classmethod
49
- def parse_raw(cls,
50
- b: StrBytes,
51
- *,
52
- content_type: str = ...,
53
- encoding: str = ...,
54
- proto: PydanticProtocol = ...,
55
- allow_pickle: bool = ...) -> B: ...
80
+ def parse_raw( # pylint: disable=too-many-arguments
81
+ cls,
82
+ b: StrBytes,
83
+ *,
84
+ content_type: str = ...,
85
+ encoding: str = ...,
86
+ proto: PydanticProtocol = ...,
87
+ allow_pickle: bool = ...,
88
+ ) -> B_co:
89
+ ...
56
90
 
91
+ @classmethod
92
+ def parse_obj(cls, obj: Any) -> "B_co":
93
+ ...
57
94
 
58
- C = TypeVar('C', bound='SupportsValidation')
95
+
96
+ C = TypeVar("C", bound="SupportsValidation")
59
97
 
60
98
 
61
99
  class ValidateValuesMixin(Generic[C]):
@@ -63,7 +101,9 @@ class ValidateValuesMixin(Generic[C]):
63
101
  try:
64
102
  return self.json(by_alias=True, exclude_none=True)
65
103
  except (ValidationError, TypeError) as e:
66
- raise S2ValidationError(self, 'Pydantic raised a format validation error.') from e
104
+ raise S2ValidationError(
105
+ self, "Pydantic raised a format validation error."
106
+ ) from e
67
107
 
68
108
  def to_dict(self: C) -> dict:
69
109
  return self.dict()
@@ -73,13 +113,24 @@ class ValidateValuesMixin(Generic[C]):
73
113
  gen_model: C = cls.parse_raw(json_str)
74
114
  return gen_model
75
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
76
124
 
77
- def convert_to_s2exception(f : Callable) -> Callable:
125
+
126
+ def convert_to_s2exception(f: Callable) -> Callable:
78
127
  def inner(*args: List[Any], **kwargs: Dict[str, Any]) -> Any:
79
128
  try:
80
129
  return f(*args, **kwargs)
81
- except (ValidationError, TypeError) as e:
82
- raise S2ValidationError(args, 'Pydantic raised a format validation error.') 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
83
134
 
84
135
  inner.__doc__ = f.__doc__
85
136
  inner.__annotations__ = f.__annotations__
@@ -87,7 +138,9 @@ def convert_to_s2exception(f : Callable) -> Callable:
87
138
  return inner
88
139
 
89
140
 
90
- def catch_and_convert_exceptions(input_class: Type[SupportsValidation[B]]) -> Type[SupportsValidation[B]]:
141
+ def catch_and_convert_exceptions(
142
+ input_class: Type[SupportsValidation[B_co]],
143
+ ) -> Type[SupportsValidation[B_co]]:
91
144
  input_class.__init__ = convert_to_s2exception(input_class.__init__) # type: ignore[method-assign]
92
145
  input_class.__setattr__ = convert_to_s2exception(input_class.__setattr__) # type: ignore[method-assign]
93
146
  input_class.parse_raw = convert_to_s2exception(input_class.parse_raw) # type: ignore[method-assign]
s2python/version.py CHANGED
@@ -1 +1 @@
1
- VERSION = '0.2.0'
1
+ VERSION = "0.2.0"
@@ -1,50 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: s2-python
3
- Version: 0.0.0
4
- Summary: S2 Protocol Python Wrapper
5
- Home-page: https://github.com/flexiblepower/s2-ws-json-python
6
- Author: Flexiblepower
7
- Author-email: info@info.nl
8
- License: APACHE
9
- Platform: Linux
10
- Classifier: Development Status :: 4 - Beta
11
- Classifier: Programming Language :: Python
12
- Description-Content-Type: text/x-rst; charset=UTF-8
13
- Requires-Dist: pydantic <=1.10.7
14
- Requires-Dist: pytz
15
- Requires-Dist: click
16
- Provides-Extra: development
17
- Requires-Dist: pip-tools ; extra == 'development'
18
- Requires-Dist: datamodel-code-generator ; extra == 'development'
19
- Requires-Dist: pre-commit ; extra == 'development'
20
- Requires-Dist: tox ; extra == 'development'
21
- Provides-Extra: docs
22
- Requires-Dist: sphinx ; extra == 'docs'
23
- Requires-Dist: sphinx-rtd-theme >=1.2 ; extra == 'docs'
24
- Requires-Dist: sphinx-tabs ; extra == 'docs'
25
- Requires-Dist: sphinx-copybutton ; extra == 'docs'
26
- Requires-Dist: sphinx-fontawesome ; extra == 'docs'
27
- Requires-Dist: sphinxcontrib.httpdomain ; extra == 'docs'
28
- Provides-Extra: testing
29
- Requires-Dist: pytest ; extra == 'testing'
30
- Requires-Dist: pytest-coverage ; extra == 'testing'
31
- Requires-Dist: pytest-timer ; extra == 'testing'
32
- Requires-Dist: mypy ; extra == 'testing'
33
- Requires-Dist: pylint ; extra == 'testing'
34
-
35
- Python Wrapper for S2 Flexibility Protocol
36
- ===========================================
37
-
38
-
39
- Install for development:
40
-
41
- pip install -e .[testing,development]
42
-
43
-
44
- Run tests:
45
- pip install -e .[testing,development]
46
- tox
47
-
48
- Build
49
- tox -e build,clean
50
-
@@ -1,49 +0,0 @@
1
- s2python/__init__.py,sha256=aLCMCipFsPGFEsc8ritsDiYDSUBTW5kA34N_3po08p8,352
2
- s2python/s2_validation_error.py,sha256=AordALh8VENfP9Mrva49OtwaejhG6uxV3AAYp3ZbTeA,265
3
- s2python/utils.py,sha256=FiPSJcu2uaizPXgrsIzvNyq7tvQpBDV4Vkn_BzWMJMA,100
4
- s2python/validate_values_mixin.py,sha256=hNZoPyKzhEX0V8LY29E-9HA3tG3gtVEwzyDa0hoZ958,3343
5
- s2python/version.py,sha256=Te87yKMugWziDTANt72vxbLxpfD405Ve4s9uS1gESGU,18
6
- s2python/common/__init__.py,sha256=4MDCbNpUhFTEKD0LYfCjRgJsObybaDM6He41LUmtVVc,1341
7
- s2python/common/duration.py,sha256=UzZZo3iEB-fJOg4wzbQgniEvb4IjOld2vRWQLqOSrrQ,668
8
- s2python/common/handshake.py,sha256=DboFxNv-yKSdrV3v3_o7i_U6TXCS9isCUHnuOpwxiew,447
9
- s2python/common/handshake_response.py,sha256=9Du70SEO1uuAj2vcujR8utuwXfj3MEKqSbspfdr3zCU,503
10
- s2python/common/instruction_status_update.py,sha256=2_N0Xb0Efw_CZ9LS6Q722pcpsSbGPzZfeRx1bZeLeBQ,672
11
- s2python/common/number_range.py,sha256=81dJWm0uQac9uK22ZvSxIsLnOjvvCnIWXD-2TJVqpKc,1023
12
- s2python/common/power_forecast.py,sha256=xNujNZACtsyYK0k7lk-qbnSfTbv6CE6Ear9YBGipBQg,670
13
- s2python/common/power_forecast_element.py,sha256=D_NRNSprzkZ4k7q1XCfn6GVUylPc28mCzzXRXH_b9i8,723
14
- s2python/common/power_forecast_value.py,sha256=TzvMpgjE8llbR3OjN8SV0VRoLJ07C5fX1861FmjH1Bc,382
15
- s2python/common/power_measurement.py,sha256=aj9AxR1Exsgn-oPV8gQdw5OE5WLSStrRTIXr9hRMsxY,670
16
- s2python/common/power_range.py,sha256=PBbn0oqhdE8xbhjRgWRMbEMflPY0z0lhbtW1Jxdz9_I,708
17
- s2python/common/power_value.py,sha256=-sl-AdrA9Rw_x4laoj7BuDgsCXCDRhEA2yLjjApbDcE,334
18
- s2python/common/reception_status.py,sha256=BA535UhrZC_Uq5g8YLDipAlEAdmjjjrdh11NMhJJmFo,505
19
- s2python/common/resource_manager_details.py,sha256=bdxZUN4Ngzr8_tPKJ9hgWzdz8e01zU5AU2r-tuyfuj8,987
20
- s2python/common/revoke_object.py,sha256=ySM5cHrCt7mFvdVmxol6cHj-t-SOlgOR_t3k2iYTRk0,574
21
- s2python/common/role.py,sha256=grW98IKir4kIe4UROOv1wKoQt9N3_n-ZpqXFrStMiXg,298
22
- s2python/common/select_control_type.py,sha256=1xCM75Pn77B5izQJI8TSufb7CW4bnSrGt2Y7MF2ewf0,503
23
- s2python/common/session_request.py,sha256=pKYUNnstQO1WccG5ilIz-mDkX6AkzuZ6lPXqufb_AhY,481
24
- s2python/common/support.py,sha256=OvOGXz3zPUy-kFmYwBRn2hcM81I8I-BuHBxPfahTXIo,1000
25
- s2python/common/timer.py,sha256=ekS15yp0F-cQ1kWUksQRmLxwcfxvb2auc27QmoDScrU,545
26
- s2python/common/transition.py,sha256=v2L-omP3XPKiP8N3cwolNyQLuGBBCgSavUSJXIGbQUU,1066
27
- s2python/frbc/__init__.py,sha256=vOgcsODtqo5ojg9brRKeDCdS-WI4Mn_WOJIayGe6gP0,1095
28
- s2python/frbc/frbc_actuator_description.py,sha256=h4cxlOSBaEZdYv6t_MGvIo2558W0dJ5yTvKrY6LQXGU,6077
29
- s2python/frbc/frbc_actuator_status.py,sha256=FXwpeLnMq52l2sQ8myDSESP4T6y045Ul5ap7FDWZB3g,952
30
- s2python/frbc/frbc_fill_level_target_profile.py,sha256=JqJ3CxSQfOS3ylmadbJvGys7Bl6t5dxu6ShsEL28PgE,798
31
- s2python/frbc/frbc_fill_level_target_profile_element.py,sha256=73uZWePP9Lgo95H1ZaxONpvGzTMo3TCHUceQIr4N-8c,791
32
- s2python/frbc/frbc_instruction.py,sha256=2MH_axt5PPVtRbE39IcyR3EHiz5KDgznHYK7BhXFvuA,817
33
- s2python/frbc/frbc_leakage_behaviour.py,sha256=yC9OoE5RJ8pco4pm4CRcmlTy62hGXBsPFstN9g6RCAU,738
34
- s2python/frbc/frbc_leakage_behaviour_element.py,sha256=ZFChN7OITRQ22ayqKfk_W8UupfugWCmPsYiJIDVOk4Q,614
35
- s2python/frbc/frbc_operation_mode.py,sha256=ETK8ZHILZ8yWVu9iRhYruJxrvCfAciaei_dZZfADX4s,1847
36
- s2python/frbc/frbc_operation_mode_element.py,sha256=nzKRHtouZaJBsE1DRW2t026pyUWWM-7knjrY_Tx22rk,1029
37
- s2python/frbc/frbc_storage_description.py,sha256=liP59YnT68Tdr-9I6PKqtMuW10BjWbT54Hq5WUGNleU,579
38
- s2python/frbc/frbc_storage_status.py,sha256=btFuwqebbVo0R8Evc22tfl6omrMD7LuUMkTAkDX6z6U,503
39
- s2python/frbc/frbc_system_description.py,sha256=dPdaRcEUsYMbp-tJq8uVpb5BY6oed-OHAXOAMphrC8o,888
40
- s2python/frbc/frbc_timer_status.py,sha256=a0ILHtugiIrMUJTybOe0KVLI_X3Y8RZn7s3TcnLzPkc,709
41
- s2python/frbc/frbc_usage_forecast.py,sha256=r4m0kB9k8B9ppT9FwSg9SS4uxRiOJRB4-OWBEqyouss,708
42
- s2python/frbc/frbc_usage_forecast_element.py,sha256=WAXdAbyRFWuyrZx4MLkbOpGp82XeNMWIz8xCdBsjiq4,572
43
- s2python/generated/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
44
- s2python/generated/gen_s2.py,sha256=6CGPuVnK-6OgmxOhPWKQxgCwbF1LWMlBB_gooa6yaCE,61928
45
- s2_python-0.0.0.dist-info/METADATA,sha256=59s-SoyBxwko5KGq_6_IVzWz9enzuF9IhdkFO09dflA,1513
46
- s2_python-0.0.0.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
47
- s2_python-0.0.0.dist-info/entry_points.txt,sha256=feX-xmgJZgSe5-jxMgFKPKCJz4Ys3eQcGrsXsirNZyM,61
48
- s2_python-0.0.0.dist-info/top_level.txt,sha256=OLFq0oDhr77Mp-EYLEcWk5P3jvooOt4IHkTI5KYJMc8,9
49
- s2_python-0.0.0.dist-info/RECORD,,