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.
Files changed (214) hide show
  1. examples/__init__.py +0 -0
  2. examples/minimal+pid.py +82 -0
  3. examples/minimal.py +32 -0
  4. examples/minimal_recipe.py +117 -0
  5. examples/pea_alarm_base.py +47 -0
  6. examples/pea_minimal.py +258 -0
  7. mtppy/__init__.py +1 -0
  8. mtppy/part1/__init__.py +4 -0
  9. mtppy/part1/empty_folder_test.py +7 -0
  10. mtppy/part3/__init__.py +4 -0
  11. mtppy/part3/data_assembly_set/__init__.py +4 -0
  12. mtppy/part3/data_assembly_set/active_elements/__init__.py +4 -0
  13. mtppy/part3/data_assembly_set/active_elements/active_element.py +22 -0
  14. mtppy/part3/data_assembly_set/active_elements/drives/__init__.py +4 -0
  15. mtppy/part3/data_assembly_set/active_elements/drives/ana_drv.py +446 -0
  16. mtppy/part3/data_assembly_set/active_elements/drives/ana_drv_test.py +567 -0
  17. mtppy/part3/data_assembly_set/active_elements/drives/bin_drv.py +365 -0
  18. mtppy/part3/data_assembly_set/active_elements/drives/bin_drv_test.py +503 -0
  19. mtppy/part3/data_assembly_set/active_elements/drives/mon_ana_drv.py +469 -0
  20. mtppy/part3/data_assembly_set/active_elements/drives/mon_ana_drv_test.py +418 -0
  21. mtppy/part3/data_assembly_set/active_elements/drives/mon_bin_drv.py +295 -0
  22. mtppy/part3/data_assembly_set/active_elements/drives/mon_bin_drv_test.py +265 -0
  23. mtppy/part3/data_assembly_set/active_elements/pid/__init__.py +4 -0
  24. mtppy/part3/data_assembly_set/active_elements/pid/pid_ctrl.py +333 -0
  25. mtppy/part3/data_assembly_set/active_elements/pid/pid_ctrl_test.py +156 -0
  26. mtppy/part3/data_assembly_set/active_elements/valves/__init__.py +4 -0
  27. mtppy/part3/data_assembly_set/active_elements/valves/ana_vlv.py +402 -0
  28. mtppy/part3/data_assembly_set/active_elements/valves/ana_vlv_test.py +732 -0
  29. mtppy/part3/data_assembly_set/active_elements/valves/bin_vlv.py +279 -0
  30. mtppy/part3/data_assembly_set/active_elements/valves/bin_vlv_test.py +585 -0
  31. mtppy/part3/data_assembly_set/active_elements/valves/mon_ana_vlv.py +402 -0
  32. mtppy/part3/data_assembly_set/active_elements/valves/mon_ana_vlv_test.py +270 -0
  33. mtppy/part3/data_assembly_set/active_elements/valves/mon_bin_vlv.py +286 -0
  34. mtppy/part3/data_assembly_set/active_elements/valves/mon_bin_vlv_test.py +224 -0
  35. mtppy/part3/data_assembly_set/base_functions/__init__.py +4 -0
  36. mtppy/part3/data_assembly_set/base_functions/operation_mode.py +252 -0
  37. mtppy/part3/data_assembly_set/base_functions/operation_mode_test.py +260 -0
  38. mtppy/part3/data_assembly_set/base_functions/oslevel.py +35 -0
  39. mtppy/part3/data_assembly_set/base_functions/source_mode.py +189 -0
  40. mtppy/part3/data_assembly_set/base_functions/source_mode_test.py +112 -0
  41. mtppy/part3/data_assembly_set/base_functions/wqc.py +75 -0
  42. mtppy/part3/data_assembly_set/base_functions/wqc_test.py +86 -0
  43. mtppy/part3/data_assembly_set/data_assembly.py +65 -0
  44. mtppy/part3/data_assembly_set/diagnostic_elements/__init__.py +4 -0
  45. mtppy/part3/data_assembly_set/diagnostic_elements/diagnostic_element.py +19 -0
  46. mtppy/part3/data_assembly_set/indicator_elements/__init__.py +4 -0
  47. mtppy/part3/data_assembly_set/indicator_elements/indicator_element.py +22 -0
  48. mtppy/part3/data_assembly_set/indicator_elements/views/__init__.py +4 -0
  49. mtppy/part3/data_assembly_set/indicator_elements/views/ana_view.py +68 -0
  50. mtppy/part3/data_assembly_set/indicator_elements/views/bin_view.py +73 -0
  51. mtppy/part3/data_assembly_set/indicator_elements/views/dint_view.py +76 -0
  52. mtppy/part3/data_assembly_set/indicator_elements/views/string_view.py +55 -0
  53. mtppy/part3/data_assembly_set/operation_elements/__init__.py +4 -0
  54. mtppy/part3/data_assembly_set/operation_elements/operation_element.py +19 -0
  55. mtppy/part3/data_assembly_set/pea_elements/__init__.py +4 -0
  56. mtppy/part3/data_assembly_set/pea_elements/pea_element.py +28 -0
  57. mtppy/part3/data_assembly_set/pea_elements/pea_information_label/__init__.py +4 -0
  58. mtppy/part3/data_assembly_set/pea_elements/pea_information_label/pea_information_label.py +231 -0
  59. mtppy/part3/data_assembly_set/pea_elements/web_server_url_info/__init__.py +4 -0
  60. mtppy/part3/data_assembly_set/pea_elements/web_server_url_info/web_server_url_info.py +42 -0
  61. mtppy/part3/definitions/__init__.py +4 -0
  62. mtppy/part3/definitions/mtp_access.py +15 -0
  63. mtppy/part4/__init__.py +4 -0
  64. mtppy/part4/automation_services/__init__.py +4 -0
  65. mtppy/part4/automation_services/base_functions/__init__.py +4 -0
  66. mtppy/part4/automation_services/base_functions/service_operation_mode.py +368 -0
  67. mtppy/part4/automation_services/base_functions/service_operation_mode_test.py +242 -0
  68. mtppy/part4/automation_services/base_functions/service_operator_interaction.py +62 -0
  69. mtppy/part4/automation_services/base_functions/service_source_mode.py +138 -0
  70. mtppy/part4/automation_services/base_functions/service_source_mode_test.py +179 -0
  71. mtppy/part4/automation_services/helpers/__init__.py +4 -0
  72. mtppy/part4/automation_services/helpers/command_en_control.py +330 -0
  73. mtppy/part4/automation_services/helpers/command_en_control_test.py +302 -0
  74. mtppy/part4/automation_services/helpers/state_machine.py +167 -0
  75. mtppy/part4/automation_services/helpers/state_machine_test.py +294 -0
  76. mtppy/part4/automation_services/helpers/thread_control.py +39 -0
  77. mtppy/part4/automation_services/helpers/thread_control_test.py +80 -0
  78. mtppy/part4/automation_services/procedure.py +111 -0
  79. mtppy/part4/automation_services/procedure_test.py +185 -0
  80. mtppy/part4/automation_services/service.py +463 -0
  81. mtppy/part4/automation_services/service_elements/__init__.py +4 -0
  82. mtppy/part4/automation_services/service_elements/parameter_elements/__init__.py +4 -0
  83. mtppy/part4/automation_services/service_elements/parameter_elements/ana_serv_param.py +108 -0
  84. mtppy/part4/automation_services/service_elements/parameter_elements/ana_serv_param_test.py +59 -0
  85. mtppy/part4/automation_services/service_elements/parameter_elements/bin_serv_param.py +70 -0
  86. mtppy/part4/automation_services/service_elements/parameter_elements/bin_serv_param_test.py +39 -0
  87. mtppy/part4/automation_services/service_elements/parameter_elements/common_serv_param.py +111 -0
  88. mtppy/part4/automation_services/service_elements/parameter_elements/dint_serv_param.py +77 -0
  89. mtppy/part4/automation_services/service_elements/parameter_elements/dint_serv_param_test.py +58 -0
  90. mtppy/part4/automation_services/service_elements/parameter_elements/parameter_element.py +175 -0
  91. mtppy/part4/automation_services/service_elements/parameter_elements/parameter_element_test.py +246 -0
  92. mtppy/part4/automation_services/service_elements/parameter_elements/string_serv_param.py +48 -0
  93. mtppy/part4/automation_services/service_elements/parameter_elements/string_serv_param_test.py +37 -0
  94. mtppy/part4/automation_services/service_elements/procedure_health_view.py +36 -0
  95. mtppy/part4/automation_services/service_elements/service_control.py +473 -0
  96. mtppy/part4/automation_services/service_elements/service_control_test.py +150 -0
  97. mtppy/part4/automation_services/service_elements/service_element.py +20 -0
  98. mtppy/part4/automation_services/service_test.py +407 -0
  99. mtppy/part4/definitions/__init__.py +4 -0
  100. mtppy/part4/definitions/command_codes.py +58 -0
  101. mtppy/part4/definitions/command_codes_test.py +44 -0
  102. mtppy/part4/definitions/state_codes.py +65 -0
  103. mtppy/part4/definitions/state_codes_test.py +44 -0
  104. mtppy/part4/process_values/__init__.py +4 -0
  105. mtppy/part4/process_values/base_functions/__init__.py +4 -0
  106. mtppy/part4/process_values/base_functions/vqc.py +48 -0
  107. mtppy/part4/process_values/input_elements/__init__.py +4 -0
  108. mtppy/part4/process_values/input_elements/ana_process_value_in.py +160 -0
  109. mtppy/part4/process_values/input_elements/bin_process_value_in.py +83 -0
  110. mtppy/part4/process_values/input_elements/dint_process_value_in.py +159 -0
  111. mtppy/part4/process_values/input_elements/input_element.py +40 -0
  112. mtppy/part4/process_values/input_elements/string_process_value_in.py +45 -0
  113. mtppy/part5/__init__.py +4 -0
  114. mtppy/part5/communication_object.py +99 -0
  115. mtppy/part5/communication_object_test.py +59 -0
  116. mtppy/part5/definitions/__init__.py +4 -0
  117. mtppy/part5/definitions/iec61131_data_types.py +31 -0
  118. mtppy/part5/definitions/iec61131_data_types_test.py +82 -0
  119. mtppy/part5/definitions/opcua_data_types.py +36 -0
  120. mtppy/part5/definitions/opcua_data_types_test.py +90 -0
  121. mtppy/part5/definitions/w3c_xml_data_types.py +177 -0
  122. mtppy/part5/definitions/w3c_xml_data_types_test.py +143 -0
  123. mtppy/part5/server_assembly_set/__init__.py +5 -0
  124. mtppy/part6/__init__.py +4 -0
  125. mtppy/part6/alarm_set/__init__.py +4 -0
  126. mtppy/part6/alarm_set/alarm.py +132 -0
  127. mtppy/part6/alarm_set/alarm_test.py +265 -0
  128. mtppy/pea/__init__.py +19 -0
  129. mtppy/pea/data_assembly_factory.py +124 -0
  130. mtppy/pea/data_assembly_factory_test.py +229 -0
  131. mtppy/pea/mtp_generator/__init__.py +4 -0
  132. mtppy/pea/mtp_generator/mtp_generator.py +1183 -0
  133. mtppy/pea/mtp_generator/mtp_generator_test.py +518 -0
  134. mtppy/pea/pea.py +139 -0
  135. mtppy/pea/pea_opcua_server/__init__.py +4 -0
  136. mtppy/pea/pea_opcua_server/marshalling.py +60 -0
  137. mtppy/pea/pea_opcua_server/opcua_options_provider/__init__.py +4 -0
  138. mtppy/pea/pea_opcua_server/opcua_options_provider/instances/basic_opcua_options_provider.py +50 -0
  139. mtppy/pea/pea_opcua_server/opcua_options_provider/opcua_options_provider.py +103 -0
  140. mtppy/pea/pea_opcua_server/pea_opcua_server.py +492 -0
  141. mtppy/pea/pea_opcua_server/subscription_list.py +55 -0
  142. mtppy/pea/pea_test.py +59 -0
  143. mtppy/pea/rmtp_pea.py +155 -0
  144. mtppy/pea/rmtp_pea_test.py +27 -0
  145. mtppy/pea/service_factory.py +178 -0
  146. mtppy/pea/service_factory_test.py +156 -0
  147. mtppy/pea/user_logic/__init__.py +4 -0
  148. mtppy/pea/user_logic/user_logic_pea.py +72 -0
  149. mtppy/pea/user_logic/user_logic_registry.py +106 -0
  150. mtppy/pea/user_logic/user_logic_registry_test.py +167 -0
  151. mtppy/pea/user_logic/user_logic_service.py +228 -0
  152. mtppy/pea/user_logic/user_logic_service_test.py +289 -0
  153. mtppy/utils/__init__.py +4 -0
  154. mtppy/utils/data_assembly_dict.py +61 -0
  155. mtppy/utils/data_assembly_dict_test.py +107 -0
  156. mtppy/utils/data_item.py +446 -0
  157. mtppy/utils/data_item_com_test.py +82 -0
  158. mtppy/utils/data_item_test.py +325 -0
  159. mtppy/utils/logging.py +23 -0
  160. mtppy/utils/logging_test.py +26 -0
  161. mtppy/utils/mtp_file_handling/__init__.py +4 -0
  162. mtppy/utils/mtp_file_handling/extract_manifest_from_mtp_file.py +22 -0
  163. mtppy/utils/mtp_file_handling/extract_mtp_file.py +22 -0
  164. mtppy/utils/mtp_file_handling/is_valid_mtp.py +22 -0
  165. mtppy/utils/mtp_file_handling/is_valid_path_for_manifest.py +15 -0
  166. mtppy/utils/mtp_file_handling/is_valid_path_to_manifest.py +17 -0
  167. mtppy/utils/mtp_file_handling/is_valid_path_to_mtp.py +17 -0
  168. mtppy/utils/mtp_file_handling/load_manifest_file.py +24 -0
  169. mtppy/utils/mtp_file_handling/mtp_reader/__init__.py +4 -0
  170. mtppy/utils/mtp_file_handling/mtp_reader/mtp_reader.py +103 -0
  171. mtppy/utils/mtp_file_handling/mtp_reader/mtp_reader_test.py +96 -0
  172. mtppy/utils/mtp_file_handling/mtp_reader/mtp_xml.py +226 -0
  173. mtppy/utils/mtp_file_handling/mtp_reader/mtp_xml_test.py +108 -0
  174. mtppy/utils/mtp_file_handling/mtp_writer/__init__.py +4 -0
  175. mtppy/utils/mtp_file_handling/mtp_writer/mtp_writer.py +77 -0
  176. mtppy/utils/mtp_file_handling/mtp_writer/ressources/get_content_types.py +10 -0
  177. mtppy/utils/mtp_file_handling/mtp_writer/ressources/get_rels.py +11 -0
  178. mtppy/utils/mtp_file_handling/mtp_writer/test_mtp_writer.py +25 -0
  179. mtppy/utils/mtp_file_handling/write_manifest_file.py +29 -0
  180. mtppy/utils/mtp_file_handling/write_manifest_file_test.py +22 -0
  181. mtppy/utils/mtp_file_handling/write_mtp_file.py +43 -0
  182. mtppy/utils/mtp_file_handling/write_mtp_file_test.py +22 -0
  183. mtppy/utils/testing.py +31 -0
  184. mtppy2_0-0.1.5.dist-info/METADATA +75 -0
  185. mtppy2_0-0.1.5.dist-info/RECORD +214 -0
  186. mtppy2_0-0.1.5.dist-info/WHEEL +5 -0
  187. mtppy2_0-0.1.5.dist-info/entry_points.txt +3 -0
  188. mtppy2_0-0.1.5.dist-info/licenses/LICENSE +21 -0
  189. mtppy2_0-0.1.5.dist-info/top_level.txt +4 -0
  190. tools/__init__.py +0 -0
  191. tools/create_bugreport.py +150 -0
  192. tools/inspect_mtp.py +110 -0
  193. utils/__init__.py +1 -0
  194. utils/file_handling/__init__.py +4 -0
  195. utils/file_handling/cleanup_folder.py +9 -0
  196. utils/file_handling/get_utc_foldername_with_ms.py +15 -0
  197. utils/file_handling/get_work_dir.py +9 -0
  198. utils/file_handling/is_valid_path_for_json.py +11 -0
  199. utils/file_handling/is_valid_path_to_json.py +17 -0
  200. utils/file_handling/load_json_file.py +18 -0
  201. utils/file_handling/read_file_from_file_archive.py +43 -0
  202. utils/file_handling/read_file_string.py +10 -0
  203. utils/file_handling/validate_json_data.py +28 -0
  204. utils/file_handling/write_json_file.py +23 -0
  205. utils/get_uuid.py +18 -0
  206. utils/get_uuid_test.py +17 -0
  207. utils/logging.py +100 -0
  208. utils/logging_test.py +67 -0
  209. utils/opcua/check_node.py +79 -0
  210. utils/resolve_unit/resolve_unit.py +11 -0
  211. utils/resolve_unit/unit_lib.py +2101 -0
  212. utils/resolve_unit/unit_lib_test.py +36 -0
  213. utils/type_conversion.py +236 -0
  214. utils/type_conversion_test.py +114 -0
@@ -0,0 +1,160 @@
1
+ """Implementation of Analog Process Value Input.
2
+
3
+ This module implements the AnaProcessValueIn class which represents an analog process value input
4
+ element in accordance with the MTP 2.0 specification.
5
+ """
6
+
7
+ __copyright__ = (
8
+ "Copyright (c) 2026 Dresden University of Technology, Process-to-Order Group"
9
+ )
10
+ __license__ = "MIT"
11
+
12
+ from typing import ClassVar
13
+
14
+ from mtppy.utils.logging import logger
15
+ from mtppy.utils.data_item import DataItem
16
+ from mtppy.part3.definitions.mtp_access import MTPAccess
17
+ from mtppy.part5.definitions.w3c_xml_data_types import W3cXmlDataTypes
18
+ from mtppy.part3.data_assembly_set.base_functions.oslevel import OSLevelBaseFunction
19
+ from mtppy.part4.process_values.input_elements.input_element import InputElement
20
+
21
+
22
+ class AnaProcessValueIn(InputElement):
23
+ """Analog Process Value Input (AnaProcessValueIn).
24
+
25
+ Implements an analog process value input element according to MTP 2.0 specification.
26
+ """
27
+
28
+ V_ = "V"
29
+ UNIT_CUR = "UnitCur"
30
+ SCL_MIN_CUR = "SclMinCur"
31
+ SCL_MAX_CUR = "SclMaxCur"
32
+ UNIT_EXT = "UnitExt"
33
+ SCL_MIN_EXT = "SclMinExt"
34
+ SCL_MAX_EXT = "SclMaxExt"
35
+ APPLY_EN = "ApplyEn"
36
+ APPLY_ = "Apply"
37
+
38
+ # Class-level data items dictionary
39
+ CLASS_DATA_ITEMS: ClassVar = {
40
+ V_: DataItem(V_, W3cXmlDataTypes.FLOAT, MTPAccess.ReadWriteAccess, 0),
41
+ UNIT_CUR: DataItem(UNIT_CUR, W3cXmlDataTypes.SHORT, MTPAccess.ReadAccess, 0),
42
+ SCL_MIN_CUR: DataItem(
43
+ SCL_MIN_CUR, W3cXmlDataTypes.FLOAT, MTPAccess.ReadAccess, 0
44
+ ),
45
+ SCL_MAX_CUR: DataItem(
46
+ SCL_MAX_CUR, W3cXmlDataTypes.FLOAT, MTPAccess.ReadAccess, 0
47
+ ),
48
+ UNIT_EXT: DataItem(
49
+ UNIT_EXT, W3cXmlDataTypes.SHORT, MTPAccess.ReadWriteAccess, 0, None
50
+ ),
51
+ SCL_MIN_EXT: DataItem(
52
+ SCL_MIN_EXT, W3cXmlDataTypes.FLOAT, MTPAccess.ReadWriteAccess, 0, None
53
+ ),
54
+ SCL_MAX_EXT: DataItem(
55
+ SCL_MAX_EXT, W3cXmlDataTypes.FLOAT, MTPAccess.ReadWriteAccess, 0, None
56
+ ),
57
+ APPLY_EN: DataItem(
58
+ APPLY_EN, W3cXmlDataTypes.BOOLEAN, MTPAccess.ReadAccess, False
59
+ ),
60
+ APPLY_: DataItem(
61
+ APPLY_, W3cXmlDataTypes.BOOLEAN, MTPAccess.ReadWriteAccess, False, None
62
+ ),
63
+ }
64
+
65
+ os_level: OSLevelBaseFunction
66
+
67
+ def __init__(
68
+ self,
69
+ tag_name: str,
70
+ tag_description: str,
71
+ v: float = 0,
72
+ scl_min_cur: float = 0,
73
+ scl_max_cur: float = 100,
74
+ unit_cur: int = 1998,
75
+ apply_en: bool = False,
76
+ ) -> None:
77
+ """Initialize the AnaProcessValueIn element.
78
+
79
+ Args:
80
+ tag_name: Name of the tag.
81
+ tag_description: Description of the tag.
82
+ v: Initial value for the V data item.
83
+ scl_min_cur: Current scale minimum value.
84
+ scl_max_cur: Current scale maximum value.
85
+ unit_cur: Current unit value.
86
+ apply_en: Apply enable flag.
87
+ """
88
+ super().__init__(tag_name, tag_description)
89
+ self.mtpObjectType = (
90
+ "MTPDataAssemblySUCLib/DataAssembly/InputElement/AnaProcessValueIn"
91
+ )
92
+
93
+ self.os_level = OSLevelBaseFunction()
94
+
95
+ # Set initial values for data items
96
+ self[self.V_] = v
97
+ self[self.UNIT_CUR] = unit_cur
98
+ self[self.SCL_MIN_CUR] = scl_min_cur
99
+ self[self.SCL_MAX_CUR] = scl_max_cur
100
+ self[self.UNIT_EXT] = 0
101
+ self[self.SCL_MIN_EXT] = 0
102
+ self[self.SCL_MAX_EXT] = 0
103
+ self[self.APPLY_EN] = apply_en
104
+
105
+ self.get_item(self.V_).ext_wrt_cb = self.set_v
106
+ self.get_item(self.UNIT_EXT).ext_wrt_cb = self._set_unit_ext
107
+ self.get_item(self.SCL_MIN_EXT).ext_wrt_cb = self._set_scl_min_ext
108
+ self.get_item(self.SCL_MAX_EXT).ext_wrt_cb = self._set_scl_max_ext
109
+ self.get_item(self.APPLY_).ext_wrt_cb = self.apply
110
+
111
+ def set_v(self, value: float) -> None:
112
+ """Set the V data item value.
113
+
114
+ Args:
115
+ value: The value to set for the V data item.
116
+ """
117
+ logger.debug(f"V set to {value}")
118
+ self[self.V_] = value
119
+
120
+ def _set_unit_ext(self, value: int) -> None:
121
+ """Set the UnitExt data item value.
122
+
123
+ Args:
124
+ value: The value to set for the UnitExt data item.
125
+ """
126
+ logger.debug(f"UnitExt set to {value}")
127
+ self[self.UNIT_EXT] = value
128
+
129
+ def _set_scl_min_ext(self, value: float) -> None:
130
+ """Set the SclMinExt data item value.
131
+
132
+ Args:
133
+ value: The value to set for the SclMinExt data item.
134
+ """
135
+ logger.debug("SclMinExt set to {value}")
136
+ self[self.SCL_MIN_EXT] = value
137
+
138
+ def _set_scl_max_ext(self, value: float) -> None:
139
+ """Set the SclMaxExt data item value.
140
+
141
+ Args:
142
+ value: The value to set for the SclMaxExt data item.
143
+ """
144
+ logger.debug(f"SclMaxExt set to {value}")
145
+ self[self.SCL_MAX_EXT] = value
146
+
147
+ def set_apply_en(self, value: bool) -> None:
148
+ """Set the ApplyEn data item value.
149
+
150
+ Args:
151
+ value: The boolean value to set for the ApplyEn data item.
152
+ """
153
+ self[self.APPLY_EN] = value
154
+
155
+ def apply(self) -> None:
156
+ """Apply the external values to current values."""
157
+ self[self.UNIT_CUR] = self[self.UNIT_EXT]
158
+ self[self.SCL_MIN_CUR] = self[self.SCL_MIN_EXT]
159
+ self[self.SCL_MAX_CUR] = self[self.SCL_MAX_EXT]
160
+ self[self.APPLY_] = False
@@ -0,0 +1,83 @@
1
+ """Implements Binary Process Value Input.
2
+
3
+ This module implements the BinProcessValueIn class which represents a binary process value input
4
+ element in accordance with the MTP 2.0 specification.
5
+ """
6
+
7
+ __copyright__ = (
8
+ "Copyright (c) 2026 Dresden University of Technology, Process-to-Order Group"
9
+ )
10
+ __license__ = "MIT"
11
+
12
+ from typing import ClassVar
13
+
14
+ from mtppy.utils.logging import logger
15
+ from mtppy.utils.data_item import DataItem
16
+ from mtppy.part3.definitions.mtp_access import MTPAccess
17
+ from mtppy.part5.definitions.w3c_xml_data_types import W3cXmlDataTypes
18
+ from mtppy.part3.data_assembly_set.base_functions.oslevel import OSLevelBaseFunction
19
+ from mtppy.part4.process_values.input_elements.input_element import InputElement
20
+
21
+
22
+ class BinProcessValueIn(InputElement):
23
+ """Binary Process Value Input (BinProcessValueIn).
24
+
25
+ Implements a binary process value input element according to MTP 2.0 specification.
26
+ """
27
+
28
+ V_ = "V"
29
+ V_STATE_0 = "VState0"
30
+ V_STATE_1 = "VState1"
31
+
32
+ # Class-level data items dictionary
33
+ CLASS_DATA_ITEMS: ClassVar = {
34
+ V_: DataItem(V_, W3cXmlDataTypes.BOOLEAN, MTPAccess.ReadWriteAccess, False),
35
+ V_STATE_0: DataItem(
36
+ V_STATE_0, W3cXmlDataTypes.STRING, MTPAccess.ReadAccess, ""
37
+ ),
38
+ V_STATE_1: DataItem(
39
+ V_STATE_1, W3cXmlDataTypes.STRING, MTPAccess.ReadAccess, ""
40
+ ),
41
+ }
42
+
43
+ os_level: OSLevelBaseFunction
44
+
45
+ def __init__(
46
+ self,
47
+ tag_name: str,
48
+ tag_description: str,
49
+ v: bool = False,
50
+ v_state_0: str = "False",
51
+ v_state_1: str = "True",
52
+ ) -> None:
53
+ """Initialize the BinProcessValueIn element.
54
+
55
+ Args:
56
+ tag_name: Name of the tag.
57
+ tag_description: Description of the tag.
58
+ v: Initial value for the V data item.
59
+ v_state_0: Value for VState0 data item.
60
+ v_state_1: Value for VState1 data item.
61
+ """
62
+ super().__init__(tag_name, tag_description)
63
+ self.mtpObjectType = (
64
+ "MTPDataAssemblySUCLib/DataAssembly/InputElement/BinProcessValueIn"
65
+ )
66
+
67
+ self.os_level = OSLevelBaseFunction()
68
+
69
+ # Set initial values for data items
70
+ self[self.V_] = v
71
+ self[self.V_STATE_0] = v_state_0
72
+ self[self.V_STATE_1] = v_state_1
73
+
74
+ self.get_item(self.V_).ext_wrt_cb = self.set_v
75
+
76
+ def set_v(self, value: bool) -> None:
77
+ """Set the V data item value.
78
+
79
+ Args:
80
+ value: The boolean value to set for the V data item.
81
+ """
82
+ logger.debug(f"V set to {value}")
83
+ self[self.V_] = value
@@ -0,0 +1,159 @@
1
+ """Implementation of DIntProcessValueIn
2
+
3
+ This module implements the DIntProcessValueIn class which represents a discrete integer
4
+ process value input element in accordance with the MTP 2.0 specification.
5
+ """
6
+
7
+ __copyright__ = (
8
+ "Copyright (c) 2026 Dresden University of Technology, Process-to-Order Group"
9
+ )
10
+ __license__ = "MIT"
11
+
12
+ from typing import ClassVar
13
+
14
+ from mtppy.utils.logging import logger
15
+ from mtppy.utils.data_item import DataItem
16
+ from mtppy.part3.definitions.mtp_access import MTPAccess
17
+ from mtppy.part5.definitions.w3c_xml_data_types import W3cXmlDataTypes
18
+ from mtppy.part3.data_assembly_set.base_functions.oslevel import OSLevelBaseFunction
19
+ from mtppy.part4.process_values.input_elements.input_element import InputElement
20
+
21
+
22
+ class DIntProcessValueIn(InputElement):
23
+ """Discrete Integer Process Value Input (DIntProcessValueIn)."""
24
+
25
+ V_ = "V"
26
+ UNIT_CUR = "UnitCur"
27
+ SCL_MIN_CUR = "SclMinCur"
28
+ SCL_MAX_CUR = "SclMaxCur"
29
+ UNIT_EXT = "UnitExt"
30
+ SCL_MIN_EXT = "SclMinExt"
31
+ SCL_MAX_EXT = "SclMaxExt"
32
+ APPLY_EN = "ApplyEn"
33
+ APPLY_ = "Apply"
34
+
35
+ # Class-level data items dictionary
36
+ CLASS_DATA_ITEMS: ClassVar = {
37
+ V_: DataItem(V_, W3cXmlDataTypes.SHORT, MTPAccess.ReadWriteAccess, 0),
38
+ UNIT_CUR: DataItem(UNIT_CUR, W3cXmlDataTypes.SHORT, MTPAccess.ReadAccess, 0),
39
+ SCL_MIN_CUR: DataItem(
40
+ SCL_MIN_CUR, W3cXmlDataTypes.SHORT, MTPAccess.ReadAccess, 0
41
+ ),
42
+ SCL_MAX_CUR: DataItem(
43
+ SCL_MAX_CUR, W3cXmlDataTypes.SHORT, MTPAccess.ReadAccess, 0
44
+ ),
45
+ UNIT_EXT: DataItem(
46
+ UNIT_EXT, W3cXmlDataTypes.SHORT, MTPAccess.ReadWriteAccess, 0
47
+ ),
48
+ SCL_MIN_EXT: DataItem(
49
+ SCL_MIN_EXT, W3cXmlDataTypes.SHORT, MTPAccess.ReadWriteAccess, 0
50
+ ),
51
+ SCL_MAX_EXT: DataItem(
52
+ SCL_MAX_EXT, W3cXmlDataTypes.SHORT, MTPAccess.ReadWriteAccess, 0
53
+ ),
54
+ APPLY_EN: DataItem(
55
+ APPLY_EN, W3cXmlDataTypes.BOOLEAN, MTPAccess.ReadAccess, False
56
+ ),
57
+ APPLY_: DataItem(
58
+ APPLY_, W3cXmlDataTypes.BOOLEAN, MTPAccess.ReadWriteAccess, False
59
+ ),
60
+ }
61
+
62
+ os_level: OSLevelBaseFunction
63
+
64
+ def __init__(
65
+ self,
66
+ tag_name: str,
67
+ tag_description: str,
68
+ v: int = 0,
69
+ scl_min_cur: int = 0,
70
+ scl_max_cur: int = 100,
71
+ unit_cur: int = 1998,
72
+ apply_en: bool = False,
73
+ ) -> None:
74
+ """Initialize the DIntProcessValueIn element.
75
+
76
+ Args:
77
+ tag_name: Name of the tag.
78
+ tag_description: Description of the tag.
79
+ v: Initial value for the V data item.
80
+ scl_min_cur: Current scale minimum value.
81
+ scl_max_cur: Current scale maximum value.
82
+ unit_cur: Current unit value.
83
+ apply_en: Apply enable flag.
84
+ """
85
+ super().__init__(tag_name, tag_description)
86
+ self.mtpObjectType = (
87
+ "MTPDataAssemblySUCLib/DataAssembly/InputElement/DIntProcessValueIn"
88
+ )
89
+
90
+ self.os_level = OSLevelBaseFunction()
91
+
92
+ # Set initial values for data items
93
+ self[self.V_] = v
94
+ self[self.UNIT_CUR] = unit_cur
95
+ self[self.SCL_MIN_CUR] = scl_min_cur
96
+ self[self.SCL_MAX_CUR] = scl_max_cur
97
+ self[self.UNIT_EXT] = 0
98
+ self[self.SCL_MIN_EXT] = 0
99
+ self[self.SCL_MAX_EXT] = 0
100
+ self[self.APPLY_EN] = apply_en
101
+ self[self.APPLY_] = False
102
+
103
+ # Setup callbacks
104
+ self.get_item(self.V_).ext_wrt_cb = self.set_v
105
+ self.get_item(self.UNIT_EXT).ext_wrt_cb = self.set_unit_ext
106
+ self.get_item(self.SCL_MIN_EXT).ext_wrt_cb = self.set_scl_min_ext
107
+ self.get_item(self.SCL_MAX_EXT).ext_wrt_cb = self.set_scl_max_ext
108
+ self.get_item(self.APPLY_).ext_wrt_cb = self.apply
109
+
110
+ def set_v(self, value: int) -> None:
111
+ """Set the V data item value.
112
+
113
+ Args:
114
+ value: The value to set for the V data item.
115
+ """
116
+ logger.debug(f"V set to {value}")
117
+ self[self.V_] = value
118
+
119
+ def set_unit_ext(self, value: int) -> None:
120
+ """Set the UnitExt data item value.
121
+
122
+ Args:
123
+ value: The value to set for the UnitExt data item.
124
+ """
125
+ logger.debug(f"UnitExt set to {value}")
126
+ self[self.UNIT_EXT] = value
127
+
128
+ def set_scl_min_ext(self, value: int) -> None:
129
+ """Set the SclMinExt data item value.
130
+
131
+ Args:
132
+ value: The value to set for the SclMinExt data item.
133
+ """
134
+ logger.debug(f"SclMinExt set to {value}")
135
+ self[self.SCL_MIN_EXT] = value
136
+
137
+ def set_scl_max_ext(self, value: int) -> None:
138
+ """Set the SclMaxExt data item value.
139
+
140
+ Args:
141
+ value: The value to set for the SclMaxExt data item.
142
+ """
143
+ logger.debug(f"SclMaxExt set to {value}")
144
+ self[self.SCL_MAX_EXT] = value
145
+
146
+ def set_apply_en(self, value: bool) -> None:
147
+ """Set the ApplyEn data item value.
148
+
149
+ Args:
150
+ value: The boolean value to set for the ApplyEn data item.
151
+ """
152
+ self[self.APPLY_EN] = value
153
+
154
+ def apply(self) -> None:
155
+ """Apply the external values to current values."""
156
+ self[self.UNIT_CUR] = self[self.UNIT_EXT]
157
+ self[self.SCL_MIN_CUR] = self[self.SCL_MIN_EXT]
158
+ self[self.SCL_MAX_CUR] = self[self.SCL_MAX_EXT]
159
+ self[self.APPLY_] = False
@@ -0,0 +1,40 @@
1
+ """Base Class for Input 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
+ from mtppy.part4.process_values.base_functions.vqc import VQCBaseFunction
11
+
12
+
13
+ class InputElement(DataAssembly):
14
+ """Base class for input elements in the process value framework.
15
+
16
+ Input elements provide data input capabilities with integrated quality control
17
+ through WQC (Write Quality Control) and VQC (Validation Quality Control) functions.
18
+ They inherit from DataAssembly and serve as the foundation for various input
19
+ element types in the system.
20
+
21
+ Attributes:
22
+ wqc: Write Quality Control function instance for managing write operations
23
+ vqc: Validation Quality Control function instance for validating data
24
+ """
25
+
26
+ wqc: WQCBaseFunction
27
+ vqc: VQCBaseFunction
28
+
29
+ def __init__(self, tag_name: str, tag_description: str):
30
+ """Initialize an InputElement instance.
31
+
32
+ Args:
33
+ tag_name: The name identifier for the input element
34
+ tag_description: A descriptive text for the input element
35
+ """
36
+ super().__init__(tag_name, tag_description)
37
+ self.mtpObjectType = "MTPDataAssemblySUCLib/DataAssembly/InputElement"
38
+
39
+ self.wqc = WQCBaseFunction()
40
+ self.vqc = VQCBaseFunction()
@@ -0,0 +1,45 @@
1
+ """Implementation of String Process Value Input.
2
+
3
+ This module implements the StringProcessValueIn class which represents an analog process value input
4
+ element in accordance with the MTP 2.0 specification.
5
+ """
6
+
7
+ __copyright__ = (
8
+ "Copyright (c) 2026 Dresden University of Technology, Process-to-Order Group"
9
+ )
10
+ __license__ = "MIT"
11
+
12
+ from typing import ClassVar
13
+
14
+ from mtppy.utils.logging import logger
15
+ from mtppy.utils.data_item import DataItem
16
+ from mtppy.part3.definitions.mtp_access import MTPAccess
17
+ from mtppy.part5.definitions.w3c_xml_data_types import W3cXmlDataTypes
18
+ from mtppy.part3.data_assembly_set.base_functions.oslevel import OSLevelBaseFunction
19
+ from mtppy.part4.process_values.input_elements.input_element import InputElement
20
+
21
+
22
+ class StringProcessValueIn(InputElement):
23
+ V_ = "V"
24
+
25
+ # Class-level data items dictionary
26
+ CLASS_DATA_ITEMS: ClassVar = {
27
+ V_: DataItem(V_, W3cXmlDataTypes.STRING, MTPAccess.ReadWriteAccess, "")
28
+ }
29
+
30
+ os_level: OSLevelBaseFunction
31
+
32
+ def __init__(self, tag_name: str, tag_description: str, v: str = ""):
33
+ super().__init__(tag_name, tag_description)
34
+ self.mtpObjectType = (
35
+ "MTPDataAssemblySUCLib/DataAssembly/InputElement/StringProcessValueIn"
36
+ )
37
+
38
+ self.os_level = OSLevelBaseFunction()
39
+
40
+ self[self.V_] = v
41
+ self.get_item(self.V_).ext_wrt_cb = self.set_v
42
+
43
+ def set_v(self, value):
44
+ logger.debug(f"V set to {value}")
45
+ self[self.V_] = value
@@ -0,0 +1,4 @@
1
+ __copyright__ = (
2
+ "Copyright (c) 2026 Dresden University of Technology, Process-to-Order Group"
3
+ )
4
+ __license__ = "MIT"
@@ -0,0 +1,99 @@
1
+ """Communication objects encapsulate value updates for external protocols."""
2
+
3
+ __copyright__ = (
4
+ "Copyright (c) 2026 Dresden University of Technology, Process-to-Order Group"
5
+ )
6
+ __license__ = "MIT"
7
+
8
+ from abc import ABC, abstractmethod
9
+ from typing import Any
10
+
11
+ from opcua import ua
12
+ from opcua.common.node import Node as OPCUA_Node
13
+
14
+ import utils.type_conversion as tc
15
+
16
+
17
+ class CommunicationObject(ABC):
18
+ """Base class for protocol-specific communication objects.
19
+
20
+ A communication object binds a protocol-specific node to a callback that a
21
+ DataItem can use to publish value changes.
22
+
23
+ Attributes:
24
+ write_value_callback: Public callback that delegates to the concrete
25
+ protocol-specific write implementation.
26
+ """
27
+
28
+ def __init__(self, node_obj: Any, node_id: str) -> None:
29
+ """Initialize a communication object.
30
+
31
+ Args:
32
+ node_obj: Protocol-specific node or client object used to write
33
+ values.
34
+ node_id: Identifier of the associated node or register. Its
35
+ interpretation is defined by the concrete subclass.
36
+ """
37
+ self._node_obj = node_obj
38
+ self._node_id = node_id
39
+ self.write_value_callback = self._set_value
40
+
41
+ @abstractmethod
42
+ def _set_value(self, value: tc.ANY_TYPE) -> None:
43
+ """Write a value using the protocol-specific implementation.
44
+
45
+ Args:
46
+ value: Value to write to the associated external node.
47
+ """
48
+
49
+
50
+ class OPCUACommunicationObject(CommunicationObject):
51
+ """Write DataItem values to an OPC UA node.
52
+
53
+ Values are wrapped in an ``opcua.ua.Variant`` before being passed to the
54
+ node's ``set_value`` method.
55
+ """
56
+
57
+ def __init__(self, opcua_node_obj: OPCUA_Node, node_id: str) -> None:
58
+ """Initialize an OPC UA communication object.
59
+
60
+ Args:
61
+ opcua_node_obj: OPC UA node that receives written values.
62
+ node_id: OPC UA node identifier retained for diagnostics and model
63
+ generation.
64
+ """
65
+ super().__init__(opcua_node_obj, node_id)
66
+
67
+ def _set_value(self, value: tc.ANY_TYPE) -> None:
68
+ """Set a value on the OPC UA node.
69
+
70
+ Args:
71
+ value: Value to wrap in an OPC UA Variant and write to the node.
72
+ """
73
+ self._node_obj.set_value(ua.Variant(value))
74
+
75
+
76
+ class MODBUSCommunicationObject(CommunicationObject):
77
+ """Write DataItem values to a Modbus holding register.
78
+
79
+ The ``node_obj`` is expected to be a pymodbus client exposing
80
+ ``write_register``. The string ``node_id`` is converted to an integer
81
+ register address for each write.
82
+ """
83
+
84
+ def __init__(self, modbus_client: Any, node_id: str) -> None:
85
+ """Initialize a Modbus communication object.
86
+
87
+ Args:
88
+ modbus_client: Pymodbus client used to write the register.
89
+ node_id: Register address represented as a string.
90
+ """
91
+ super().__init__(modbus_client, node_id)
92
+
93
+ def _set_value(self, value: tc.ANY_TYPE) -> None:
94
+ """Write a value to the configured Modbus holding register.
95
+
96
+ Args:
97
+ value: Integer-compatible value accepted by pymodbus.
98
+ """
99
+ self._node_obj.write_register(address=int(self._node_id), value=value)
@@ -0,0 +1,59 @@
1
+ """Test suite for the OPC UA communication object."""
2
+
3
+ __copyright__ = (
4
+ "Copyright (c) 2026 Dresden University of Technology, Process-to-Order Group"
5
+ )
6
+ __license__ = "MIT"
7
+
8
+ from unittest.mock import Mock
9
+ from typing import Any
10
+
11
+ from opcua import ua
12
+
13
+ from mtppy.part5.communication_object import (
14
+ CommunicationObject,
15
+ MODBUSCommunicationObject,
16
+ OPCUACommunicationObject,
17
+ )
18
+
19
+
20
+ class TestCommunicationObject(CommunicationObject):
21
+ def _set_value(self, value: Any) -> None:
22
+ self.written_value = value
23
+
24
+
25
+ def test_initializes_with_node_and_node_id() -> None:
26
+ node = Mock()
27
+
28
+ communication_object = OPCUACommunicationObject(node, "ns=2;s=Test")
29
+
30
+ assert callable(communication_object.write_value_callback)
31
+
32
+
33
+ def test_base_callback_delegates_to_protocol_specific_writer() -> None:
34
+ communication_object = TestCommunicationObject(Mock(), "test")
35
+
36
+ communication_object.write_value_callback("value")
37
+
38
+ assert communication_object.written_value == "value"
39
+
40
+
41
+ def test_write_value_callback_sets_variant_on_node() -> None:
42
+ node = Mock()
43
+ communication_object = OPCUACommunicationObject(node, "ns=2;s=Test")
44
+
45
+ communication_object.write_value_callback(42)
46
+
47
+ node.set_value.assert_called_once()
48
+ value = node.set_value.call_args.args[0]
49
+ assert isinstance(value, ua.Variant)
50
+ assert getattr(value, "Value") == 42
51
+
52
+
53
+ def test_modbus_write_value_callback_writes_to_register() -> None:
54
+ client = Mock()
55
+ communication_object = MODBUSCommunicationObject(client, "42")
56
+
57
+ communication_object.write_value_callback(7)
58
+
59
+ client.write_register.assert_called_once_with(address=42, value=7)
@@ -0,0 +1,4 @@
1
+ __copyright__ = (
2
+ "Copyright (c) 2026 Dresden University of Technology, Process-to-Order Group"
3
+ )
4
+ __license__ = "MIT"
@@ -0,0 +1,31 @@
1
+ """Implementation of IEC-61131 Data Types."""
2
+
3
+ __copyright__ = (
4
+ "Copyright (c) 2026 Dresden University of Technology, Process-to-Order Group"
5
+ )
6
+ __license__ = "MIT"
7
+
8
+ from enum import Enum
9
+
10
+
11
+ class IEC61131DataTypes(Enum):
12
+ BOOL = ("BOOL",)
13
+ BYTE = ("BYTE",)
14
+ WORD = ("WORD",)
15
+ DWORD = ("DWORD",)
16
+ LWORD = ("LWORD",)
17
+ SINT = ("SINT",)
18
+ INT = ("INT",)
19
+ DINT = ("DINT",)
20
+ LINT = ("LINT",)
21
+ USINT = ("USINT",)
22
+ UINT = ("UINT",)
23
+ UDINT = ("UDINT",)
24
+ ULINT = ("ULINT",)
25
+ REAL = ("REAL",)
26
+ LREAL = ("LREAL",)
27
+ STRING = ("STRING",)
28
+ WSTRING = ("WSTRING",)
29
+ DATE = ("DATE",)
30
+ TIME_OF_DAY = ("TIME_OF_DAY",)
31
+ DATE_AND_TIME = "DATE_AND_TIME"