s2-python 0.2.2__tar.gz → 0.3.1__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.
- {s2_python-0.2.2 → s2_python-0.3.1}/PKG-INFO +2 -2
- {s2_python-0.2.2 → s2_python-0.3.1}/setup.cfg +1 -1
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2_python.egg-info/PKG-INFO +2 -2
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2_python.egg-info/SOURCES.txt +11 -1
- s2_python-0.3.1/src/s2python/ppbc/__init__.py +12 -0
- s2_python-0.3.1/src/s2python/ppbc/ppbc_end_interruption_instruction.py +32 -0
- s2_python-0.3.1/src/s2python/ppbc/ppbc_power_profile_definition.py +27 -0
- s2_python-0.3.1/src/s2python/ppbc/ppbc_power_profile_status.py +26 -0
- s2_python-0.3.1/src/s2python/ppbc/ppbc_power_sequence.py +30 -0
- s2_python-0.3.1/src/s2python/ppbc/ppbc_power_sequence_container.py +27 -0
- s2_python-0.3.1/src/s2python/ppbc/ppbc_power_sequence_container_status.py +32 -0
- s2_python-0.3.1/src/s2python/ppbc/ppbc_power_sequence_element.py +25 -0
- s2_python-0.3.1/src/s2python/ppbc/ppbc_schedule_instruction.py +33 -0
- s2_python-0.3.1/src/s2python/ppbc/ppbc_start_interruption_instruction.py +32 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/s2_connection.py +81 -38
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/s2_control_type.py +26 -2
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/s2_parser.py +9 -2
- {s2_python-0.2.2 → s2_python-0.3.1}/README.rst +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/pyproject.toml +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/setup.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2_python.egg-info/dependency_links.txt +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2_python.egg-info/entry_points.txt +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2_python.egg-info/not-zip-safe +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2_python.egg-info/requires.txt +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2_python.egg-info/top_level.txt +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/__init__.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/common/__init__.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/common/duration.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/common/handshake.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/common/handshake_response.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/common/instruction_status_update.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/common/number_range.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/common/power_forecast.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/common/power_forecast_element.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/common/power_forecast_value.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/common/power_measurement.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/common/power_range.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/common/power_value.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/common/reception_status.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/common/resource_manager_details.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/common/revoke_object.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/common/role.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/common/select_control_type.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/common/session_request.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/common/support.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/common/timer.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/common/transition.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/frbc/__init__.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/frbc/frbc_actuator_description.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/frbc/frbc_actuator_status.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/frbc/frbc_fill_level_target_profile.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/frbc/frbc_fill_level_target_profile_element.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/frbc/frbc_instruction.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/frbc/frbc_leakage_behaviour.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/frbc/frbc_leakage_behaviour_element.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/frbc/frbc_operation_mode.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/frbc/frbc_operation_mode_element.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/frbc/frbc_storage_description.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/frbc/frbc_storage_status.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/frbc/frbc_system_description.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/frbc/frbc_timer_status.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/frbc/frbc_usage_forecast.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/frbc/frbc_usage_forecast_element.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/frbc/rm.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/generated/__init__.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/generated/gen_s2.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/py.typed +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/reception_status_awaiter.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/s2_validation_error.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/utils.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/validate_values_mixin.py +0 -0
- {s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/version.py +0 -0
@@ -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.
|
11
|
+
version = 0.3.1
|
12
12
|
platforms = Linux
|
13
13
|
classifiers =
|
14
14
|
Development Status :: 4 - Beta
|
@@ -58,4 +58,14 @@ src/s2python/frbc/frbc_usage_forecast.py
|
|
58
58
|
src/s2python/frbc/frbc_usage_forecast_element.py
|
59
59
|
src/s2python/frbc/rm.py
|
60
60
|
src/s2python/generated/__init__.py
|
61
|
-
src/s2python/generated/gen_s2.py
|
61
|
+
src/s2python/generated/gen_s2.py
|
62
|
+
src/s2python/ppbc/__init__.py
|
63
|
+
src/s2python/ppbc/ppbc_end_interruption_instruction.py
|
64
|
+
src/s2python/ppbc/ppbc_power_profile_definition.py
|
65
|
+
src/s2python/ppbc/ppbc_power_profile_status.py
|
66
|
+
src/s2python/ppbc/ppbc_power_sequence.py
|
67
|
+
src/s2python/ppbc/ppbc_power_sequence_container.py
|
68
|
+
src/s2python/ppbc/ppbc_power_sequence_container_status.py
|
69
|
+
src/s2python/ppbc/ppbc_power_sequence_element.py
|
70
|
+
src/s2python/ppbc/ppbc_schedule_instruction.py
|
71
|
+
src/s2python/ppbc/ppbc_start_interruption_instruction.py
|
@@ -0,0 +1,12 @@
|
|
1
|
+
from s2python.ppbc.ppbc_schedule_instruction import PPBCScheduleInstruction
|
2
|
+
from s2python.ppbc.ppbc_end_interruption_instruction import (
|
3
|
+
PPBCEndInterruptionInstruction,
|
4
|
+
)
|
5
|
+
from s2python.ppbc.ppbc_power_profile_definition import PPBCPowerProfileDefinition
|
6
|
+
from s2python.ppbc.ppbc_power_sequence_container import PPBCPowerSequenceContainer
|
7
|
+
from s2python.ppbc.ppbc_power_sequence import PPBCPowerSequence
|
8
|
+
from s2python.ppbc.ppbc_power_profile_status import PPBCPowerProfileStatus
|
9
|
+
from s2python.ppbc.ppbc_power_sequence_container_status import (
|
10
|
+
PPBCPowerSequenceContainerStatus,
|
11
|
+
)
|
12
|
+
from s2python.ppbc.ppbc_power_sequence_element import PPBCPowerSequenceElement
|
@@ -0,0 +1,32 @@
|
|
1
|
+
import uuid
|
2
|
+
|
3
|
+
from s2python.generated.gen_s2 import (
|
4
|
+
PPBCEndInterruptionInstruction as GenPPBCEndInterruptionInstruction,
|
5
|
+
)
|
6
|
+
|
7
|
+
from s2python.validate_values_mixin import (
|
8
|
+
S2Message,
|
9
|
+
catch_and_convert_exceptions,
|
10
|
+
)
|
11
|
+
|
12
|
+
|
13
|
+
@catch_and_convert_exceptions
|
14
|
+
class PPBCEndInterruptionInstruction(
|
15
|
+
GenPPBCEndInterruptionInstruction, S2Message["PPBCEndInterruptionInstruction"]
|
16
|
+
):
|
17
|
+
model_config = GenPPBCEndInterruptionInstruction.model_config
|
18
|
+
model_config["validate_assignment"] = True
|
19
|
+
|
20
|
+
id: uuid.UUID = GenPPBCEndInterruptionInstruction.model_fields["id"] # type: ignore[assignment]
|
21
|
+
power_profile_id: uuid.UUID = GenPPBCEndInterruptionInstruction.model_fields[
|
22
|
+
"power_profile_id"
|
23
|
+
] # type: ignore[assignment]
|
24
|
+
sequence_container_id: uuid.UUID = GenPPBCEndInterruptionInstruction.model_fields[
|
25
|
+
"sequence_container_id"
|
26
|
+
] # type: ignore[assignment]
|
27
|
+
power_sequence_id: uuid.UUID = GenPPBCEndInterruptionInstruction.model_fields[
|
28
|
+
"power_sequence_id"
|
29
|
+
] # type: ignore[assignment]
|
30
|
+
abnormal_condition: bool = GenPPBCEndInterruptionInstruction.model_fields[
|
31
|
+
"abnormal_condition"
|
32
|
+
] # type: ignore[assignment]
|
@@ -0,0 +1,27 @@
|
|
1
|
+
from typing import List
|
2
|
+
import uuid
|
3
|
+
|
4
|
+
from s2python.generated.gen_s2 import (
|
5
|
+
PPBCPowerProfileDefinition as GenPPBCPowerProfileDefinition,
|
6
|
+
)
|
7
|
+
|
8
|
+
from s2python.validate_values_mixin import (
|
9
|
+
S2Message,
|
10
|
+
catch_and_convert_exceptions,
|
11
|
+
)
|
12
|
+
|
13
|
+
from s2python.ppbc.ppbc_power_sequence_container import PPBCPowerSequenceContainer
|
14
|
+
|
15
|
+
|
16
|
+
@catch_and_convert_exceptions
|
17
|
+
class PPBCPowerProfileDefinition(
|
18
|
+
GenPPBCPowerProfileDefinition, S2Message["PPBCPowerProfileDefinition"]
|
19
|
+
):
|
20
|
+
model_config = GenPPBCPowerProfileDefinition.model_config
|
21
|
+
model_config["validate_assignment"] = True
|
22
|
+
|
23
|
+
message_id: uuid.UUID = GenPPBCPowerProfileDefinition.model_fields["message_id"] # type: ignore[assignment]
|
24
|
+
id: uuid.UUID = GenPPBCPowerProfileDefinition.model_fields["id"] # type: ignore[assignment]
|
25
|
+
power_sequences_containers: List[PPBCPowerSequenceContainer] = (
|
26
|
+
GenPPBCPowerProfileDefinition.model_fields["power_sequences_containers"] # type: ignore[assignment]
|
27
|
+
)
|
@@ -0,0 +1,26 @@
|
|
1
|
+
from typing import List
|
2
|
+
|
3
|
+
from s2python.generated.gen_s2 import (
|
4
|
+
PPBCPowerProfileStatus as GenPPBCPowerProfileStatus,
|
5
|
+
)
|
6
|
+
|
7
|
+
from s2python.validate_values_mixin import (
|
8
|
+
S2Message,
|
9
|
+
catch_and_convert_exceptions,
|
10
|
+
)
|
11
|
+
|
12
|
+
from s2python.ppbc.ppbc_power_sequence_container_status import (
|
13
|
+
PPBCPowerSequenceContainerStatus,
|
14
|
+
)
|
15
|
+
|
16
|
+
|
17
|
+
@catch_and_convert_exceptions
|
18
|
+
class PPBCPowerProfileStatus(
|
19
|
+
GenPPBCPowerProfileStatus, S2Message["PPBCPowerProfileStatus"]
|
20
|
+
):
|
21
|
+
model_config = GenPPBCPowerProfileStatus.model_config
|
22
|
+
model_config["validate_assignment"] = True
|
23
|
+
|
24
|
+
sequence_container_status: List[PPBCPowerSequenceContainerStatus] = (
|
25
|
+
GenPPBCPowerProfileStatus.model_fields["sequence_container_status"] # type: ignore[assignment]
|
26
|
+
)
|
@@ -0,0 +1,30 @@
|
|
1
|
+
from typing import List
|
2
|
+
import uuid
|
3
|
+
|
4
|
+
from s2python.generated.gen_s2 import (
|
5
|
+
PPBCPowerSequence as GenPPBCPowerSequence,
|
6
|
+
)
|
7
|
+
|
8
|
+
from s2python.validate_values_mixin import (
|
9
|
+
S2Message,
|
10
|
+
catch_and_convert_exceptions,
|
11
|
+
)
|
12
|
+
|
13
|
+
from s2python.ppbc.ppbc_power_sequence_element import PPBCPowerSequenceElement
|
14
|
+
from s2python.common import Duration
|
15
|
+
|
16
|
+
|
17
|
+
@catch_and_convert_exceptions
|
18
|
+
class PPBCPowerSequence(GenPPBCPowerSequence, S2Message["PPBCPowerSequence"]):
|
19
|
+
model_config = GenPPBCPowerSequence.model_config
|
20
|
+
model_config["validate_assignment"] = True
|
21
|
+
|
22
|
+
id: uuid.UUID = GenPPBCPowerSequence.model_fields["id"] # type: ignore[assignment]
|
23
|
+
elements: List[PPBCPowerSequenceElement] = GenPPBCPowerSequence.model_fields[
|
24
|
+
"elements"
|
25
|
+
] # type: ignore[assignment]
|
26
|
+
is_interruptible: bool = GenPPBCPowerSequence.model_fields["is_interruptible"] # type: ignore[assignment]
|
27
|
+
max_pause_before: Duration = GenPPBCPowerSequence.model_fields["max_pause_before"] # type: ignore[assignment]
|
28
|
+
abnormal_condition_only: bool = GenPPBCPowerSequence.model_fields[
|
29
|
+
"abnormal_condition_only"
|
30
|
+
] # type: ignore[assignment]
|
@@ -0,0 +1,27 @@
|
|
1
|
+
from typing import List
|
2
|
+
import uuid
|
3
|
+
|
4
|
+
|
5
|
+
from s2python.generated.gen_s2 import (
|
6
|
+
PPBCPowerSequenceContainer as GenPPBCPowerSequenceContainer,
|
7
|
+
)
|
8
|
+
|
9
|
+
from s2python.validate_values_mixin import (
|
10
|
+
S2Message,
|
11
|
+
catch_and_convert_exceptions,
|
12
|
+
)
|
13
|
+
|
14
|
+
from s2python.ppbc.ppbc_power_sequence import PPBCPowerSequence
|
15
|
+
|
16
|
+
|
17
|
+
@catch_and_convert_exceptions
|
18
|
+
class PPBCPowerSequenceContainer(
|
19
|
+
GenPPBCPowerSequenceContainer, S2Message["PPBCPowerSequenceContainer"]
|
20
|
+
):
|
21
|
+
model_config = GenPPBCPowerSequenceContainer.model_config
|
22
|
+
model_config["validate_assignment"] = True
|
23
|
+
|
24
|
+
id: uuid.UUID = GenPPBCPowerSequenceContainer.model_fields["id"] # type: ignore[assignment]
|
25
|
+
power_sequences: List[PPBCPowerSequence] = (
|
26
|
+
GenPPBCPowerSequenceContainer.model_fields["power_sequences"] # type: ignore[assignment]
|
27
|
+
)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
import uuid
|
2
|
+
from typing import Union
|
3
|
+
|
4
|
+
from s2python.generated.gen_s2 import (
|
5
|
+
PPBCPowerSequenceContainerStatus as GenPPBCPowerSequenceContainerStatus,
|
6
|
+
)
|
7
|
+
|
8
|
+
from s2python.validate_values_mixin import (
|
9
|
+
S2Message,
|
10
|
+
catch_and_convert_exceptions,
|
11
|
+
)
|
12
|
+
|
13
|
+
|
14
|
+
@catch_and_convert_exceptions
|
15
|
+
class PPBCPowerSequenceContainerStatus(
|
16
|
+
GenPPBCPowerSequenceContainerStatus, S2Message["PPBCPowerSequenceContainerStatus"]
|
17
|
+
):
|
18
|
+
model_config = GenPPBCPowerSequenceContainerStatus.model_config
|
19
|
+
model_config["validate_assignment"] = True
|
20
|
+
|
21
|
+
power_profile_id: uuid.UUID = GenPPBCPowerSequenceContainerStatus.model_fields[
|
22
|
+
"power_profile_id" # type: ignore[assignment]
|
23
|
+
]
|
24
|
+
sequence_container_id: uuid.UUID = GenPPBCPowerSequenceContainerStatus.model_fields[
|
25
|
+
"sequence_container_id" # type: ignore[assignment]
|
26
|
+
]
|
27
|
+
selected_sequence_id: Union[uuid.UUID, None] = (
|
28
|
+
GenPPBCPowerSequenceContainerStatus.model_fields["selected_sequence_id"] # type: ignore[assignment]
|
29
|
+
)
|
30
|
+
progress: Union[uuid.UUID, None] = GenPPBCPowerSequenceContainerStatus.model_fields[
|
31
|
+
"progress" # type: ignore[assignment]
|
32
|
+
]
|
@@ -0,0 +1,25 @@
|
|
1
|
+
from typing import List
|
2
|
+
|
3
|
+
from s2python.generated.gen_s2 import (
|
4
|
+
PPBCPowerSequenceElement as GenPPBCPowerSequenceElement,
|
5
|
+
)
|
6
|
+
|
7
|
+
from s2python.validate_values_mixin import (
|
8
|
+
S2Message,
|
9
|
+
catch_and_convert_exceptions,
|
10
|
+
)
|
11
|
+
|
12
|
+
from s2python.common import Duration, PowerForecastValue
|
13
|
+
|
14
|
+
|
15
|
+
@catch_and_convert_exceptions
|
16
|
+
class PPBCPowerSequenceElement(
|
17
|
+
GenPPBCPowerSequenceElement, S2Message["PPBCPowerSequenceElement"]
|
18
|
+
):
|
19
|
+
model_config = GenPPBCPowerSequenceElement.model_config
|
20
|
+
model_config["validate_assignment"] = True
|
21
|
+
|
22
|
+
duration: Duration = GenPPBCPowerSequenceElement.model_fields["duration"] # type: ignore[assignment]
|
23
|
+
power_values: List[PowerForecastValue] = GenPPBCPowerSequenceElement.model_fields[
|
24
|
+
"power_values"
|
25
|
+
] # type: ignore[assignment]
|
@@ -0,0 +1,33 @@
|
|
1
|
+
import uuid
|
2
|
+
|
3
|
+
from s2python.generated.gen_s2 import (
|
4
|
+
PPBCScheduleInstruction as GenPPBCScheduleInstruction,
|
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 PPBCScheduleInstruction(
|
14
|
+
GenPPBCScheduleInstruction, S2Message["PPBCScheduleInstruction"]
|
15
|
+
):
|
16
|
+
model_config = GenPPBCScheduleInstruction.model_config
|
17
|
+
model_config["validate_assignment"] = True
|
18
|
+
|
19
|
+
id: uuid.UUID = GenPPBCScheduleInstruction.model_fields["id"] # type: ignore[assignment]
|
20
|
+
|
21
|
+
power_profile_id: uuid.UUID = GenPPBCScheduleInstruction.model_fields[
|
22
|
+
"power_profile_id"
|
23
|
+
] # type: ignore[assignment]
|
24
|
+
|
25
|
+
message_id: uuid.UUID = GenPPBCScheduleInstruction.model_fields["message_id"] # type: ignore[assignment]
|
26
|
+
|
27
|
+
sequence_container_id: uuid.UUID = GenPPBCScheduleInstruction.model_fields[
|
28
|
+
"sequence_container_id"
|
29
|
+
] # type: ignore[assignment]
|
30
|
+
|
31
|
+
power_sequence_id: uuid.UUID = GenPPBCScheduleInstruction.model_fields[
|
32
|
+
"power_sequence_id"
|
33
|
+
] # type: ignore[assignment]
|
@@ -0,0 +1,32 @@
|
|
1
|
+
import uuid
|
2
|
+
|
3
|
+
from s2python.generated.gen_s2 import (
|
4
|
+
PPBCStartInterruptionInstruction as GenPPBCStartInterruptionInstruction,
|
5
|
+
)
|
6
|
+
|
7
|
+
from s2python.validate_values_mixin import (
|
8
|
+
S2Message,
|
9
|
+
catch_and_convert_exceptions,
|
10
|
+
)
|
11
|
+
|
12
|
+
|
13
|
+
@catch_and_convert_exceptions
|
14
|
+
class PPBCStartInterruptionInstruction(
|
15
|
+
GenPPBCStartInterruptionInstruction, S2Message["PPBCStartInterruptionInstruction"]
|
16
|
+
):
|
17
|
+
model_config = GenPPBCStartInterruptionInstruction.model_config
|
18
|
+
model_config["validate_assignment"] = True
|
19
|
+
|
20
|
+
id: uuid.UUID = GenPPBCStartInterruptionInstruction.model_fields["id"] # type: ignore[assignment]
|
21
|
+
power_profile_id: uuid.UUID = GenPPBCStartInterruptionInstruction.model_fields[
|
22
|
+
"power_profile_id"
|
23
|
+
] # type: ignore[assignment]
|
24
|
+
sequence_container_id: uuid.UUID = GenPPBCStartInterruptionInstruction.model_fields[
|
25
|
+
"sequence_container_id"
|
26
|
+
] # type: ignore[assignment]
|
27
|
+
power_sequence_id: uuid.UUID = GenPPBCStartInterruptionInstruction.model_fields[
|
28
|
+
"power_sequence_id"
|
29
|
+
] # type: ignore[assignment]
|
30
|
+
abnormal_condition: bool = GenPPBCStartInterruptionInstruction.model_fields[
|
31
|
+
"abnormal_condition"
|
32
|
+
] # type: ignore[assignment]
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import asyncio
|
2
2
|
import json
|
3
3
|
import logging
|
4
|
+
import time
|
4
5
|
import threading
|
5
6
|
import uuid
|
6
7
|
from dataclasses import dataclass
|
@@ -180,6 +181,7 @@ class MessageHandlers:
|
|
180
181
|
|
181
182
|
class S2Connection: # pylint: disable=too-many-instance-attributes
|
182
183
|
url: str
|
184
|
+
reconnect: bool
|
183
185
|
reception_status_awaiter: ReceptionStatusAwaiter
|
184
186
|
ws: Optional[WSConnection]
|
185
187
|
s2_parser: S2Parser
|
@@ -195,16 +197,20 @@ class S2Connection: # pylint: disable=too-many-instance-attributes
|
|
195
197
|
|
196
198
|
_eventloop: asyncio.AbstractEventLoop
|
197
199
|
_stop_event: asyncio.Event
|
200
|
+
_restart_connection_event: asyncio.Event
|
198
201
|
|
199
|
-
def __init__(
|
202
|
+
def __init__( # pylint: disable=too-many-arguments
|
200
203
|
self,
|
201
204
|
url: str,
|
202
205
|
role: EnergyManagementRole,
|
203
206
|
control_types: List[S2ControlType],
|
204
207
|
asset_details: AssetDetails,
|
208
|
+
reconnect: bool = False,
|
205
209
|
) -> None:
|
206
210
|
self.url = url
|
211
|
+
self.reconnect = reconnect
|
207
212
|
self.reception_status_awaiter = ReceptionStatusAwaiter()
|
213
|
+
self.ws = None
|
208
214
|
self.s2_parser = S2Parser()
|
209
215
|
|
210
216
|
self._handlers = MessageHandlers()
|
@@ -221,14 +227,13 @@ class S2Connection: # pylint: disable=too-many-instance-attributes
|
|
221
227
|
self._handlers.register_handler(HandshakeResponse, self.handle_handshake_response_as_rm)
|
222
228
|
|
223
229
|
def start_as_rm(self) -> None:
|
224
|
-
self.
|
225
|
-
self._thread.start()
|
226
|
-
logger.debug("Started eventloop thread!")
|
230
|
+
self._run_eventloop(self._run_as_rm())
|
227
231
|
|
228
|
-
def _run_eventloop(self) -> None:
|
232
|
+
def _run_eventloop(self, main_task: Awaitable[None]) -> None:
|
233
|
+
self._thread = threading.current_thread()
|
229
234
|
logger.debug("Starting eventloop")
|
230
235
|
try:
|
231
|
-
self._eventloop.run_until_complete(
|
236
|
+
self._eventloop.run_until_complete(main_task)
|
232
237
|
except asyncio.CancelledError:
|
233
238
|
pass
|
234
239
|
logger.debug("S2 connection thread has stopped.")
|
@@ -256,45 +261,69 @@ class S2Connection: # pylint: disable=too-many-instance-attributes
|
|
256
261
|
|
257
262
|
async def _run_as_rm(self) -> None:
|
258
263
|
logger.debug("Connecting as S2 resource manager.")
|
259
|
-
|
264
|
+
|
260
265
|
self._stop_event = asyncio.Event()
|
261
|
-
await self.connect_ws()
|
262
266
|
|
263
|
-
|
264
|
-
background_tasks.append(self._eventloop.create_task(self._receive_messages()))
|
265
|
-
background_tasks.append(self._eventloop.create_task(self._handle_received_messages()))
|
267
|
+
first_run = True
|
266
268
|
|
267
|
-
|
268
|
-
|
269
|
+
while (first_run or self.reconnect) and not self._stop_event.is_set():
|
270
|
+
first_run = False
|
271
|
+
self._restart_connection_event = asyncio.Event()
|
272
|
+
await self._connect_and_run()
|
273
|
+
time.sleep(1)
|
269
274
|
|
270
|
-
|
275
|
+
logger.debug("Finished S2 connection eventloop.")
|
271
276
|
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
await task
|
277
|
-
except asyncio.CancelledError:
|
278
|
-
pass
|
279
|
-
except websockets.ConnectionClosedError:
|
280
|
-
logger.info("The other party closed the websocket connection.c")
|
277
|
+
async def _connect_and_run(self) -> None:
|
278
|
+
self._received_messages = asyncio.Queue()
|
279
|
+
await self._connect_ws()
|
280
|
+
if self.ws:
|
281
281
|
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
282
|
+
async def wait_till_stop() -> None:
|
283
|
+
await self._stop_event.wait()
|
284
|
+
|
285
|
+
async def wait_till_connection_restart() -> None:
|
286
|
+
await self._restart_connection_event.wait()
|
287
|
+
|
288
|
+
background_tasks = [
|
289
|
+
self._eventloop.create_task(self._receive_messages()),
|
290
|
+
self._eventloop.create_task(wait_till_stop()),
|
291
|
+
self._eventloop.create_task(self._connect_as_rm()),
|
292
|
+
self._eventloop.create_task(wait_till_connection_restart()),
|
293
|
+
]
|
294
|
+
|
295
|
+
(done, pending) = await asyncio.wait(
|
296
|
+
background_tasks, return_when=asyncio.FIRST_COMPLETED
|
297
|
+
)
|
298
|
+
if self._current_control_type:
|
299
|
+
self._current_control_type.deactivate(self)
|
300
|
+
self._current_control_type = None
|
301
|
+
|
302
|
+
for task in done:
|
303
|
+
try:
|
304
|
+
await task
|
305
|
+
except asyncio.CancelledError:
|
306
|
+
pass
|
307
|
+
except (websockets.ConnectionClosedError, websockets.ConnectionClosedOK):
|
308
|
+
logger.info("The other party closed the websocket connection.")
|
309
|
+
|
310
|
+
for task in pending:
|
311
|
+
try:
|
312
|
+
task.cancel()
|
313
|
+
await task
|
314
|
+
except asyncio.CancelledError:
|
315
|
+
pass
|
288
316
|
|
289
|
-
if self.ws:
|
290
317
|
await self.ws.close()
|
291
318
|
await self.ws.wait_closed()
|
292
|
-
logger.debug("Finished S2 connection eventloop.")
|
293
319
|
|
294
|
-
async def
|
295
|
-
|
320
|
+
async def _connect_ws(self) -> None:
|
321
|
+
try:
|
322
|
+
self.ws = await ws_connect(uri=self.url)
|
323
|
+
except (EOFError, OSError) as e:
|
324
|
+
logger.info("Could not connect due to: %s", str(e))
|
296
325
|
|
297
|
-
async def
|
326
|
+
async def _connect_as_rm(self) -> None:
|
298
327
|
await self.send_msg_and_await_reception_status_async(
|
299
328
|
Handshake(
|
300
329
|
message_id=uuid.uuid4(), role=self.role, supported_protocol_versions=[S2_VERSION]
|
@@ -302,6 +331,8 @@ class S2Connection: # pylint: disable=too-many-instance-attributes
|
|
302
331
|
)
|
303
332
|
logger.debug("Send handshake to CEM. Expecting Handshake and HandshakeResponse from CEM.")
|
304
333
|
|
334
|
+
await self._handle_received_messages()
|
335
|
+
|
305
336
|
async def handle_handshake(
|
306
337
|
self, _: "S2Connection", message: S2Message, send_okay: Awaitable[None]
|
307
338
|
) -> None:
|
@@ -427,7 +458,11 @@ class S2Connection: # pylint: disable=too-many-instance-attributes
|
|
427
458
|
|
428
459
|
json_msg = s2_msg.to_json()
|
429
460
|
logger.debug("Sending message %s", json_msg)
|
430
|
-
|
461
|
+
try:
|
462
|
+
await self.ws.send(json_msg)
|
463
|
+
except websockets.ConnectionClosedError as e:
|
464
|
+
logger.error("Unable to send message %s due to %s", s2_msg, str(e))
|
465
|
+
self._restart_connection_event.set()
|
431
466
|
|
432
467
|
async def respond_with_reception_status(
|
433
468
|
self, subject_message_id: str, status: ReceptionStatusValues, diagnostic_label: str
|
@@ -458,9 +493,17 @@ class S2Connection: # pylint: disable=too-many-instance-attributes
|
|
458
493
|
s2_msg.message_id, # type: ignore[attr-defined]
|
459
494
|
timeout_reception_status,
|
460
495
|
)
|
461
|
-
|
462
|
-
|
463
|
-
|
496
|
+
try:
|
497
|
+
reception_status = await self.reception_status_awaiter.wait_for_reception_status(
|
498
|
+
s2_msg.message_id, timeout_reception_status # type: ignore[attr-defined]
|
499
|
+
)
|
500
|
+
except TimeoutError:
|
501
|
+
logger.error(
|
502
|
+
"Did not receive a reception status on time for %s",
|
503
|
+
s2_msg.message_id, # type: ignore[attr-defined]
|
504
|
+
)
|
505
|
+
self._stop_event.set()
|
506
|
+
raise
|
464
507
|
|
465
508
|
if reception_status.status != ReceptionStatusValues.OK and raise_on_error:
|
466
509
|
raise RuntimeError(f"ReceptionStatus was not OK but rather {reception_status.status}")
|
@@ -3,6 +3,7 @@ import typing
|
|
3
3
|
|
4
4
|
from s2python.common import ControlType as ProtocolControlType
|
5
5
|
from s2python.frbc import FRBCInstruction
|
6
|
+
from s2python.ppbc import PPBCScheduleInstruction
|
6
7
|
from s2python.validate_values_mixin import S2Message
|
7
8
|
|
8
9
|
if typing.TYPE_CHECKING:
|
@@ -36,10 +37,33 @@ class FRBCControlType(S2ControlType):
|
|
36
37
|
) -> None: ...
|
37
38
|
|
38
39
|
@abc.abstractmethod
|
39
|
-
def activate(self, conn: "S2Connection") -> None:
|
40
|
+
def activate(self, conn: "S2Connection") -> None:
|
41
|
+
"""Overwrite with the actual dctivation logic of your Resource Manager for this particular control type."""
|
40
42
|
|
41
43
|
@abc.abstractmethod
|
42
|
-
def deactivate(self, conn: "S2Connection") -> None:
|
44
|
+
def deactivate(self, conn: "S2Connection") -> None:
|
45
|
+
"""Overwrite with the actual deactivation logic of your Resource Manager for this particular control type."""
|
46
|
+
|
47
|
+
|
48
|
+
class PPBCControlType(S2ControlType):
|
49
|
+
def get_protocol_control_type(self) -> ProtocolControlType:
|
50
|
+
return ProtocolControlType.POWER_PROFILE_BASED_CONTROL
|
51
|
+
|
52
|
+
def register_handlers(self, handlers: "MessageHandlers") -> None:
|
53
|
+
handlers.register_handler(PPBCScheduleInstruction, self.handle_instruction)
|
54
|
+
|
55
|
+
@abc.abstractmethod
|
56
|
+
def handle_instruction(
|
57
|
+
self, conn: "S2Connection", msg: S2Message, send_okay: typing.Callable[[], None]
|
58
|
+
) -> None: ...
|
59
|
+
|
60
|
+
@abc.abstractmethod
|
61
|
+
def activate(self, conn: "S2Connection") -> None:
|
62
|
+
"""Overwrite with the actual dctivation logic of your Resource Manager for this particular control type."""
|
63
|
+
|
64
|
+
@abc.abstractmethod
|
65
|
+
def deactivate(self, conn: "S2Connection") -> None:
|
66
|
+
"""Overwrite with the actual deactivation logic of your Resource Manager for this particular control type."""
|
43
67
|
|
44
68
|
|
45
69
|
class NoControlControlType(S2ControlType):
|
@@ -24,6 +24,8 @@ from s2python.frbc import (
|
|
24
24
|
FRBCTimerStatus,
|
25
25
|
FRBCUsageForecast,
|
26
26
|
)
|
27
|
+
from s2python.ppbc import PPBCScheduleInstruction
|
28
|
+
|
27
29
|
from s2python.validate_values_mixin import S2Message
|
28
30
|
from s2python.s2_validation_error import S2ValidationError
|
29
31
|
|
@@ -44,6 +46,7 @@ TYPE_TO_MESSAGE_CLASS: Dict[str, Type[S2Message]] = {
|
|
44
46
|
"FRBC.SystemDescription": FRBCSystemDescription,
|
45
47
|
"FRBC.TimerStatus": FRBCTimerStatus,
|
46
48
|
"FRBC.UsageForecast": FRBCUsageForecast,
|
49
|
+
"PPBC.ScheduleInstruction": PPBCScheduleInstruction,
|
47
50
|
"Handshake": Handshake,
|
48
51
|
"HandshakeResponse": HandshakeResponse,
|
49
52
|
"InstructionStatusUpdate": InstructionStatusUpdate,
|
@@ -86,7 +89,9 @@ class S2Parser:
|
|
86
89
|
return TYPE_TO_MESSAGE_CLASS[message_type].model_validate(message_json)
|
87
90
|
|
88
91
|
@staticmethod
|
89
|
-
def parse_as_message(
|
92
|
+
def parse_as_message(
|
93
|
+
unparsed_message: Union[dict, str, bytes], as_message: Type[M]
|
94
|
+
) -> M:
|
90
95
|
"""Parse the message to a specific S2 python message.
|
91
96
|
|
92
97
|
:param unparsed_message: The message as a JSON-formatted string or as a JSON-parsed dictionary.
|
@@ -98,7 +103,9 @@ class S2Parser:
|
|
98
103
|
return as_message.from_dict(message_json)
|
99
104
|
|
100
105
|
@staticmethod
|
101
|
-
def parse_message_type(
|
106
|
+
def parse_message_type(
|
107
|
+
unparsed_message: Union[dict, str, bytes],
|
108
|
+
) -> Optional[S2MessageType]:
|
102
109
|
"""Parse only the message type from the unparsed message.
|
103
110
|
|
104
111
|
This is useful to call before `parse_as_message` to retrieve the message type and allows for strictly-typed
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{s2_python-0.2.2 → s2_python-0.3.1}/src/s2python/frbc/frbc_fill_level_target_profile_element.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|