MTPPy2.0 0.1.5__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mtppy2_0-0.1.5/src/MTPPy2.0.egg-info → mtppy2_0-0.2.0}/PKG-INFO +7 -5
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/README.md +4 -4
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/pyproject.toml +14 -3
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0/src/MTPPy2.0.egg-info}/PKG-INFO +7 -5
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/MTPPy2.0.egg-info/SOURCES.txt +25 -4
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/MTPPy2.0.egg-info/entry_points.txt +2 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/MTPPy2.0.egg-info/requires.txt +2 -0
- mtppy2_0-0.2.0/src/examples/modbus/m15_logic.py +108 -0
- mtppy2_0-0.2.0/src/examples/modbus/m15_pea.py +225 -0
- mtppy2_0-0.2.0/src/examples/modbus/m15_pea_test.py +117 -0
- mtppy2_0-0.2.0/src/examples/modbus/m15_simulator.py +42 -0
- mtppy2_0-0.2.0/src/examples/rmtp/__init__.py +0 -0
- mtppy2_0-0.2.0/src/examples/rmtp/minimal+pid.py +81 -0
- {mtppy2_0-0.1.5/src/examples → mtppy2_0-0.2.0/src/examples/rmtp}/minimal.py +1 -1
- mtppy2_0-0.2.0/src/examples/scratch/__init__.py +0 -0
- {mtppy2_0-0.1.5/src/examples → mtppy2_0-0.2.0/src/examples/scratch}/pea_minimal.py +50 -56
- mtppy2_0-0.2.0/src/mtppy/feas/__init__.py +6 -0
- mtppy2_0-0.2.0/src/mtppy/feas/modbus/__init__.py +37 -0
- mtppy2_0-0.2.0/src/mtppy/feas/modbus/config_loader.py +161 -0
- mtppy2_0-0.2.0/src/mtppy/feas/modbus/config_loader_test.py +160 -0
- mtppy2_0-0.2.0/src/mtppy/feas/modbus/io_action.py +243 -0
- mtppy2_0-0.2.0/src/mtppy/feas/modbus/io_action_test.py +296 -0
- mtppy2_0-0.2.0/src/mtppy/feas/modbus/io_logic.py +164 -0
- mtppy2_0-0.2.0/src/mtppy/feas/modbus/io_logic_test.py +383 -0
- mtppy2_0-0.2.0/src/mtppy/feas/modbus/io_procedure.py +49 -0
- mtppy2_0-0.2.0/src/mtppy/feas/modbus/io_procedure_test.py +46 -0
- mtppy2_0-0.2.0/src/mtppy/feas/modbus/io_service.py +115 -0
- mtppy2_0-0.2.0/src/mtppy/feas/modbus/io_service_test.py +62 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/active_elements/drives/mon_ana_drv.py +212 -89
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/active_elements/drives/mon_ana_drv_test.py +0 -28
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/active_elements/drives/mon_bin_drv.py +172 -64
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/active_elements/drives/mon_bin_drv_test.py +37 -45
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/active_elements/pid/pid_ctrl.py +4 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/active_elements/valves/mon_ana_vlv.py +177 -77
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/active_elements/valves/mon_ana_vlv_test.py +60 -55
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/active_elements/valves/mon_bin_vlv.py +158 -64
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/active_elements/valves/mon_bin_vlv_test.py +49 -57
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/base_functions/operation_mode.py +3 -2
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/base_functions/operation_mode_test.py +4 -4
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/helpers/state_machine.py +24 -9
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/helpers/state_machine_test.py +94 -0
- mtppy2_0-0.2.0/src/mtppy/part4/automation_services/helpers/thread_control.py +184 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/service.py +176 -137
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/service_elements/service_control.py +10 -8
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/service_elements/service_control_test.py +8 -4
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/service_test.py +44 -73
- mtppy2_0-0.2.0/src/mtppy/part5/communication_object.py +199 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/pea/data_assembly_factory.py +27 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/pea/mtp_generator/mtp_generator_test.py +21 -20
- mtppy2_0-0.2.0/src/mtppy/pea/pea.py +247 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/pea/pea_opcua_server/marshalling.py +12 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/pea/rmtp_pea_test.py +2 -2
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/pea/user_logic/user_logic_registry.py +1 -1
- mtppy2_0-0.2.0/src/mtppy/pea/user_logic/user_logic_service.py +326 -0
- mtppy2_0-0.2.0/src/mtppy/pea/user_logic/user_logic_service_scenario_test.py +360 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/pea/user_logic/user_logic_service_test.py +47 -26
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/utils/data_item.py +43 -5
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/utils/mtp_file_handling/mtp_reader/mtp_reader.py +3 -2
- mtppy2_0-0.2.0/src/tools/__init__.py +0 -0
- mtppy2_0-0.2.0/src/tools/inspect_mtp.py +172 -0
- mtppy2_0-0.2.0/src/tools/minimal_recipe.py +289 -0
- mtppy2_0-0.2.0/src/tools/scan_pea.py +224 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/utils/logging.py +1 -1
- mtppy2_0-0.2.0/tests/test_examples.py +325 -0
- mtppy2_0-0.1.5/src/examples/minimal+pid.py +0 -82
- mtppy2_0-0.1.5/src/examples/minimal_recipe.py +0 -117
- mtppy2_0-0.1.5/src/mtppy/part4/automation_services/helpers/thread_control.py +0 -39
- mtppy2_0-0.1.5/src/mtppy/part5/communication_object.py +0 -99
- mtppy2_0-0.1.5/src/mtppy/pea/pea.py +0 -139
- mtppy2_0-0.1.5/src/mtppy/pea/user_logic/user_logic_service.py +0 -228
- mtppy2_0-0.1.5/src/tools/inspect_mtp.py +0 -110
- mtppy2_0-0.1.5/tests/test_examples.py +0 -161
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/LICENSE +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/setup.cfg +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/MTPPy2.0.egg-info/dependency_links.txt +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/MTPPy2.0.egg-info/top_level.txt +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/examples/__init__.py +0 -0
- {mtppy2_0-0.1.5/src/tools → mtppy2_0-0.2.0/src/examples/modbus}/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/examples/pea_alarm_base.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part1/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part1/empty_folder_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/active_elements/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/active_elements/active_element.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/active_elements/drives/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/active_elements/drives/ana_drv.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/active_elements/drives/ana_drv_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/active_elements/drives/bin_drv.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/active_elements/drives/bin_drv_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/active_elements/pid/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/active_elements/pid/pid_ctrl_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/active_elements/valves/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/active_elements/valves/ana_vlv.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/active_elements/valves/ana_vlv_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/active_elements/valves/bin_vlv.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/active_elements/valves/bin_vlv_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/base_functions/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/base_functions/oslevel.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/base_functions/source_mode.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/base_functions/source_mode_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/base_functions/wqc.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/base_functions/wqc_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/data_assembly.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/diagnostic_elements/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/diagnostic_elements/diagnostic_element.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/indicator_elements/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/indicator_elements/indicator_element.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/indicator_elements/views/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/indicator_elements/views/ana_view.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/indicator_elements/views/bin_view.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/indicator_elements/views/dint_view.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/indicator_elements/views/string_view.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/operation_elements/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/operation_elements/operation_element.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/pea_elements/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/pea_elements/pea_element.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/pea_elements/pea_information_label/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/pea_elements/pea_information_label/pea_information_label.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/pea_elements/web_server_url_info/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/data_assembly_set/pea_elements/web_server_url_info/web_server_url_info.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/definitions/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part3/definitions/mtp_access.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/base_functions/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/base_functions/service_operation_mode.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/base_functions/service_operation_mode_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/base_functions/service_operator_interaction.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/base_functions/service_source_mode.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/base_functions/service_source_mode_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/helpers/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/helpers/command_en_control.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/helpers/command_en_control_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/helpers/thread_control_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/procedure.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/procedure_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/service_elements/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/service_elements/parameter_elements/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/service_elements/parameter_elements/ana_serv_param.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/service_elements/parameter_elements/ana_serv_param_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/service_elements/parameter_elements/bin_serv_param.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/service_elements/parameter_elements/bin_serv_param_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/service_elements/parameter_elements/common_serv_param.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/service_elements/parameter_elements/dint_serv_param.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/service_elements/parameter_elements/dint_serv_param_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/service_elements/parameter_elements/parameter_element.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/service_elements/parameter_elements/parameter_element_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/service_elements/parameter_elements/string_serv_param.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/service_elements/parameter_elements/string_serv_param_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/service_elements/procedure_health_view.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/automation_services/service_elements/service_element.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/definitions/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/definitions/command_codes.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/definitions/command_codes_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/definitions/state_codes.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/definitions/state_codes_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/process_values/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/process_values/base_functions/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/process_values/base_functions/vqc.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/process_values/input_elements/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/process_values/input_elements/ana_process_value_in.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/process_values/input_elements/bin_process_value_in.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/process_values/input_elements/dint_process_value_in.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/process_values/input_elements/input_element.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part4/process_values/input_elements/string_process_value_in.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part5/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part5/communication_object_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part5/definitions/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part5/definitions/iec61131_data_types.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part5/definitions/iec61131_data_types_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part5/definitions/opcua_data_types.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part5/definitions/opcua_data_types_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part5/definitions/w3c_xml_data_types.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part5/definitions/w3c_xml_data_types_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part5/server_assembly_set/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part6/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part6/alarm_set/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part6/alarm_set/alarm.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/part6/alarm_set/alarm_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/pea/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/pea/data_assembly_factory_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/pea/mtp_generator/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/pea/mtp_generator/mtp_generator.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/pea/pea_opcua_server/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/pea/pea_opcua_server/opcua_options_provider/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/pea/pea_opcua_server/opcua_options_provider/instances/basic_opcua_options_provider.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/pea/pea_opcua_server/opcua_options_provider/opcua_options_provider.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/pea/pea_opcua_server/pea_opcua_server.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/pea/pea_opcua_server/subscription_list.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/pea/pea_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/pea/rmtp_pea.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/pea/service_factory.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/pea/service_factory_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/pea/user_logic/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/pea/user_logic/user_logic_pea.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/pea/user_logic/user_logic_registry_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/utils/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/utils/data_assembly_dict.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/utils/data_assembly_dict_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/utils/data_item_com_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/utils/data_item_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/utils/logging.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/utils/logging_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/utils/mtp_file_handling/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/utils/mtp_file_handling/extract_manifest_from_mtp_file.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/utils/mtp_file_handling/extract_mtp_file.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/utils/mtp_file_handling/is_valid_mtp.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/utils/mtp_file_handling/is_valid_path_for_manifest.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/utils/mtp_file_handling/is_valid_path_to_manifest.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/utils/mtp_file_handling/is_valid_path_to_mtp.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/utils/mtp_file_handling/load_manifest_file.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/utils/mtp_file_handling/mtp_reader/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/utils/mtp_file_handling/mtp_reader/mtp_reader_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/utils/mtp_file_handling/mtp_reader/mtp_xml.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/utils/mtp_file_handling/mtp_reader/mtp_xml_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/utils/mtp_file_handling/mtp_writer/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/utils/mtp_file_handling/mtp_writer/mtp_writer.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/utils/mtp_file_handling/mtp_writer/ressources/get_content_types.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/utils/mtp_file_handling/mtp_writer/ressources/get_rels.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/utils/mtp_file_handling/mtp_writer/test_mtp_writer.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/utils/mtp_file_handling/write_manifest_file.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/utils/mtp_file_handling/write_manifest_file_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/utils/mtp_file_handling/write_mtp_file.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/utils/mtp_file_handling/write_mtp_file_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/mtppy/utils/testing.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/tools/create_bugreport.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/utils/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/utils/file_handling/__init__.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/utils/file_handling/cleanup_folder.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/utils/file_handling/get_utc_foldername_with_ms.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/utils/file_handling/get_work_dir.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/utils/file_handling/is_valid_path_for_json.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/utils/file_handling/is_valid_path_to_json.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/utils/file_handling/load_json_file.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/utils/file_handling/read_file_from_file_archive.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/utils/file_handling/read_file_string.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/utils/file_handling/validate_json_data.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/utils/file_handling/write_json_file.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/utils/get_uuid.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/utils/get_uuid_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/utils/logging_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/utils/opcua/check_node.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/utils/resolve_unit/resolve_unit.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/utils/resolve_unit/unit_lib.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/utils/resolve_unit/unit_lib_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/utils/type_conversion.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/src/utils/type_conversion_test.py +0 -0
- {mtppy2_0-0.1.5 → mtppy2_0-0.2.0}/tests/test_data_item_handshake.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: MTPPy2.0
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Open-source modular automation with MTP 2.0
|
|
5
5
|
Author: Dresden University of Technology, Process-to-Order Group
|
|
6
6
|
Author-email: Julius Lorenz <julius.lorenz@tu-dresden.de>, Leon Urbas <leon.urbas@tu-dresden.de>
|
|
@@ -21,6 +21,8 @@ License-File: LICENSE
|
|
|
21
21
|
Requires-Dist: opcua~=0.98.13
|
|
22
22
|
Requires-Dist: jsonschema>=4.26.0
|
|
23
23
|
Requires-Dist: chardet>=7.6.0
|
|
24
|
+
Requires-Dist: aiohttp>=3.12.0
|
|
25
|
+
Requires-Dist: pymodbus>=3.15.0
|
|
24
26
|
Requires-Dist: simple-pid>=2.0.1
|
|
25
27
|
Requires-Dist: pymodbus>=3.15.0
|
|
26
28
|
Dynamic: license-file
|
|
@@ -56,19 +58,19 @@ uv add MTPPy2.0
|
|
|
56
58
|
|
|
57
59
|
### Developers
|
|
58
60
|
- Check out ``main`` from the [gitlab repository](https://gitlab.hrz.tu-chemnitz.de/process-to-order-group/mtppy2.0)
|
|
59
|
-
- Run `uv sync --all-groups` to
|
|
61
|
+
- Run `uv sync --all-groups` to set up the virtual environment `mtppy2-0` and install
|
|
60
62
|
all the required packages for running and development
|
|
61
63
|
- You might want to inspect the examples in ``./examples`` and perhaps the jupyter-notebook snippets in
|
|
62
64
|
``./snippets``
|
|
63
65
|
|
|
64
66
|
### Contributors
|
|
65
|
-
- Check out ``
|
|
66
|
-
- Run `uv sync --all-groups` to
|
|
67
|
+
- Check out ``develop`` from the [gitlab repository](https://gitlab.hrz.tu-chemnitz.de/process-to-order-group/mtppy2.0)
|
|
68
|
+
- Run `uv sync --all-groups` to set up the virtual environment `mtppy2-0` and install
|
|
67
69
|
all the required packages for running and development
|
|
68
70
|
- Study the [developer handbook](https://aas-demo.p2o-lab.ifa.et.tu-dresden.de/mtppy2.0/developer/developer/)
|
|
69
71
|
- Feel invited to contribute by
|
|
70
72
|
- joining the development on a certain [branch](https://gitlab.hrz.tu-chemnitz.de/process-to-order-group/mtppy2.0/-/branches), or by
|
|
71
|
-
- selecting an [open issue](https://gitlab.hrz.tu-chemnitz.de/process-to-order-group/mtppy2.0/-/boards?milestone_title=Started&types=ISSUE)
|
|
73
|
+
- selecting an [open issue](https://gitlab.hrz.tu-chemnitz.de/process-to-order-group/mtppy2.0/-/boards?milestone_title=Started&types=ISSUE), create your branch and provide a solution
|
|
72
74
|
|
|
73
75
|
|
|
74
76
|
|
|
@@ -29,19 +29,19 @@ uv add MTPPy2.0
|
|
|
29
29
|
|
|
30
30
|
### Developers
|
|
31
31
|
- Check out ``main`` from the [gitlab repository](https://gitlab.hrz.tu-chemnitz.de/process-to-order-group/mtppy2.0)
|
|
32
|
-
- Run `uv sync --all-groups` to
|
|
32
|
+
- Run `uv sync --all-groups` to set up the virtual environment `mtppy2-0` and install
|
|
33
33
|
all the required packages for running and development
|
|
34
34
|
- You might want to inspect the examples in ``./examples`` and perhaps the jupyter-notebook snippets in
|
|
35
35
|
``./snippets``
|
|
36
36
|
|
|
37
37
|
### Contributors
|
|
38
|
-
- Check out ``
|
|
39
|
-
- Run `uv sync --all-groups` to
|
|
38
|
+
- Check out ``develop`` from the [gitlab repository](https://gitlab.hrz.tu-chemnitz.de/process-to-order-group/mtppy2.0)
|
|
39
|
+
- Run `uv sync --all-groups` to set up the virtual environment `mtppy2-0` and install
|
|
40
40
|
all the required packages for running and development
|
|
41
41
|
- Study the [developer handbook](https://aas-demo.p2o-lab.ifa.et.tu-dresden.de/mtppy2.0/developer/developer/)
|
|
42
42
|
- Feel invited to contribute by
|
|
43
43
|
- joining the development on a certain [branch](https://gitlab.hrz.tu-chemnitz.de/process-to-order-group/mtppy2.0/-/branches), or by
|
|
44
|
-
- selecting an [open issue](https://gitlab.hrz.tu-chemnitz.de/process-to-order-group/mtppy2.0/-/boards?milestone_title=Started&types=ISSUE)
|
|
44
|
+
- selecting an [open issue](https://gitlab.hrz.tu-chemnitz.de/process-to-order-group/mtppy2.0/-/boards?milestone_title=Started&types=ISSUE), create your branch and provide a solution
|
|
45
45
|
|
|
46
46
|
|
|
47
47
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "MTPPy2.0"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.2.0"
|
|
4
4
|
description = "Open-source modular automation with MTP 2.0"
|
|
5
5
|
readme="README.md"
|
|
6
6
|
license = "MIT"
|
|
7
|
-
license-files = ["LICENSE"
|
|
7
|
+
license-files = ["LICENSE"]
|
|
8
8
|
requires-python = ">=3.13"
|
|
9
9
|
authors = [
|
|
10
10
|
{ name = "Dresden University of Technology, Process-to-Order Group" },
|
|
@@ -25,6 +25,8 @@ dependencies = [
|
|
|
25
25
|
"opcua~=0.98.13",
|
|
26
26
|
"jsonschema>=4.26.0",
|
|
27
27
|
"chardet>=7.6.0",
|
|
28
|
+
"aiohttp>=3.12.0",
|
|
29
|
+
"pymodbus>=3.15.0",
|
|
28
30
|
"simple-pid>=2.0.1",
|
|
29
31
|
"pymodbus>=3.15.0",
|
|
30
32
|
]
|
|
@@ -40,9 +42,10 @@ build-backend = "setuptools.build_meta"
|
|
|
40
42
|
|
|
41
43
|
[project.scripts]
|
|
42
44
|
inspect_mtp = "tools.inspect_mtp:main"
|
|
45
|
+
minimal_recipe = "tools.minimal_recipe:main"
|
|
46
|
+
scan_pea = "tools.scan_pea:main"
|
|
43
47
|
rmtp_pea = "mtppy.pea.rmtp_pea:main"
|
|
44
48
|
|
|
45
|
-
|
|
46
49
|
[dependency-groups]
|
|
47
50
|
dev = [
|
|
48
51
|
"black>=26.5.1",
|
|
@@ -100,7 +103,12 @@ filterwarnings = [
|
|
|
100
103
|
]
|
|
101
104
|
|
|
102
105
|
[tool.ruff]
|
|
106
|
+
line-length = 88
|
|
107
|
+
target-version = "py310"
|
|
108
|
+
inline-quotes = "double"
|
|
109
|
+
|
|
103
110
|
lint.select = ["ALL"]
|
|
111
|
+
|
|
104
112
|
# ANN001 - Missing type annotation for function argument
|
|
105
113
|
# `incorrect-blank-line-before-class` (D203) and `no-blank-line-before-class` (D211) are incompatible. Ignoring `incorrect-blank-line-before-class`.
|
|
106
114
|
# `multi-line-summary-first-line` (D212) and `multi-line-summary-second-line` (D213) are incompatible. Ignoring `multi-line-summary-second-line`.
|
|
@@ -110,3 +118,6 @@ lint.select = ["ALL"]
|
|
|
110
118
|
# `Missing blank line after last section` (D413)
|
|
111
119
|
# `Too many arguments in function definition` (PLR0913)
|
|
112
120
|
lint.ignore = ["ANN002","ANN003","D203","D213","D205","D413","PLR0913"]
|
|
121
|
+
|
|
122
|
+
[tool.ruff.pydocstyle]
|
|
123
|
+
convention = "google" # Enforce Google-style docstrings
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: MTPPy2.0
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Open-source modular automation with MTP 2.0
|
|
5
5
|
Author: Dresden University of Technology, Process-to-Order Group
|
|
6
6
|
Author-email: Julius Lorenz <julius.lorenz@tu-dresden.de>, Leon Urbas <leon.urbas@tu-dresden.de>
|
|
@@ -21,6 +21,8 @@ License-File: LICENSE
|
|
|
21
21
|
Requires-Dist: opcua~=0.98.13
|
|
22
22
|
Requires-Dist: jsonschema>=4.26.0
|
|
23
23
|
Requires-Dist: chardet>=7.6.0
|
|
24
|
+
Requires-Dist: aiohttp>=3.12.0
|
|
25
|
+
Requires-Dist: pymodbus>=3.15.0
|
|
24
26
|
Requires-Dist: simple-pid>=2.0.1
|
|
25
27
|
Requires-Dist: pymodbus>=3.15.0
|
|
26
28
|
Dynamic: license-file
|
|
@@ -56,19 +58,19 @@ uv add MTPPy2.0
|
|
|
56
58
|
|
|
57
59
|
### Developers
|
|
58
60
|
- Check out ``main`` from the [gitlab repository](https://gitlab.hrz.tu-chemnitz.de/process-to-order-group/mtppy2.0)
|
|
59
|
-
- Run `uv sync --all-groups` to
|
|
61
|
+
- Run `uv sync --all-groups` to set up the virtual environment `mtppy2-0` and install
|
|
60
62
|
all the required packages for running and development
|
|
61
63
|
- You might want to inspect the examples in ``./examples`` and perhaps the jupyter-notebook snippets in
|
|
62
64
|
``./snippets``
|
|
63
65
|
|
|
64
66
|
### Contributors
|
|
65
|
-
- Check out ``
|
|
66
|
-
- Run `uv sync --all-groups` to
|
|
67
|
+
- Check out ``develop`` from the [gitlab repository](https://gitlab.hrz.tu-chemnitz.de/process-to-order-group/mtppy2.0)
|
|
68
|
+
- Run `uv sync --all-groups` to set up the virtual environment `mtppy2-0` and install
|
|
67
69
|
all the required packages for running and development
|
|
68
70
|
- Study the [developer handbook](https://aas-demo.p2o-lab.ifa.et.tu-dresden.de/mtppy2.0/developer/developer/)
|
|
69
71
|
- Feel invited to contribute by
|
|
70
72
|
- joining the development on a certain [branch](https://gitlab.hrz.tu-chemnitz.de/process-to-order-group/mtppy2.0/-/branches), or by
|
|
71
|
-
- selecting an [open issue](https://gitlab.hrz.tu-chemnitz.de/process-to-order-group/mtppy2.0/-/boards?milestone_title=Started&types=ISSUE)
|
|
73
|
+
- selecting an [open issue](https://gitlab.hrz.tu-chemnitz.de/process-to-order-group/mtppy2.0/-/boards?milestone_title=Started&types=ISSUE), create your branch and provide a solution
|
|
72
74
|
|
|
73
75
|
|
|
74
76
|
|
|
@@ -8,12 +8,30 @@ src/MTPPy2.0.egg-info/entry_points.txt
|
|
|
8
8
|
src/MTPPy2.0.egg-info/requires.txt
|
|
9
9
|
src/MTPPy2.0.egg-info/top_level.txt
|
|
10
10
|
src/examples/__init__.py
|
|
11
|
-
src/examples/minimal+pid.py
|
|
12
|
-
src/examples/minimal.py
|
|
13
|
-
src/examples/minimal_recipe.py
|
|
14
11
|
src/examples/pea_alarm_base.py
|
|
15
|
-
src/examples/
|
|
12
|
+
src/examples/modbus/__init__.py
|
|
13
|
+
src/examples/modbus/m15_logic.py
|
|
14
|
+
src/examples/modbus/m15_pea.py
|
|
15
|
+
src/examples/modbus/m15_pea_test.py
|
|
16
|
+
src/examples/modbus/m15_simulator.py
|
|
17
|
+
src/examples/rmtp/__init__.py
|
|
18
|
+
src/examples/rmtp/minimal+pid.py
|
|
19
|
+
src/examples/rmtp/minimal.py
|
|
20
|
+
src/examples/scratch/__init__.py
|
|
21
|
+
src/examples/scratch/pea_minimal.py
|
|
16
22
|
src/mtppy/__init__.py
|
|
23
|
+
src/mtppy/feas/__init__.py
|
|
24
|
+
src/mtppy/feas/modbus/__init__.py
|
|
25
|
+
src/mtppy/feas/modbus/config_loader.py
|
|
26
|
+
src/mtppy/feas/modbus/config_loader_test.py
|
|
27
|
+
src/mtppy/feas/modbus/io_action.py
|
|
28
|
+
src/mtppy/feas/modbus/io_action_test.py
|
|
29
|
+
src/mtppy/feas/modbus/io_logic.py
|
|
30
|
+
src/mtppy/feas/modbus/io_logic_test.py
|
|
31
|
+
src/mtppy/feas/modbus/io_procedure.py
|
|
32
|
+
src/mtppy/feas/modbus/io_procedure_test.py
|
|
33
|
+
src/mtppy/feas/modbus/io_service.py
|
|
34
|
+
src/mtppy/feas/modbus/io_service_test.py
|
|
17
35
|
src/mtppy/part1/__init__.py
|
|
18
36
|
src/mtppy/part1/empty_folder_test.py
|
|
19
37
|
src/mtppy/part3/__init__.py
|
|
@@ -158,6 +176,7 @@ src/mtppy/pea/user_logic/user_logic_pea.py
|
|
|
158
176
|
src/mtppy/pea/user_logic/user_logic_registry.py
|
|
159
177
|
src/mtppy/pea/user_logic/user_logic_registry_test.py
|
|
160
178
|
src/mtppy/pea/user_logic/user_logic_service.py
|
|
179
|
+
src/mtppy/pea/user_logic/user_logic_service_scenario_test.py
|
|
161
180
|
src/mtppy/pea/user_logic/user_logic_service_test.py
|
|
162
181
|
src/mtppy/utils/__init__.py
|
|
163
182
|
src/mtppy/utils/data_assembly_dict.py
|
|
@@ -193,6 +212,8 @@ src/mtppy/utils/mtp_file_handling/mtp_writer/ressources/get_rels.py
|
|
|
193
212
|
src/tools/__init__.py
|
|
194
213
|
src/tools/create_bugreport.py
|
|
195
214
|
src/tools/inspect_mtp.py
|
|
215
|
+
src/tools/minimal_recipe.py
|
|
216
|
+
src/tools/scan_pea.py
|
|
196
217
|
src/utils/__init__.py
|
|
197
218
|
src/utils/get_uuid.py
|
|
198
219
|
src/utils/get_uuid_test.py
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"""Application logic for the M15 PEM electrolysis module service ``produce``."""
|
|
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.active_elements.pid.pid_ctrl import PIDCtrl
|
|
9
|
+
from mtppy.utils.logging import logger
|
|
10
|
+
from mtppy.part4.automation_services.service import Service
|
|
11
|
+
from mtppy.pea.user_logic.user_logic_registry import register
|
|
12
|
+
|
|
13
|
+
__requirements_mtp__ = "M15.mtp"
|
|
14
|
+
|
|
15
|
+
DA_PRESSURE_UNITS = "p_eng_units"
|
|
16
|
+
DA_TEMP_UNITS = "t_eng_units"
|
|
17
|
+
DA_VOLUME_UNITS = "v_eng_units"
|
|
18
|
+
DA_START_STOP = "start_stop"
|
|
19
|
+
DA_VALVE = "V010"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
"""
|
|
23
|
+
Spezifikation für produce.auto.starting.entry:
|
|
24
|
+
Setze die Anzeigeeinheiten des Generators (Druck, Temperatur,
|
|
25
|
+
Volumen) auf den Standardwert 0.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@register("produce.auto.starting.entry")
|
|
30
|
+
def reset_units(context: Service) -> bool:
|
|
31
|
+
context.get_param(DA_PRESSURE_UNITS).V = 0
|
|
32
|
+
context.get_param(DA_TEMP_UNITS).V = 0
|
|
33
|
+
context.get_param(DA_VOLUME_UNITS).V = 0
|
|
34
|
+
|
|
35
|
+
pctl: PIDCtrl = context.get_param("PIC009")
|
|
36
|
+
|
|
37
|
+
pctl.op_mode.set_state_channel(True)
|
|
38
|
+
pctl.op_mode.set_state_aut_aut(True)
|
|
39
|
+
pctl.src_mode.set_src_channel(True)
|
|
40
|
+
pctl.src_mode.set_src_man_aut(True)
|
|
41
|
+
pctl.SPManMin = pctl.SPSclMin = 0
|
|
42
|
+
pctl.SPManMax = pctl.SPSclMax = 100
|
|
43
|
+
|
|
44
|
+
return True
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
"""
|
|
48
|
+
Spezifikation für produce.auto.starting.do:
|
|
49
|
+
Starte den Generator und öffne das Auslassventil.
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@register("produce.auto.starting.do")
|
|
54
|
+
def start_generator(context: Service) -> bool:
|
|
55
|
+
start_stop = context.get_param(DA_START_STOP)
|
|
56
|
+
valve = context.get_param(DA_VALVE)
|
|
57
|
+
p_out_sp = context.get_param("p_out_sp")
|
|
58
|
+
pctl: PIDCtrl = context.get_param("PIC009")
|
|
59
|
+
|
|
60
|
+
start_stop.V = 0
|
|
61
|
+
valve.OpenAut = 1
|
|
62
|
+
pctl.SPMan = p_out_sp.VOut
|
|
63
|
+
|
|
64
|
+
return True
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
"""
|
|
68
|
+
Spezifikation für produce.auto.holding.do:
|
|
69
|
+
Schließe das Auslassventil.
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@register("produce.auto.holding.do")
|
|
74
|
+
def hold_generator(context: Service) -> bool:
|
|
75
|
+
context.get_param(DA_VALVE).CloseAut = 1
|
|
76
|
+
return True
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
"""
|
|
80
|
+
Spezifikation für produce.auto.unholding.do:
|
|
81
|
+
Öffne das Auslassventil.
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
@register("produce.auto.unholding.do")
|
|
86
|
+
def unhold_generator(context: Service) -> bool:
|
|
87
|
+
context.get_param(DA_VALVE).OpenAut = 1
|
|
88
|
+
return True
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
"""
|
|
92
|
+
Spezifikation für produce.auto.completing.do sowie stopping und aborting:
|
|
93
|
+
Stoppe den Generator (DA_START_STOP.V = 1) und schließe das
|
|
94
|
+
Auslassventil (DA_VALVE.V = 0).
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
@register(
|
|
99
|
+
"produce.auto.completing.do", "produce.auto.stopping.do", "produce.auto.aborting.do"
|
|
100
|
+
)
|
|
101
|
+
def stop_generator(context: Service) -> bool:
|
|
102
|
+
start_stop = context.get_param(DA_START_STOP)
|
|
103
|
+
valve = context.get_param(DA_VALVE)
|
|
104
|
+
|
|
105
|
+
start_stop.V = 1
|
|
106
|
+
valve.CloseAut = 1
|
|
107
|
+
|
|
108
|
+
return True
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
"""Access the M15 Modbus server through an MTPPy PEA background service."""
|
|
2
|
+
|
|
3
|
+
__copyright__ = (
|
|
4
|
+
"Copyright (c) 2026 Dresden University of Technology, Process-to-Order Group"
|
|
5
|
+
)
|
|
6
|
+
__license__ = "MIT"
|
|
7
|
+
import argparse
|
|
8
|
+
import asyncio
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
from pymodbus.client import ModbusTcpClient
|
|
12
|
+
|
|
13
|
+
from mtppy.feas.modbus import (
|
|
14
|
+
IOLogic,
|
|
15
|
+
IOProcedure,
|
|
16
|
+
IOService,
|
|
17
|
+
load_register_mappings,
|
|
18
|
+
)
|
|
19
|
+
from mtppy.part3.data_assembly_set.data_assembly import DataAssembly
|
|
20
|
+
from mtppy.pea.user_logic.user_logic_pea import UserLogicPEA
|
|
21
|
+
from mtppy.utils.logging import CHOICES, logger, setLogLevel
|
|
22
|
+
|
|
23
|
+
DEFAULT_HOST = "localhost"
|
|
24
|
+
DEFAULT_MODBUS_PORT = 5020
|
|
25
|
+
DEFAULT_OPCUA_ENDPOINT = "opc.tcp://localhost:4044"
|
|
26
|
+
DEFAULT_CYCLE_TIME = 0.5
|
|
27
|
+
CONFIG_PATH = Path(__file__).with_name("m15_modbus.json")
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class M15Pea(UserLogicPEA):
|
|
31
|
+
"""PEA that exposes M15 registers as internal DataAssemblies."""
|
|
32
|
+
|
|
33
|
+
def __init__(
|
|
34
|
+
self,
|
|
35
|
+
endpoint: str = DEFAULT_OPCUA_ENDPOINT,
|
|
36
|
+
host: str = DEFAULT_HOST,
|
|
37
|
+
modbus_port: int = DEFAULT_MODBUS_PORT,
|
|
38
|
+
config_path: str | Path = CONFIG_PATH,
|
|
39
|
+
cycle_time: float = DEFAULT_CYCLE_TIME,
|
|
40
|
+
mtp: str = "",
|
|
41
|
+
ssd: str = "",
|
|
42
|
+
code: str = "",
|
|
43
|
+
) -> None:
|
|
44
|
+
super().__init__(endpoint=endpoint, mtp=mtp, ssd=ssd, code=code)
|
|
45
|
+
self.modbus_client = ModbusTcpClient(host, port=modbus_port)
|
|
46
|
+
|
|
47
|
+
internal_data_assemblies, mappings, assignments = load_register_mappings(
|
|
48
|
+
config_path, dict(self.data_assemblies)
|
|
49
|
+
)
|
|
50
|
+
if mtp:
|
|
51
|
+
matching_data_assemblies = self._matching_requirement_data_assemblies(
|
|
52
|
+
internal_data_assemblies
|
|
53
|
+
)
|
|
54
|
+
for mapping in mappings:
|
|
55
|
+
matching_data_assembly = matching_data_assemblies.get(
|
|
56
|
+
mapping.data_assembly.tag_name
|
|
57
|
+
)
|
|
58
|
+
if matching_data_assembly is not None:
|
|
59
|
+
mapping.data_assembly = matching_data_assembly
|
|
60
|
+
else:
|
|
61
|
+
self.add_data_assembly(internal_data_assemblies)
|
|
62
|
+
|
|
63
|
+
self.io_logic = IOLogic(self.modbus_client, mappings)
|
|
64
|
+
self.io_procedure = IOProcedure(
|
|
65
|
+
self.io_logic,
|
|
66
|
+
required_equipment=list(internal_data_assemblies.values()),
|
|
67
|
+
)
|
|
68
|
+
self.io_service = IOService(self.io_procedure, cycle_time=cycle_time)
|
|
69
|
+
self.add_service(self.io_service)
|
|
70
|
+
|
|
71
|
+
self._assign_data_assemblies(assignments, internal_data_assemblies)
|
|
72
|
+
|
|
73
|
+
def _matching_requirement_data_assemblies(
|
|
74
|
+
self, modbus_data_assemblies: dict[str, DataAssembly]
|
|
75
|
+
) -> dict[str, DataAssembly]:
|
|
76
|
+
"""Validate and return rMTP assemblies matching Modbus configuration.
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
modbus_data_assemblies: Assemblies declared by the Modbus
|
|
80
|
+
``internal_equipment`` configuration.
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
rMTP-loaded assemblies keyed by the configured Modbus tag name.
|
|
84
|
+
Tags missing from the requirements MTP or with a mismatching
|
|
85
|
+
DataAssembly class are skipped (and logged) rather than raised.
|
|
86
|
+
"""
|
|
87
|
+
matching_data_assemblies: dict[str, DataAssembly] = {}
|
|
88
|
+
for tag_name, modbus_data_assembly in modbus_data_assemblies.items():
|
|
89
|
+
requirement_data_assembly = self.data_assemblies.get(tag_name)
|
|
90
|
+
if requirement_data_assembly is None:
|
|
91
|
+
logger.warning(
|
|
92
|
+
f"Modbus DataAssembly {tag_name!r} is missing from requirements MTP"
|
|
93
|
+
)
|
|
94
|
+
continue
|
|
95
|
+
if type(requirement_data_assembly) is not type(modbus_data_assembly):
|
|
96
|
+
logger.warning(
|
|
97
|
+
f"Modbus DataAssembly {tag_name!r} has class "
|
|
98
|
+
f"{type(modbus_data_assembly).__name__}, but requirements MTP "
|
|
99
|
+
f"defines {type(requirement_data_assembly).__name__}"
|
|
100
|
+
)
|
|
101
|
+
continue
|
|
102
|
+
matching_data_assemblies[tag_name] = requirement_data_assembly
|
|
103
|
+
return matching_data_assemblies
|
|
104
|
+
|
|
105
|
+
def _assign_data_assemblies(
|
|
106
|
+
self,
|
|
107
|
+
assignments: dict[str, list[str]],
|
|
108
|
+
data_assemblies: dict[str, DataAssembly],
|
|
109
|
+
) -> None:
|
|
110
|
+
"""Add DataAssemblies as required equipment to named procedures.
|
|
111
|
+
|
|
112
|
+
Args:
|
|
113
|
+
assignments: Mapping of procedure name to list of tag names.
|
|
114
|
+
data_assemblies: Pool of DataAssembly instances to look up by tag name.
|
|
115
|
+
"""
|
|
116
|
+
for procedure_name, tag_names in assignments.items():
|
|
117
|
+
procedure = self._find_procedure(procedure_name)
|
|
118
|
+
if procedure is None:
|
|
119
|
+
logger.critical(
|
|
120
|
+
f"procedure {procedure_name!r} not found for assignment"
|
|
121
|
+
)
|
|
122
|
+
continue
|
|
123
|
+
for tag_name in tag_names:
|
|
124
|
+
if tag_name not in data_assemblies:
|
|
125
|
+
logger.critical(
|
|
126
|
+
f"DataAssembly {tag_name!r} not found for assignment "
|
|
127
|
+
f"to procedure {procedure_name!r}"
|
|
128
|
+
)
|
|
129
|
+
continue
|
|
130
|
+
procedure.add_required_equipment(data_assemblies[tag_name])
|
|
131
|
+
|
|
132
|
+
def _find_procedure(self, name: str):
|
|
133
|
+
"""Find a procedure by name among all registered services.
|
|
134
|
+
|
|
135
|
+
Args:
|
|
136
|
+
name: Procedure name to search for.
|
|
137
|
+
|
|
138
|
+
Returns:
|
|
139
|
+
The matching procedure, or None if not found.
|
|
140
|
+
"""
|
|
141
|
+
for service in self.service_set.values():
|
|
142
|
+
for procedure in service.procedures.values():
|
|
143
|
+
if procedure.name == name:
|
|
144
|
+
return procedure
|
|
145
|
+
return None
|
|
146
|
+
|
|
147
|
+
def start(self) -> None:
|
|
148
|
+
"""Start the OPC UA server and the cyclic Modbus I/O service."""
|
|
149
|
+
if not self.modbus_client.connect():
|
|
150
|
+
raise ConnectionError("unable to connect to the M15 Modbus server")
|
|
151
|
+
super().start()
|
|
152
|
+
self.io_service.activate_and_run()
|
|
153
|
+
|
|
154
|
+
def stop(self) -> None:
|
|
155
|
+
"""Stop the cyclic I/O service, OPC UA server, and Modbus client."""
|
|
156
|
+
self.io_service.stop()
|
|
157
|
+
super().stop()
|
|
158
|
+
self.modbus_client.close()
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def parse_args(args: list[str] | None = None) -> argparse.Namespace:
|
|
162
|
+
"""Parse command-line options for the M15 PEA."""
|
|
163
|
+
parser = argparse.ArgumentParser(description=__doc__)
|
|
164
|
+
parser.add_argument("--host", default=DEFAULT_HOST)
|
|
165
|
+
parser.add_argument("-p", "--modbus-port", type=int, default=DEFAULT_MODBUS_PORT)
|
|
166
|
+
parser.add_argument("--endpoint", default=DEFAULT_OPCUA_ENDPOINT)
|
|
167
|
+
parser.add_argument(
|
|
168
|
+
"-r",
|
|
169
|
+
"--rmtp",
|
|
170
|
+
default="",
|
|
171
|
+
help="basename of the requirements MTP files (without .mtp or .json)",
|
|
172
|
+
)
|
|
173
|
+
parser.add_argument(
|
|
174
|
+
"-u",
|
|
175
|
+
"--user-logic",
|
|
176
|
+
dest="user_logic",
|
|
177
|
+
default="",
|
|
178
|
+
help="Python module containing the user logic",
|
|
179
|
+
)
|
|
180
|
+
parser.add_argument(
|
|
181
|
+
"-m",
|
|
182
|
+
"--modbus-config",
|
|
183
|
+
type=Path,
|
|
184
|
+
default=CONFIG_PATH,
|
|
185
|
+
help="path to the Modbus register-mapping JSON configuration file",
|
|
186
|
+
)
|
|
187
|
+
parser.add_argument("-t", "--duration", type=float, default=10.0)
|
|
188
|
+
parser.add_argument("-c", "--cycle-time", type=float, default=DEFAULT_CYCLE_TIME)
|
|
189
|
+
parser.add_argument("-d", "--daemon", action="store_true")
|
|
190
|
+
parser.add_argument(
|
|
191
|
+
"-l",
|
|
192
|
+
"--log-level",
|
|
193
|
+
default="MTP",
|
|
194
|
+
choices=["DEBUG", "INFO", *CHOICES, "WARNING", "ERROR", "CRITICAL"],
|
|
195
|
+
help="logging level (default: MTP)",
|
|
196
|
+
)
|
|
197
|
+
return parser.parse_args(args)
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
async def main(args: list[str] | None = None) -> None:
|
|
201
|
+
"""Start the M15 PEA and keep it alive for the requested duration."""
|
|
202
|
+
parsed_args = parse_args(args)
|
|
203
|
+
setLogLevel(parsed_args.log_level)
|
|
204
|
+
pea = M15Pea(
|
|
205
|
+
endpoint=parsed_args.endpoint,
|
|
206
|
+
host=parsed_args.host,
|
|
207
|
+
modbus_port=parsed_args.modbus_port,
|
|
208
|
+
config_path=parsed_args.modbus_config,
|
|
209
|
+
cycle_time=parsed_args.cycle_time,
|
|
210
|
+
mtp=f"{parsed_args.rmtp}.mtp" if parsed_args.rmtp else "",
|
|
211
|
+
ssd=f"{parsed_args.rmtp}.json" if parsed_args.rmtp else "",
|
|
212
|
+
code=parsed_args.user_logic,
|
|
213
|
+
)
|
|
214
|
+
try:
|
|
215
|
+
pea.start()
|
|
216
|
+
if parsed_args.daemon:
|
|
217
|
+
await asyncio.Event().wait()
|
|
218
|
+
else:
|
|
219
|
+
await asyncio.sleep(parsed_args.duration)
|
|
220
|
+
finally:
|
|
221
|
+
pea.stop()
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
if __name__ == "__main__":
|
|
225
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"""Tests for M15 PEA."""
|
|
2
|
+
|
|
3
|
+
__copyright__ = (
|
|
4
|
+
"Copyright (c) 2026 Dresden University of Technology, Process-to-Order Group"
|
|
5
|
+
)
|
|
6
|
+
__license__ = "MIT"
|
|
7
|
+
|
|
8
|
+
import json
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from unittest.mock import patch, MagicMock
|
|
11
|
+
|
|
12
|
+
from examples.modbus.m15_pea import M15Pea
|
|
13
|
+
from mtppy.part3.data_assembly_set.indicator_elements.views.dint_view import DIntView
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def test_loads_internal_data_assemblies_from_config(tmp_path):
|
|
17
|
+
config = {
|
|
18
|
+
"internal_equipment": {
|
|
19
|
+
"start_stop": {
|
|
20
|
+
"class": "mtppy.part3.data_assembly_set.indicator_elements.views.dint_view.DIntView",
|
|
21
|
+
"V": {"register": 401, "access": "write"},
|
|
22
|
+
},
|
|
23
|
+
"p_out": {
|
|
24
|
+
"class": "mtppy.part3.data_assembly_set.indicator_elements.views.dint_view.DIntView",
|
|
25
|
+
"V": {"register": 400, "access": "write"},
|
|
26
|
+
},
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
config_path = tmp_path / "config.json"
|
|
30
|
+
config_path.write_text(json.dumps(config))
|
|
31
|
+
|
|
32
|
+
with patch("pymodbus.client.ModbusTcpClient") as mock_client_cls:
|
|
33
|
+
mock_client_cls.return_value.connect.return_value = True
|
|
34
|
+
pea = M15Pea(config_path=config_path)
|
|
35
|
+
|
|
36
|
+
assert "start_stop" in pea.data_assemblies
|
|
37
|
+
assert "p_out" in pea.data_assemblies
|
|
38
|
+
assert isinstance(pea.data_assemblies["start_stop"], DIntView)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def test_write_access_configures_communication_object(tmp_path):
|
|
42
|
+
config = {
|
|
43
|
+
"internal_equipment": {
|
|
44
|
+
"start_stop": {
|
|
45
|
+
"class": "mtppy.part3.data_assembly_set.indicator_elements.views.dint_view.DIntView",
|
|
46
|
+
"V": {"register": 401, "access": "write"},
|
|
47
|
+
},
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
config_path = tmp_path / "config.json"
|
|
51
|
+
config_path.write_text(json.dumps(config))
|
|
52
|
+
|
|
53
|
+
with patch("pymodbus.client.ModbusTcpClient") as mock_client_cls:
|
|
54
|
+
mock_client_cls.return_value.connect.return_value = True
|
|
55
|
+
pea = M15Pea(config_path=config_path)
|
|
56
|
+
|
|
57
|
+
mapping = pea.io_logic.mappings[0]
|
|
58
|
+
assert mapping.access == "write"
|
|
59
|
+
assert mapping.register == 401
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def test_assign_adds_data_assembly_to_named_procedure(tmp_path):
|
|
63
|
+
config = {
|
|
64
|
+
"internal_equipment": {
|
|
65
|
+
"start_stop": {
|
|
66
|
+
"class": "mtppy.part3.data_assembly_set.indicator_elements.views.dint_view.DIntView",
|
|
67
|
+
"assign": ["auto"],
|
|
68
|
+
"V": {"register": 401, "access": "write"},
|
|
69
|
+
},
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
config_path = tmp_path / "config.json"
|
|
73
|
+
config_path.write_text(json.dumps(config))
|
|
74
|
+
|
|
75
|
+
mock_procedure = MagicMock()
|
|
76
|
+
mock_procedure.name = "auto"
|
|
77
|
+
mock_service = MagicMock()
|
|
78
|
+
mock_service.procedures = {"auto": mock_procedure}
|
|
79
|
+
|
|
80
|
+
with patch("pymodbus.client.ModbusTcpClient") as mock_client_cls:
|
|
81
|
+
mock_client_cls.return_value.connect.return_value = True
|
|
82
|
+
pea = M15Pea(config_path=config_path)
|
|
83
|
+
pea.service_set["produce"] = mock_service
|
|
84
|
+
|
|
85
|
+
pea._assign_data_assemblies(
|
|
86
|
+
{"auto": ["start_stop"]},
|
|
87
|
+
{"start_stop": pea.data_assemblies["start_stop"]},
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
mock_procedure.add_required_equipment.assert_called_once_with(
|
|
91
|
+
pea.data_assemblies["start_stop"]
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def test_assign_logs_warning_for_missing_procedure(tmp_path, caplog):
|
|
96
|
+
config = {
|
|
97
|
+
"internal_equipment": {
|
|
98
|
+
"start_stop": {
|
|
99
|
+
"class": "mtppy.part3.data_assembly_set.indicator_elements.views.dint_view.DIntView",
|
|
100
|
+
"assign": ["nonexistent"],
|
|
101
|
+
"V": {"register": 401, "access": "write"},
|
|
102
|
+
},
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
config_path = tmp_path / "config.json"
|
|
106
|
+
config_path.write_text(json.dumps(config))
|
|
107
|
+
|
|
108
|
+
with patch("pymodbus.client.ModbusTcpClient") as mock_client_cls:
|
|
109
|
+
mock_client_cls.return_value.connect.return_value = True
|
|
110
|
+
pea = M15Pea(config_path=config_path)
|
|
111
|
+
|
|
112
|
+
pea._assign_data_assemblies(
|
|
113
|
+
{"nonexistent": ["start_stop"]},
|
|
114
|
+
{"start_stop": pea.data_assemblies["start_stop"]},
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
assert "procedure 'nonexistent' not found for assignment" in caplog.text
|