MTPPy2.0 0.1.5__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.
- examples/__init__.py +0 -0
- examples/minimal+pid.py +82 -0
- examples/minimal.py +32 -0
- examples/minimal_recipe.py +117 -0
- examples/pea_alarm_base.py +47 -0
- examples/pea_minimal.py +258 -0
- mtppy/__init__.py +1 -0
- mtppy/part1/__init__.py +4 -0
- mtppy/part1/empty_folder_test.py +7 -0
- mtppy/part3/__init__.py +4 -0
- mtppy/part3/data_assembly_set/__init__.py +4 -0
- mtppy/part3/data_assembly_set/active_elements/__init__.py +4 -0
- mtppy/part3/data_assembly_set/active_elements/active_element.py +22 -0
- mtppy/part3/data_assembly_set/active_elements/drives/__init__.py +4 -0
- mtppy/part3/data_assembly_set/active_elements/drives/ana_drv.py +446 -0
- mtppy/part3/data_assembly_set/active_elements/drives/ana_drv_test.py +567 -0
- mtppy/part3/data_assembly_set/active_elements/drives/bin_drv.py +365 -0
- mtppy/part3/data_assembly_set/active_elements/drives/bin_drv_test.py +503 -0
- mtppy/part3/data_assembly_set/active_elements/drives/mon_ana_drv.py +469 -0
- mtppy/part3/data_assembly_set/active_elements/drives/mon_ana_drv_test.py +418 -0
- mtppy/part3/data_assembly_set/active_elements/drives/mon_bin_drv.py +295 -0
- mtppy/part3/data_assembly_set/active_elements/drives/mon_bin_drv_test.py +265 -0
- mtppy/part3/data_assembly_set/active_elements/pid/__init__.py +4 -0
- mtppy/part3/data_assembly_set/active_elements/pid/pid_ctrl.py +333 -0
- mtppy/part3/data_assembly_set/active_elements/pid/pid_ctrl_test.py +156 -0
- mtppy/part3/data_assembly_set/active_elements/valves/__init__.py +4 -0
- mtppy/part3/data_assembly_set/active_elements/valves/ana_vlv.py +402 -0
- mtppy/part3/data_assembly_set/active_elements/valves/ana_vlv_test.py +732 -0
- mtppy/part3/data_assembly_set/active_elements/valves/bin_vlv.py +279 -0
- mtppy/part3/data_assembly_set/active_elements/valves/bin_vlv_test.py +585 -0
- mtppy/part3/data_assembly_set/active_elements/valves/mon_ana_vlv.py +402 -0
- mtppy/part3/data_assembly_set/active_elements/valves/mon_ana_vlv_test.py +270 -0
- mtppy/part3/data_assembly_set/active_elements/valves/mon_bin_vlv.py +286 -0
- mtppy/part3/data_assembly_set/active_elements/valves/mon_bin_vlv_test.py +224 -0
- mtppy/part3/data_assembly_set/base_functions/__init__.py +4 -0
- mtppy/part3/data_assembly_set/base_functions/operation_mode.py +252 -0
- mtppy/part3/data_assembly_set/base_functions/operation_mode_test.py +260 -0
- mtppy/part3/data_assembly_set/base_functions/oslevel.py +35 -0
- mtppy/part3/data_assembly_set/base_functions/source_mode.py +189 -0
- mtppy/part3/data_assembly_set/base_functions/source_mode_test.py +112 -0
- mtppy/part3/data_assembly_set/base_functions/wqc.py +75 -0
- mtppy/part3/data_assembly_set/base_functions/wqc_test.py +86 -0
- mtppy/part3/data_assembly_set/data_assembly.py +65 -0
- mtppy/part3/data_assembly_set/diagnostic_elements/__init__.py +4 -0
- mtppy/part3/data_assembly_set/diagnostic_elements/diagnostic_element.py +19 -0
- mtppy/part3/data_assembly_set/indicator_elements/__init__.py +4 -0
- mtppy/part3/data_assembly_set/indicator_elements/indicator_element.py +22 -0
- mtppy/part3/data_assembly_set/indicator_elements/views/__init__.py +4 -0
- mtppy/part3/data_assembly_set/indicator_elements/views/ana_view.py +68 -0
- mtppy/part3/data_assembly_set/indicator_elements/views/bin_view.py +73 -0
- mtppy/part3/data_assembly_set/indicator_elements/views/dint_view.py +76 -0
- mtppy/part3/data_assembly_set/indicator_elements/views/string_view.py +55 -0
- mtppy/part3/data_assembly_set/operation_elements/__init__.py +4 -0
- mtppy/part3/data_assembly_set/operation_elements/operation_element.py +19 -0
- mtppy/part3/data_assembly_set/pea_elements/__init__.py +4 -0
- mtppy/part3/data_assembly_set/pea_elements/pea_element.py +28 -0
- mtppy/part3/data_assembly_set/pea_elements/pea_information_label/__init__.py +4 -0
- mtppy/part3/data_assembly_set/pea_elements/pea_information_label/pea_information_label.py +231 -0
- mtppy/part3/data_assembly_set/pea_elements/web_server_url_info/__init__.py +4 -0
- mtppy/part3/data_assembly_set/pea_elements/web_server_url_info/web_server_url_info.py +42 -0
- mtppy/part3/definitions/__init__.py +4 -0
- mtppy/part3/definitions/mtp_access.py +15 -0
- mtppy/part4/__init__.py +4 -0
- mtppy/part4/automation_services/__init__.py +4 -0
- mtppy/part4/automation_services/base_functions/__init__.py +4 -0
- mtppy/part4/automation_services/base_functions/service_operation_mode.py +368 -0
- mtppy/part4/automation_services/base_functions/service_operation_mode_test.py +242 -0
- mtppy/part4/automation_services/base_functions/service_operator_interaction.py +62 -0
- mtppy/part4/automation_services/base_functions/service_source_mode.py +138 -0
- mtppy/part4/automation_services/base_functions/service_source_mode_test.py +179 -0
- mtppy/part4/automation_services/helpers/__init__.py +4 -0
- mtppy/part4/automation_services/helpers/command_en_control.py +330 -0
- mtppy/part4/automation_services/helpers/command_en_control_test.py +302 -0
- mtppy/part4/automation_services/helpers/state_machine.py +167 -0
- mtppy/part4/automation_services/helpers/state_machine_test.py +294 -0
- mtppy/part4/automation_services/helpers/thread_control.py +39 -0
- mtppy/part4/automation_services/helpers/thread_control_test.py +80 -0
- mtppy/part4/automation_services/procedure.py +111 -0
- mtppy/part4/automation_services/procedure_test.py +185 -0
- mtppy/part4/automation_services/service.py +463 -0
- mtppy/part4/automation_services/service_elements/__init__.py +4 -0
- mtppy/part4/automation_services/service_elements/parameter_elements/__init__.py +4 -0
- mtppy/part4/automation_services/service_elements/parameter_elements/ana_serv_param.py +108 -0
- mtppy/part4/automation_services/service_elements/parameter_elements/ana_serv_param_test.py +59 -0
- mtppy/part4/automation_services/service_elements/parameter_elements/bin_serv_param.py +70 -0
- mtppy/part4/automation_services/service_elements/parameter_elements/bin_serv_param_test.py +39 -0
- mtppy/part4/automation_services/service_elements/parameter_elements/common_serv_param.py +111 -0
- mtppy/part4/automation_services/service_elements/parameter_elements/dint_serv_param.py +77 -0
- mtppy/part4/automation_services/service_elements/parameter_elements/dint_serv_param_test.py +58 -0
- mtppy/part4/automation_services/service_elements/parameter_elements/parameter_element.py +175 -0
- mtppy/part4/automation_services/service_elements/parameter_elements/parameter_element_test.py +246 -0
- mtppy/part4/automation_services/service_elements/parameter_elements/string_serv_param.py +48 -0
- mtppy/part4/automation_services/service_elements/parameter_elements/string_serv_param_test.py +37 -0
- mtppy/part4/automation_services/service_elements/procedure_health_view.py +36 -0
- mtppy/part4/automation_services/service_elements/service_control.py +473 -0
- mtppy/part4/automation_services/service_elements/service_control_test.py +150 -0
- mtppy/part4/automation_services/service_elements/service_element.py +20 -0
- mtppy/part4/automation_services/service_test.py +407 -0
- mtppy/part4/definitions/__init__.py +4 -0
- mtppy/part4/definitions/command_codes.py +58 -0
- mtppy/part4/definitions/command_codes_test.py +44 -0
- mtppy/part4/definitions/state_codes.py +65 -0
- mtppy/part4/definitions/state_codes_test.py +44 -0
- mtppy/part4/process_values/__init__.py +4 -0
- mtppy/part4/process_values/base_functions/__init__.py +4 -0
- mtppy/part4/process_values/base_functions/vqc.py +48 -0
- mtppy/part4/process_values/input_elements/__init__.py +4 -0
- mtppy/part4/process_values/input_elements/ana_process_value_in.py +160 -0
- mtppy/part4/process_values/input_elements/bin_process_value_in.py +83 -0
- mtppy/part4/process_values/input_elements/dint_process_value_in.py +159 -0
- mtppy/part4/process_values/input_elements/input_element.py +40 -0
- mtppy/part4/process_values/input_elements/string_process_value_in.py +45 -0
- mtppy/part5/__init__.py +4 -0
- mtppy/part5/communication_object.py +99 -0
- mtppy/part5/communication_object_test.py +59 -0
- mtppy/part5/definitions/__init__.py +4 -0
- mtppy/part5/definitions/iec61131_data_types.py +31 -0
- mtppy/part5/definitions/iec61131_data_types_test.py +82 -0
- mtppy/part5/definitions/opcua_data_types.py +36 -0
- mtppy/part5/definitions/opcua_data_types_test.py +90 -0
- mtppy/part5/definitions/w3c_xml_data_types.py +177 -0
- mtppy/part5/definitions/w3c_xml_data_types_test.py +143 -0
- mtppy/part5/server_assembly_set/__init__.py +5 -0
- mtppy/part6/__init__.py +4 -0
- mtppy/part6/alarm_set/__init__.py +4 -0
- mtppy/part6/alarm_set/alarm.py +132 -0
- mtppy/part6/alarm_set/alarm_test.py +265 -0
- mtppy/pea/__init__.py +19 -0
- mtppy/pea/data_assembly_factory.py +124 -0
- mtppy/pea/data_assembly_factory_test.py +229 -0
- mtppy/pea/mtp_generator/__init__.py +4 -0
- mtppy/pea/mtp_generator/mtp_generator.py +1183 -0
- mtppy/pea/mtp_generator/mtp_generator_test.py +518 -0
- mtppy/pea/pea.py +139 -0
- mtppy/pea/pea_opcua_server/__init__.py +4 -0
- mtppy/pea/pea_opcua_server/marshalling.py +60 -0
- mtppy/pea/pea_opcua_server/opcua_options_provider/__init__.py +4 -0
- mtppy/pea/pea_opcua_server/opcua_options_provider/instances/basic_opcua_options_provider.py +50 -0
- mtppy/pea/pea_opcua_server/opcua_options_provider/opcua_options_provider.py +103 -0
- mtppy/pea/pea_opcua_server/pea_opcua_server.py +492 -0
- mtppy/pea/pea_opcua_server/subscription_list.py +55 -0
- mtppy/pea/pea_test.py +59 -0
- mtppy/pea/rmtp_pea.py +155 -0
- mtppy/pea/rmtp_pea_test.py +27 -0
- mtppy/pea/service_factory.py +178 -0
- mtppy/pea/service_factory_test.py +156 -0
- mtppy/pea/user_logic/__init__.py +4 -0
- mtppy/pea/user_logic/user_logic_pea.py +72 -0
- mtppy/pea/user_logic/user_logic_registry.py +106 -0
- mtppy/pea/user_logic/user_logic_registry_test.py +167 -0
- mtppy/pea/user_logic/user_logic_service.py +228 -0
- mtppy/pea/user_logic/user_logic_service_test.py +289 -0
- mtppy/utils/__init__.py +4 -0
- mtppy/utils/data_assembly_dict.py +61 -0
- mtppy/utils/data_assembly_dict_test.py +107 -0
- mtppy/utils/data_item.py +446 -0
- mtppy/utils/data_item_com_test.py +82 -0
- mtppy/utils/data_item_test.py +325 -0
- mtppy/utils/logging.py +23 -0
- mtppy/utils/logging_test.py +26 -0
- mtppy/utils/mtp_file_handling/__init__.py +4 -0
- mtppy/utils/mtp_file_handling/extract_manifest_from_mtp_file.py +22 -0
- mtppy/utils/mtp_file_handling/extract_mtp_file.py +22 -0
- mtppy/utils/mtp_file_handling/is_valid_mtp.py +22 -0
- mtppy/utils/mtp_file_handling/is_valid_path_for_manifest.py +15 -0
- mtppy/utils/mtp_file_handling/is_valid_path_to_manifest.py +17 -0
- mtppy/utils/mtp_file_handling/is_valid_path_to_mtp.py +17 -0
- mtppy/utils/mtp_file_handling/load_manifest_file.py +24 -0
- mtppy/utils/mtp_file_handling/mtp_reader/__init__.py +4 -0
- mtppy/utils/mtp_file_handling/mtp_reader/mtp_reader.py +103 -0
- mtppy/utils/mtp_file_handling/mtp_reader/mtp_reader_test.py +96 -0
- mtppy/utils/mtp_file_handling/mtp_reader/mtp_xml.py +226 -0
- mtppy/utils/mtp_file_handling/mtp_reader/mtp_xml_test.py +108 -0
- mtppy/utils/mtp_file_handling/mtp_writer/__init__.py +4 -0
- mtppy/utils/mtp_file_handling/mtp_writer/mtp_writer.py +77 -0
- mtppy/utils/mtp_file_handling/mtp_writer/ressources/get_content_types.py +10 -0
- mtppy/utils/mtp_file_handling/mtp_writer/ressources/get_rels.py +11 -0
- mtppy/utils/mtp_file_handling/mtp_writer/test_mtp_writer.py +25 -0
- mtppy/utils/mtp_file_handling/write_manifest_file.py +29 -0
- mtppy/utils/mtp_file_handling/write_manifest_file_test.py +22 -0
- mtppy/utils/mtp_file_handling/write_mtp_file.py +43 -0
- mtppy/utils/mtp_file_handling/write_mtp_file_test.py +22 -0
- mtppy/utils/testing.py +31 -0
- mtppy2_0-0.1.5.dist-info/METADATA +75 -0
- mtppy2_0-0.1.5.dist-info/RECORD +214 -0
- mtppy2_0-0.1.5.dist-info/WHEEL +5 -0
- mtppy2_0-0.1.5.dist-info/entry_points.txt +3 -0
- mtppy2_0-0.1.5.dist-info/licenses/LICENSE +21 -0
- mtppy2_0-0.1.5.dist-info/top_level.txt +4 -0
- tools/__init__.py +0 -0
- tools/create_bugreport.py +150 -0
- tools/inspect_mtp.py +110 -0
- utils/__init__.py +1 -0
- utils/file_handling/__init__.py +4 -0
- utils/file_handling/cleanup_folder.py +9 -0
- utils/file_handling/get_utc_foldername_with_ms.py +15 -0
- utils/file_handling/get_work_dir.py +9 -0
- utils/file_handling/is_valid_path_for_json.py +11 -0
- utils/file_handling/is_valid_path_to_json.py +17 -0
- utils/file_handling/load_json_file.py +18 -0
- utils/file_handling/read_file_from_file_archive.py +43 -0
- utils/file_handling/read_file_string.py +10 -0
- utils/file_handling/validate_json_data.py +28 -0
- utils/file_handling/write_json_file.py +23 -0
- utils/get_uuid.py +18 -0
- utils/get_uuid_test.py +17 -0
- utils/logging.py +100 -0
- utils/logging_test.py +67 -0
- utils/opcua/check_node.py +79 -0
- utils/resolve_unit/resolve_unit.py +11 -0
- utils/resolve_unit/unit_lib.py +2101 -0
- utils/resolve_unit/unit_lib_test.py +36 -0
- utils/type_conversion.py +236 -0
- utils/type_conversion_test.py +114 -0
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
"""Implementation of Service Control as specified in PNO MTP 2.0, Section x."""
|
|
2
|
+
|
|
3
|
+
__copyright__ = (
|
|
4
|
+
"Copyright (c) 2026 Dresden University of Technology, Process-to-Order Group"
|
|
5
|
+
)
|
|
6
|
+
__license__ = "MIT"
|
|
7
|
+
|
|
8
|
+
from collections.abc import Callable
|
|
9
|
+
from typing import ClassVar
|
|
10
|
+
|
|
11
|
+
from mtppy.utils.data_item import DataItem
|
|
12
|
+
from mtppy.part3.definitions.mtp_access import MTPAccess
|
|
13
|
+
from mtppy.part3.data_assembly_set.base_functions.oslevel import OSLevelBaseFunction
|
|
14
|
+
from mtppy.part4.automation_services.base_functions.service_operation_mode import (
|
|
15
|
+
ServiceOperationMode,
|
|
16
|
+
)
|
|
17
|
+
from mtppy.part4.automation_services.base_functions.service_operator_interaction import (
|
|
18
|
+
ServiceOperatorInteraction,
|
|
19
|
+
)
|
|
20
|
+
from mtppy.part4.automation_services.base_functions.service_source_mode import (
|
|
21
|
+
ServiceSourceMode,
|
|
22
|
+
)
|
|
23
|
+
from mtppy.part4.automation_services.service_elements.service_element import (
|
|
24
|
+
ServiceElement,
|
|
25
|
+
)
|
|
26
|
+
from mtppy.part5.definitions.w3c_xml_data_types import W3cXmlDataTypes
|
|
27
|
+
from mtppy.utils.logging import logger
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ServiceControl(ServiceElement):
|
|
31
|
+
# DataItem constant definitions
|
|
32
|
+
COMMAND_EN = "CommandEn"
|
|
33
|
+
COMMAND_OP = "CommandOp"
|
|
34
|
+
COMMAND_INT = "CommandInt"
|
|
35
|
+
COMMAND_EXT = "CommandExt"
|
|
36
|
+
STATE_CUR = "StateCur"
|
|
37
|
+
PROCEDURE_OP = "ProcedureOp"
|
|
38
|
+
PROCEDURE_INT = "ProcedureInt"
|
|
39
|
+
PROCEDURE_EXT = "ProcedureExt"
|
|
40
|
+
PROCEDURE_CUR = "ProcedureCur"
|
|
41
|
+
PROCEDURE_REQ = "ProcedureReq"
|
|
42
|
+
PROC_PARAM_APPLY_EN = "ProcParamApplyEn"
|
|
43
|
+
PROC_PARAM_APPLY_EXT = "ProcParamApplyExt"
|
|
44
|
+
PROC_PARAM_APPLY_OP = "ProcParamApplyOp"
|
|
45
|
+
PROC_PARAM_APPLY_INT = "ProcParamApplyInt"
|
|
46
|
+
CONFIG_PARAM_APPLY_EN = "ConfigParamApplyEn"
|
|
47
|
+
CONFIG_PARAM_APPLY_EXT = "ConfigParamApplyExt"
|
|
48
|
+
CONFIG_PARAM_APPLY_OP = "ConfigParamApplyOp"
|
|
49
|
+
CONFIG_PARAM_APPLY_INT = "ConfigParamApplyInt"
|
|
50
|
+
REPORT_VALUE_FREEZE = "ReportValueFreeze"
|
|
51
|
+
|
|
52
|
+
# Class-level data items dictionary
|
|
53
|
+
CLASS_DATA_ITEMS: ClassVar = {
|
|
54
|
+
COMMAND_EN: DataItem(
|
|
55
|
+
COMMAND_EN,
|
|
56
|
+
W3cXmlDataTypes.UNSIGNED_SHORT,
|
|
57
|
+
MTPAccess.ReadAccess,
|
|
58
|
+
0,
|
|
59
|
+
),
|
|
60
|
+
COMMAND_OP: DataItem(
|
|
61
|
+
COMMAND_OP,
|
|
62
|
+
W3cXmlDataTypes.UNSIGNED_SHORT,
|
|
63
|
+
MTPAccess.ReadWriteAccess,
|
|
64
|
+
0,
|
|
65
|
+
),
|
|
66
|
+
COMMAND_INT: DataItem(
|
|
67
|
+
COMMAND_INT,
|
|
68
|
+
W3cXmlDataTypes.UNSIGNED_SHORT,
|
|
69
|
+
MTPAccess.ReadAccess,
|
|
70
|
+
0,
|
|
71
|
+
),
|
|
72
|
+
COMMAND_EXT: DataItem(
|
|
73
|
+
COMMAND_EXT,
|
|
74
|
+
W3cXmlDataTypes.UNSIGNED_SHORT,
|
|
75
|
+
MTPAccess.ReadWriteAccess,
|
|
76
|
+
0,
|
|
77
|
+
),
|
|
78
|
+
STATE_CUR: DataItem(
|
|
79
|
+
STATE_CUR,
|
|
80
|
+
W3cXmlDataTypes.UNSIGNED_SHORT,
|
|
81
|
+
MTPAccess.ReadAccess,
|
|
82
|
+
0,
|
|
83
|
+
),
|
|
84
|
+
PROCEDURE_OP: DataItem(
|
|
85
|
+
PROCEDURE_OP,
|
|
86
|
+
W3cXmlDataTypes.UNSIGNED_SHORT,
|
|
87
|
+
MTPAccess.ReadWriteAccess,
|
|
88
|
+
0,
|
|
89
|
+
),
|
|
90
|
+
PROCEDURE_INT: DataItem(
|
|
91
|
+
PROCEDURE_INT,
|
|
92
|
+
W3cXmlDataTypes.UNSIGNED_SHORT,
|
|
93
|
+
MTPAccess.ReadAccess,
|
|
94
|
+
0,
|
|
95
|
+
),
|
|
96
|
+
PROCEDURE_EXT: DataItem(
|
|
97
|
+
PROCEDURE_EXT,
|
|
98
|
+
W3cXmlDataTypes.UNSIGNED_SHORT,
|
|
99
|
+
MTPAccess.ReadWriteAccess,
|
|
100
|
+
0,
|
|
101
|
+
),
|
|
102
|
+
PROCEDURE_CUR: DataItem(
|
|
103
|
+
PROCEDURE_CUR,
|
|
104
|
+
W3cXmlDataTypes.UNSIGNED_SHORT,
|
|
105
|
+
MTPAccess.ReadAccess,
|
|
106
|
+
0,
|
|
107
|
+
),
|
|
108
|
+
PROCEDURE_REQ: DataItem(
|
|
109
|
+
PROCEDURE_REQ,
|
|
110
|
+
W3cXmlDataTypes.UNSIGNED_SHORT,
|
|
111
|
+
MTPAccess.ReadAccess,
|
|
112
|
+
0,
|
|
113
|
+
),
|
|
114
|
+
PROC_PARAM_APPLY_EN: DataItem(
|
|
115
|
+
PROC_PARAM_APPLY_EN,
|
|
116
|
+
W3cXmlDataTypes.BOOLEAN,
|
|
117
|
+
MTPAccess.ReadAccess,
|
|
118
|
+
0,
|
|
119
|
+
),
|
|
120
|
+
PROC_PARAM_APPLY_EXT: DataItem(
|
|
121
|
+
PROC_PARAM_APPLY_EXT,
|
|
122
|
+
W3cXmlDataTypes.BOOLEAN,
|
|
123
|
+
MTPAccess.ReadWriteAccess,
|
|
124
|
+
0,
|
|
125
|
+
),
|
|
126
|
+
PROC_PARAM_APPLY_OP: DataItem(
|
|
127
|
+
PROC_PARAM_APPLY_OP,
|
|
128
|
+
W3cXmlDataTypes.BOOLEAN,
|
|
129
|
+
MTPAccess.ReadWriteAccess,
|
|
130
|
+
0,
|
|
131
|
+
),
|
|
132
|
+
PROC_PARAM_APPLY_INT: DataItem(
|
|
133
|
+
PROC_PARAM_APPLY_INT,
|
|
134
|
+
W3cXmlDataTypes.BOOLEAN,
|
|
135
|
+
MTPAccess.ReadAccess,
|
|
136
|
+
0,
|
|
137
|
+
),
|
|
138
|
+
CONFIG_PARAM_APPLY_EN: DataItem(
|
|
139
|
+
CONFIG_PARAM_APPLY_EN,
|
|
140
|
+
W3cXmlDataTypes.BOOLEAN,
|
|
141
|
+
MTPAccess.ReadAccess,
|
|
142
|
+
0,
|
|
143
|
+
),
|
|
144
|
+
CONFIG_PARAM_APPLY_EXT: DataItem(
|
|
145
|
+
CONFIG_PARAM_APPLY_EXT,
|
|
146
|
+
W3cXmlDataTypes.BOOLEAN,
|
|
147
|
+
MTPAccess.ReadWriteAccess,
|
|
148
|
+
0,
|
|
149
|
+
),
|
|
150
|
+
CONFIG_PARAM_APPLY_OP: DataItem(
|
|
151
|
+
CONFIG_PARAM_APPLY_OP,
|
|
152
|
+
W3cXmlDataTypes.BOOLEAN,
|
|
153
|
+
MTPAccess.ReadWriteAccess,
|
|
154
|
+
0,
|
|
155
|
+
),
|
|
156
|
+
CONFIG_PARAM_APPLY_INT: DataItem(
|
|
157
|
+
CONFIG_PARAM_APPLY_INT,
|
|
158
|
+
W3cXmlDataTypes.BOOLEAN,
|
|
159
|
+
MTPAccess.ReadAccess,
|
|
160
|
+
0,
|
|
161
|
+
),
|
|
162
|
+
REPORT_VALUE_FREEZE: DataItem(
|
|
163
|
+
REPORT_VALUE_FREEZE,
|
|
164
|
+
W3cXmlDataTypes.BOOLEAN,
|
|
165
|
+
MTPAccess.ReadWriteAccess,
|
|
166
|
+
0,
|
|
167
|
+
),
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
os_level: OSLevelBaseFunction
|
|
171
|
+
service_op_mode: ServiceOperationMode
|
|
172
|
+
service_src_mode: ServiceSourceMode
|
|
173
|
+
service_operator_interaction: ServiceOperatorInteraction
|
|
174
|
+
procedure_keys: list[int]
|
|
175
|
+
execution_procedure: Callable
|
|
176
|
+
|
|
177
|
+
def __init__(
|
|
178
|
+
self,
|
|
179
|
+
tag_name: str,
|
|
180
|
+
tag_description: str = "",
|
|
181
|
+
procedure_keys: list[int] | None = None,
|
|
182
|
+
execution_procedure: Callable | None = None,
|
|
183
|
+
):
|
|
184
|
+
super().__init__(tag_name, tag_description)
|
|
185
|
+
self.mtpObjectType = (
|
|
186
|
+
"MTPDataAssemblySUCLib/DataAssembly/ServiceElement/ServiceControl"
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
self.os_level = OSLevelBaseFunction()
|
|
190
|
+
self.service_op_mode = ServiceOperationMode()
|
|
191
|
+
self.service_src_mode = ServiceSourceMode()
|
|
192
|
+
self.service_operator_interaction = ServiceOperatorInteraction()
|
|
193
|
+
|
|
194
|
+
self.procedure_keys: list[int] = (
|
|
195
|
+
procedure_keys if procedure_keys is not None else []
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
# Initialize data items with dynamic values (using class-defined data items)
|
|
199
|
+
self.get_item(ServiceControl.COMMAND_OP).init_value = 0
|
|
200
|
+
self.get_item(ServiceControl.COMMAND_EXT).init_value = 0
|
|
201
|
+
self.get_item(ServiceControl.PROCEDURE_OP).init_value = 0
|
|
202
|
+
self.get_item(ServiceControl.PROCEDURE_EXT).init_value = 0
|
|
203
|
+
self.get_item(ServiceControl.PROC_PARAM_APPLY_EXT).init_value = 0
|
|
204
|
+
self.get_item(ServiceControl.PROC_PARAM_APPLY_OP).init_value = 0
|
|
205
|
+
self.get_item(ServiceControl.CONFIG_PARAM_APPLY_EXT).init_value = 0
|
|
206
|
+
self.get_item(ServiceControl.CONFIG_PARAM_APPLY_OP).init_value = 0
|
|
207
|
+
self.get_item(ServiceControl.REPORT_VALUE_FREEZE).init_value = 0
|
|
208
|
+
|
|
209
|
+
self.get_item(ServiceControl.COMMAND_OP).ext_wrt_cb = self.set_command_op
|
|
210
|
+
self.get_item(ServiceControl.COMMAND_EXT).ext_wrt_cb = self.set_command_ext
|
|
211
|
+
self.get_item(ServiceControl.PROCEDURE_OP).ext_wrt_cb = self.set_procedure_op
|
|
212
|
+
self.get_item(ServiceControl.PROCEDURE_EXT).ext_wrt_cb = self.set_procedure_ext
|
|
213
|
+
self.get_item(ServiceControl.PROC_PARAM_APPLY_EXT).ext_wrt_cb = (
|
|
214
|
+
self.set_proc_param_apply_ext
|
|
215
|
+
)
|
|
216
|
+
self.get_item(ServiceControl.PROC_PARAM_APPLY_OP).ext_wrt_cb = (
|
|
217
|
+
self.set_proc_param_apply_op
|
|
218
|
+
)
|
|
219
|
+
self.get_item(ServiceControl.CONFIG_PARAM_APPLY_EXT).ext_wrt_cb = (
|
|
220
|
+
self.set_config_param_apply_ext
|
|
221
|
+
)
|
|
222
|
+
self.get_item(ServiceControl.CONFIG_PARAM_APPLY_OP).ext_wrt_cb = (
|
|
223
|
+
self.set_config_param_apply_op
|
|
224
|
+
)
|
|
225
|
+
self.get_item(ServiceControl.REPORT_VALUE_FREEZE).ext_wrt_cb = (
|
|
226
|
+
self.set_report_value_freeze
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
self.execution_procedure = execution_procedure or self.dummy_procedure
|
|
230
|
+
|
|
231
|
+
def dummy_procedure(self, value: int) -> None:
|
|
232
|
+
"""A dummy procedure for testing purposes.
|
|
233
|
+
|
|
234
|
+
Args:
|
|
235
|
+
value: Value to log during the dummy procedure call.
|
|
236
|
+
"""
|
|
237
|
+
logger.debug(f"calling self.dummy_procedure with value {value}")
|
|
238
|
+
|
|
239
|
+
def add_procedure_key(self, value: int) -> None:
|
|
240
|
+
"""Add a procedure key to the list of valid keys.
|
|
241
|
+
|
|
242
|
+
Args:
|
|
243
|
+
value: The procedure key to add.
|
|
244
|
+
|
|
245
|
+
"""
|
|
246
|
+
if value != 0 and value not in self.procedure_keys:
|
|
247
|
+
self.procedure_keys.append(value)
|
|
248
|
+
|
|
249
|
+
def remove_procedure_key(self, value: int) -> None:
|
|
250
|
+
"""Remove a procedure key from the list of valid keys.
|
|
251
|
+
|
|
252
|
+
Args:
|
|
253
|
+
value: The procedure key to remove.
|
|
254
|
+
|
|
255
|
+
"""
|
|
256
|
+
if value != 0 and value in self.procedure_keys:
|
|
257
|
+
self.procedure_keys.remove(value)
|
|
258
|
+
|
|
259
|
+
def set_command_op(self, value: int) -> None:
|
|
260
|
+
"""Set the operator command.
|
|
261
|
+
|
|
262
|
+
Args:
|
|
263
|
+
value: The value to set for the operator command.
|
|
264
|
+
|
|
265
|
+
"""
|
|
266
|
+
logger.debug(f"call {self.execution_procedure} with value {value}")
|
|
267
|
+
self.execution_procedure(value)
|
|
268
|
+
# Handshake
|
|
269
|
+
self[ServiceControl.COMMAND_OP] = 0
|
|
270
|
+
# self.get_item(ServiceControl.COMMAND_OP)._value = 0
|
|
271
|
+
# self.get_item(ServiceControl.COMMAND_OP)._notify_external_subscribers()
|
|
272
|
+
|
|
273
|
+
def set_command_ext(self, value: int) -> None:
|
|
274
|
+
"""Set the external command.
|
|
275
|
+
|
|
276
|
+
Args:
|
|
277
|
+
value: The value to set for the external command.
|
|
278
|
+
|
|
279
|
+
"""
|
|
280
|
+
# self[ServiceControl.COMMAND_EXT] = value
|
|
281
|
+
self.execution_procedure(value)
|
|
282
|
+
self[ServiceControl.COMMAND_EXT] = 0
|
|
283
|
+
|
|
284
|
+
def set_command_int(self, value: int) -> None:
|
|
285
|
+
"""Set the internal command.
|
|
286
|
+
|
|
287
|
+
Args:
|
|
288
|
+
value: The value to set for the internal command.
|
|
289
|
+
|
|
290
|
+
"""
|
|
291
|
+
self[ServiceControl.COMMAND_INT] = value
|
|
292
|
+
|
|
293
|
+
def set_proc_param_apply_en(self, value: bool) -> None:
|
|
294
|
+
"""Set the procedure parameter apply enable.
|
|
295
|
+
|
|
296
|
+
Args:
|
|
297
|
+
value: The boolean value to set for the procedure parameter apply enable.
|
|
298
|
+
|
|
299
|
+
"""
|
|
300
|
+
self[ServiceControl.PROC_PARAM_APPLY_EN] = value
|
|
301
|
+
|
|
302
|
+
def set_proc_param_apply_ext(self, value: bool) -> None:
|
|
303
|
+
"""Set the external procedure parameter apply signal.
|
|
304
|
+
|
|
305
|
+
Args:
|
|
306
|
+
value: The boolean value to set for the external procedure parameter apply.
|
|
307
|
+
|
|
308
|
+
"""
|
|
309
|
+
self[ServiceControl.PROC_PARAM_APPLY_EXT] = value
|
|
310
|
+
|
|
311
|
+
def set_proc_param_apply_op(self, value: bool) -> None:
|
|
312
|
+
"""Set the operator procedure parameter apply signal.
|
|
313
|
+
|
|
314
|
+
Args:
|
|
315
|
+
value: The boolean value to set for the operator procedure parameter apply.
|
|
316
|
+
|
|
317
|
+
"""
|
|
318
|
+
self[ServiceControl.PROC_PARAM_APPLY_OP] = value
|
|
319
|
+
|
|
320
|
+
def set_proc_param_apply_int(self, value: bool) -> None:
|
|
321
|
+
"""Set the internal procedure parameter apply signal.
|
|
322
|
+
|
|
323
|
+
Args:
|
|
324
|
+
value: The boolean value to set for the internal procedure parameter apply.
|
|
325
|
+
|
|
326
|
+
"""
|
|
327
|
+
self[ServiceControl.PROC_PARAM_APPLY_INT] = value
|
|
328
|
+
|
|
329
|
+
def apply_proc_param(self) -> None:
|
|
330
|
+
"""Apply procedure parameters if enabled."""
|
|
331
|
+
if self[ServiceControl.PROC_PARAM_APPLY_EN]:
|
|
332
|
+
# Get ProcCur, Resolve Procedure and fire callback to update Procedures
|
|
333
|
+
self[ServiceControl.CONFIG_PARAM_APPLY_EXT] = False
|
|
334
|
+
self[ServiceControl.CONFIG_PARAM_APPLY_INT] = False
|
|
335
|
+
self[ServiceControl.CONFIG_PARAM_APPLY_OP] = False
|
|
336
|
+
|
|
337
|
+
def set_config_param_apply_en(self, value: bool) -> None:
|
|
338
|
+
"""Set the configuration parameter apply enable.
|
|
339
|
+
|
|
340
|
+
Args:
|
|
341
|
+
value: The boolean value to set for the configuration parameter apply enable.
|
|
342
|
+
|
|
343
|
+
"""
|
|
344
|
+
self[ServiceControl.CONFIG_PARAM_APPLY_EN] = value
|
|
345
|
+
|
|
346
|
+
def set_config_param_apply_ext(self, value: bool) -> None:
|
|
347
|
+
"""Set the external configuration parameter apply signal.
|
|
348
|
+
|
|
349
|
+
Args:
|
|
350
|
+
value: The boolean value to set for the external configuration parameter apply.
|
|
351
|
+
|
|
352
|
+
"""
|
|
353
|
+
self[ServiceControl.CONFIG_PARAM_APPLY_EXT] = value
|
|
354
|
+
|
|
355
|
+
def set_config_param_apply_op(self, value: bool) -> None:
|
|
356
|
+
"""Set the operator configuration parameter apply signal.
|
|
357
|
+
|
|
358
|
+
Args:
|
|
359
|
+
value: The boolean value to set for the operator configuration parameter apply.
|
|
360
|
+
|
|
361
|
+
"""
|
|
362
|
+
self[ServiceControl.CONFIG_PARAM_APPLY_OP] = value
|
|
363
|
+
|
|
364
|
+
def set_config_param_apply_int(self, value: bool) -> None:
|
|
365
|
+
"""Set the internal configuration parameter apply signal.
|
|
366
|
+
|
|
367
|
+
Args:
|
|
368
|
+
value: The boolean value to set for the internal configuration parameter apply.
|
|
369
|
+
|
|
370
|
+
"""
|
|
371
|
+
self[ServiceControl.CONFIG_PARAM_APPLY_INT] = value
|
|
372
|
+
|
|
373
|
+
def apply_config_param(self) -> None:
|
|
374
|
+
"""Apply configuration parameters if enabled."""
|
|
375
|
+
if self[ServiceControl.CONFIG_PARAM_APPLY_EN]:
|
|
376
|
+
# Get ProcCur, Resolve Procedure and fire callback to update Procedures
|
|
377
|
+
self[ServiceControl.CONFIG_PARAM_APPLY_EXT] = False
|
|
378
|
+
self[ServiceControl.CONFIG_PARAM_APPLY_INT] = False
|
|
379
|
+
self[ServiceControl.CONFIG_PARAM_APPLY_OP] = False
|
|
380
|
+
|
|
381
|
+
def set_report_value_freeze(self, value: bool) -> None:
|
|
382
|
+
"""Set the report value freeze control.
|
|
383
|
+
|
|
384
|
+
Args:
|
|
385
|
+
value: The boolean value to set for the report value freeze.
|
|
386
|
+
|
|
387
|
+
"""
|
|
388
|
+
self[ServiceControl.REPORT_VALUE_FREEZE] = value
|
|
389
|
+
|
|
390
|
+
def set_procedure_op(self, value: int) -> None:
|
|
391
|
+
"""Set the operator procedure.
|
|
392
|
+
|
|
393
|
+
Args:
|
|
394
|
+
value: The value to set for the operator procedure.
|
|
395
|
+
|
|
396
|
+
"""
|
|
397
|
+
if self.service_op_mode[ServiceOperationMode.STATE_OP_ACT]:
|
|
398
|
+
self.set_procedure_req(value)
|
|
399
|
+
logger.info(
|
|
400
|
+
f"ProcedureOp arg={value}, actual={self[ServiceControl.PROCEDURE_OP]}",
|
|
401
|
+
)
|
|
402
|
+
|
|
403
|
+
def set_procedure_int(self, value: int) -> None:
|
|
404
|
+
"""Set the internal procedure.
|
|
405
|
+
|
|
406
|
+
Args:
|
|
407
|
+
value: The value to set for the internal procedure.
|
|
408
|
+
"""
|
|
409
|
+
logger.info(f"ProcedureInt set to {value}")
|
|
410
|
+
if (
|
|
411
|
+
self.service_op_mode[ServiceOperationMode.STATE_AUT_ACT]
|
|
412
|
+
and self.service_src_mode[ServiceSourceMode.SRC_INT_ACT]
|
|
413
|
+
):
|
|
414
|
+
self.set_procedure_req(value)
|
|
415
|
+
|
|
416
|
+
def set_procedure_ext(self, value: int) -> None:
|
|
417
|
+
"""Set the external procedure.
|
|
418
|
+
|
|
419
|
+
Args:
|
|
420
|
+
value: The value to set for the external procedure.
|
|
421
|
+
"""
|
|
422
|
+
logger.info(f"ProcedureExt set to {value}")
|
|
423
|
+
if (
|
|
424
|
+
self.service_op_mode[ServiceOperationMode.STATE_AUT_ACT]
|
|
425
|
+
and self.service_src_mode[ServiceSourceMode.SRC_EXT_ACT]
|
|
426
|
+
):
|
|
427
|
+
self.set_procedure_req(value)
|
|
428
|
+
|
|
429
|
+
def valid_value(self, value: int) -> bool:
|
|
430
|
+
"""Check if a value is a valid procedure id
|
|
431
|
+
|
|
432
|
+
Args:
|
|
433
|
+
value: The value to check.
|
|
434
|
+
|
|
435
|
+
Returns:
|
|
436
|
+
True if value is in list of procedure keys, else False
|
|
437
|
+
|
|
438
|
+
"""
|
|
439
|
+
return not (value not in self.procedure_keys and value != 0)
|
|
440
|
+
|
|
441
|
+
def set_procedure_req(self, value: int) -> None:
|
|
442
|
+
"""Set the requested procedure if it is a valid procedure id,
|
|
443
|
+
else set the requested procedure parameter to 0 to indicate to
|
|
444
|
+
the POL that the request was invalid.
|
|
445
|
+
|
|
446
|
+
Args:
|
|
447
|
+
value: The value to set for the requested procedure.
|
|
448
|
+
|
|
449
|
+
"""
|
|
450
|
+
if self.valid_value(value):
|
|
451
|
+
self[ServiceControl.PROCEDURE_REQ] = value
|
|
452
|
+
else:
|
|
453
|
+
self[ServiceControl.PROCEDURE_REQ] = 0
|
|
454
|
+
logger.info(f"args={value}, result={self[ServiceControl.PROCEDURE_REQ]}")
|
|
455
|
+
|
|
456
|
+
def set_procedure_cur(self) -> None:
|
|
457
|
+
"""Set the current procedure based on the requested procedure."""
|
|
458
|
+
procedure_req = self[ServiceControl.PROCEDURE_REQ]
|
|
459
|
+
if self.valid_value(procedure_req):
|
|
460
|
+
self[ServiceControl.PROCEDURE_CUR] = procedure_req
|
|
461
|
+
# PNO MTP2.0 Part 4 requires resetting ProcedureOP and ProcedureExt (Section 8.2.4.4)
|
|
462
|
+
self[ServiceControl.PROCEDURE_OP] = 0
|
|
463
|
+
self[ServiceControl.PROCEDURE_EXT] = 0
|
|
464
|
+
logger.info(f"args={procedure_req}, result=self[ServiceControl.PROCEDURE_CUR]")
|
|
465
|
+
|
|
466
|
+
def get_procedure_cur(self) -> int:
|
|
467
|
+
"""Get the current procedure value.
|
|
468
|
+
|
|
469
|
+
Returns:
|
|
470
|
+
The current procedure value.
|
|
471
|
+
|
|
472
|
+
"""
|
|
473
|
+
return self[ServiceControl.PROCEDURE_CUR]
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"""test suite for service control."""
|
|
2
|
+
|
|
3
|
+
__copyright__ = (
|
|
4
|
+
"Copyright (c) 2026 Dresden University of Technology, Process-to-Order Group"
|
|
5
|
+
)
|
|
6
|
+
__license__ = "MIT"
|
|
7
|
+
|
|
8
|
+
import pytest
|
|
9
|
+
|
|
10
|
+
from mtppy.part4.automation_services.base_functions.service_operation_mode import (
|
|
11
|
+
ServiceOperationMode as SOM,
|
|
12
|
+
)
|
|
13
|
+
from mtppy.part4.automation_services.base_functions.service_source_mode import (
|
|
14
|
+
ServiceSourceMode as ssm,
|
|
15
|
+
)
|
|
16
|
+
from mtppy.part4.automation_services.service_elements.service_control import (
|
|
17
|
+
ServiceControl as sc,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def init_service_control(service_op_mode: str = "off", service_src_mode: str = "int"):
|
|
22
|
+
|
|
23
|
+
service_control = sc("Dummy", procedure_keys=[1, 2, 3, 4])
|
|
24
|
+
|
|
25
|
+
if service_op_mode == "off":
|
|
26
|
+
service_control.service_op_mode[SOM.STATE_OFF_ACT] = True
|
|
27
|
+
service_control.service_op_mode[SOM.STATE_OFF_AUT] = True
|
|
28
|
+
service_control.service_op_mode[SOM.STATE_OFF_OP] = True
|
|
29
|
+
elif service_op_mode == "op":
|
|
30
|
+
service_control.service_op_mode[SOM.STATE_AUT_ACT] = False
|
|
31
|
+
service_control.service_op_mode[SOM.STATE_OFF_ACT] = False
|
|
32
|
+
service_control.service_op_mode[SOM.STATE_OP_ACT] = True
|
|
33
|
+
elif service_op_mode == "aut":
|
|
34
|
+
service_control.service_op_mode[SOM.STATE_AUT_ACT] = True
|
|
35
|
+
service_control.service_op_mode[SOM.STATE_OFF_ACT] = False
|
|
36
|
+
service_control.service_op_mode[SOM.STATE_OP_ACT] = False
|
|
37
|
+
else:
|
|
38
|
+
raise ValueError(f"ServiceOperationMode {service_op_mode} is unknown")
|
|
39
|
+
|
|
40
|
+
if service_src_mode == "int":
|
|
41
|
+
service_control.service_src_mode[ssm.SRC_INT_ACT] = True
|
|
42
|
+
elif service_src_mode == "ext":
|
|
43
|
+
service_control.service_src_mode[ssm.SRC_EXT_ACT] = True
|
|
44
|
+
else:
|
|
45
|
+
raise ValueError(f"ServiceSourceMode {service_src_mode} is unknown")
|
|
46
|
+
|
|
47
|
+
return service_control
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def check_valid_states(service_control, set_function, change_allowed=False):
|
|
51
|
+
for proc_id in range(4):
|
|
52
|
+
set_function(proc_id)
|
|
53
|
+
if change_allowed:
|
|
54
|
+
assert service_control[sc.PROCEDURE_REQ] == proc_id
|
|
55
|
+
else:
|
|
56
|
+
assert service_control[sc.PROCEDURE_REQ] == 0
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def check_invalid_states(service_control, set_function):
|
|
60
|
+
set_function(0)
|
|
61
|
+
set_function(10)
|
|
62
|
+
assert service_control[sc.PROCEDURE_REQ] == 0
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@pytest.mark.parametrize(
|
|
66
|
+
"service_control_mode,change_allowed",
|
|
67
|
+
[
|
|
68
|
+
("off", False),
|
|
69
|
+
("op", True),
|
|
70
|
+
("aut", False),
|
|
71
|
+
],
|
|
72
|
+
)
|
|
73
|
+
def test_set_procedure_op(service_control_mode, change_allowed):
|
|
74
|
+
service_control = init_service_control(service_control_mode)
|
|
75
|
+
check_valid_states(
|
|
76
|
+
service_control, service_control.set_procedure_op, change_allowed=change_allowed
|
|
77
|
+
)
|
|
78
|
+
check_invalid_states(service_control, service_control.set_procedure_op)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@pytest.mark.parametrize(
|
|
82
|
+
"service_op_mode,service_src_mode,change_allowed",
|
|
83
|
+
[
|
|
84
|
+
("off", "ext", False),
|
|
85
|
+
("off", "int", False),
|
|
86
|
+
("op", "ext", False),
|
|
87
|
+
("op", "int", False),
|
|
88
|
+
("aut", "ext", False),
|
|
89
|
+
("aut", "int", True),
|
|
90
|
+
],
|
|
91
|
+
)
|
|
92
|
+
def test_set_procedure_int(service_op_mode, service_src_mode, change_allowed):
|
|
93
|
+
service_control = init_service_control(service_op_mode, service_src_mode)
|
|
94
|
+
check_valid_states(
|
|
95
|
+
service_control,
|
|
96
|
+
service_control.set_procedure_int,
|
|
97
|
+
change_allowed=change_allowed,
|
|
98
|
+
)
|
|
99
|
+
check_invalid_states(service_control, service_control.set_procedure_int)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@pytest.mark.parametrize(
|
|
103
|
+
"service_op_mode,service_src_mode,change_allowed",
|
|
104
|
+
[
|
|
105
|
+
("off", "ext", False),
|
|
106
|
+
("off", "int", False),
|
|
107
|
+
("op", "ext", False),
|
|
108
|
+
("op", "int", False),
|
|
109
|
+
("aut", "ext", True),
|
|
110
|
+
("aut", "int", False),
|
|
111
|
+
],
|
|
112
|
+
)
|
|
113
|
+
def test_set_procedure_ext(service_op_mode, service_src_mode, change_allowed):
|
|
114
|
+
service_control = init_service_control(service_op_mode, service_src_mode)
|
|
115
|
+
check_valid_states(
|
|
116
|
+
service_control,
|
|
117
|
+
service_control.set_procedure_ext,
|
|
118
|
+
change_allowed=change_allowed,
|
|
119
|
+
)
|
|
120
|
+
check_invalid_states(service_control, service_control.set_procedure_ext)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def test_set_procedure_cur():
|
|
124
|
+
service_control = init_service_control("op")
|
|
125
|
+
for proc_id in range(4):
|
|
126
|
+
service_control.set_procedure_op(proc_id)
|
|
127
|
+
service_control.set_procedure_cur()
|
|
128
|
+
assert service_control[sc.PROCEDURE_CUR] == proc_id
|
|
129
|
+
|
|
130
|
+
service_control.set_procedure_op(0)
|
|
131
|
+
service_control.set_procedure_cur()
|
|
132
|
+
service_control.set_procedure_op(10)
|
|
133
|
+
service_control.set_procedure_cur()
|
|
134
|
+
assert service_control[sc.PROCEDURE_CUR] == 0
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
@pytest.mark.parametrize("command", [sc.COMMAND_OP, sc.COMMAND_EXT])
|
|
138
|
+
def test_command_handshake(command: str) -> None:
|
|
139
|
+
received_values: list[int] = []
|
|
140
|
+
service_control = sc(
|
|
141
|
+
"Dummy",
|
|
142
|
+
execution_procedure=received_values.append,
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
callback = service_control.get_item(command).ext_wrt_cb
|
|
146
|
+
assert callback is not None
|
|
147
|
+
callback(42)
|
|
148
|
+
|
|
149
|
+
assert received_values == [42]
|
|
150
|
+
assert service_control[command] == 0
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""Base Class for Service Elements."""
|
|
2
|
+
|
|
3
|
+
__copyright__ = (
|
|
4
|
+
"Copyright (c) 2026 Dresden University of Technology, Process-to-Order Group"
|
|
5
|
+
)
|
|
6
|
+
__license__ = "MIT"
|
|
7
|
+
|
|
8
|
+
from mtppy.part3.data_assembly_set.data_assembly import DataAssembly
|
|
9
|
+
from mtppy.part3.data_assembly_set.base_functions.wqc import WQCBaseFunction
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ServiceElement(DataAssembly):
|
|
13
|
+
|
|
14
|
+
wqc: WQCBaseFunction
|
|
15
|
+
|
|
16
|
+
def __init__(self, tag_name: str, tag_description: str):
|
|
17
|
+
super().__init__(tag_name, tag_description)
|
|
18
|
+
self.mtpObjectType = "MTPDataAssemblySUCLib/DataAssembly/ServiceElement"
|
|
19
|
+
|
|
20
|
+
self.wqc = WQCBaseFunction()
|