diff --git a/backend/script_groups/IO_adaptation/.debug/98050_PLC_01_CAx_Export.aml b/backend/script_groups/IO_adaptation/.debug/98050_PLC_01_CAx_Export.aml
new file mode 100644
index 0000000..4380513
--- /dev/null
+++ b/backend/script_groups/IO_adaptation/.debug/98050_PLC_01_CAx_Export.aml
@@ -0,0 +1,6765 @@
+
+
+
+
+ Totally Integrated Automation Portal
+ 1d4fcebb-1ad6-4881-b01d-bca335d94a46:V1.0
+ Siemens AG
+ www.siemens.com
+ 1900
+ 1900.0.6801.3
+ 2025-06-06T14:33:51.3850474Z
+
+
+
+
+
+
+
+
+
+
+
+ Ethernet
+
+
+
+
+
+
+
+ GSD:GSDML-V2.33-NTI-30165-PN_PD-V1.0-20230705.XML/D
+
+
+
+ Rack
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.33-NTI-30165-PN_PD-V1.0-20230705.XML/R/DAP 1
+
+
+
+ C1250xMIPD 1S V3.0
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.33-NTI-30165-PN_PD-V1.0-20230705.XML/DAP/DAP 1
+
+
+
+ 0
+
+
+ true
+
+
+ 2024-04-18T09:41:28.8740789Z
+
+
+
+
+
+ X1
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.31
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+ DO SERVO
+
+
+ 1
+
+
+ false
+
+
+ GSD:GSDML-V2.33-NTI-30165-PN_PD-V1.0-20230705.XML/M/IDM_SERVO
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ SIEMENS telegram 105, PZD-10/10
+
+
+ 1
+
+
+ false
+
+
+ GSD:GSDML-V2.33-NTI-30165-PN_PD-V1.0-20230705.XML/SM/IDS_TEL105
+
+
+
+
+
+ 100
+
+
+ 160
+
+
+ Input
+
+
+
+
+ 100
+
+
+ 160
+
+
+ Output
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GSD:GSDML-V2.33-NTI-30165-PN_PD-V1.0-20230705.XML/D
+
+
+
+ Rack
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.33-NTI-30165-PN_PD-V1.0-20230705.XML/R/DAP 1
+
+
+
+ C1250xMIPD 1S V3.0
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.33-NTI-30165-PN_PD-V1.0-20230705.XML/DAP/DAP 1
+
+
+
+ 0
+
+
+ true
+
+
+ 2024-04-18T09:44:18.5075658Z
+
+
+
+
+
+ X1
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.32
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+ DO SERVO
+
+
+ 1
+
+
+ false
+
+
+ GSD:GSDML-V2.33-NTI-30165-PN_PD-V1.0-20230705.XML/M/IDM_SERVO
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ SIEMENS telegram 105, PZD-10/10
+
+
+ 1
+
+
+ false
+
+
+ GSD:GSDML-V2.33-NTI-30165-PN_PD-V1.0-20230705.XML/SM/IDS_TEL105
+
+
+
+
+
+ 120
+
+
+ 160
+
+
+ Input
+
+
+
+
+ 120
+
+
+ 160
+
+
+ Output
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GSD:GSDML-V2.35-SIEMENS-MC-ENCODER-20240208.XML/D
+
+
+
+ Rack
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.35-SIEMENS-MC-ENCODER-20240208.XML/R/DAP_MT30_V20
+
+
+
+ Multiturn 30 Bit V2.x
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.35-SIEMENS-MC-ENCODER-20240208.XML/DAP/DAP_MT30_V20
+
+
+
+ 0
+
+
+ true
+
+
+ 2024-08-08T12:41:24.2692277Z
+
+
+
+
+
+ X1
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.170
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+
+
+ 1
+
+
+ true
+
+
+ GSD:GSDML-V2.35-SIEMENS-MC-ENCODER-20240208.XML/DAP/DAP_MT30_V20#BUILTIN
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ Standard Telegram 83, PZD2/8
+
+
+ 1
+
+
+ false
+
+
+ GSD:GSDML-V2.35-SIEMENS-MC-ENCODER-20240208.XML/SM/IDS_T83
+
+
+
+
+
+ 140
+
+
+ 128
+
+
+ Input
+
+
+
+
+ 140
+
+
+ 32
+
+
+ Output
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GSD:GSDML-V2.32-MITSUBISHIELECTRIC-MELSERVO_MR-J4-TM-20160415.XML/D
+
+
+
+ Rack
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MITSUBISHIELECTRIC-MELSERVO_MR-J4-TM-20160415.XML/R/DAP
+
+
+
+ MELSERVO MR-J4-TM
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MITSUBISHIELECTRIC-MELSERVO_MR-J4-TM-20160415.XML/DAP/DAP
+
+
+
+ 0
+
+
+ true
+
+
+ 2025-06-04T09:26:10.5697118Z
+
+
+
+
+
+ X1
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.33
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+
+
+ DO with manufacturer telegr. 102
+
+
+ 1
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MITSUBISHIELECTRIC-MELSERVO_MR-J4-TM-20160415.XML/M/ID_MODULE_TGM102
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ 4
+
+
+ 384
+
+
+ Input
+
+
+
+
+ 3
+
+
+ 384
+
+
+ Output
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GSD:GSDML-V2.32-MITSUBISHIELECTRIC-MELSERVO_MR-J4-TM-20160415.XML/D
+
+
+
+ Rack
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MITSUBISHIELECTRIC-MELSERVO_MR-J4-TM-20160415.XML/R/DAP
+
+
+
+ MELSERVO MR-J4-TM
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MITSUBISHIELECTRIC-MELSERVO_MR-J4-TM-20160415.XML/DAP/DAP
+
+
+
+ 0
+
+
+ true
+
+
+ 2025-06-04T10:22:55.6677054Z
+
+
+
+
+
+ X1
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.34
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+
+
+ DO with manufacturer telegr. 102
+
+
+ 1
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MITSUBISHIELECTRIC-MELSERVO_MR-J4-TM-20160415.XML/M/ID_MODULE_TGM102
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ 52
+
+
+ 384
+
+
+ Input
+
+
+
+
+ 51
+
+
+ 384
+
+
+ Output
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GSD:GSDML-V2.32-MITSUBISHIELECTRIC-MELSERVO_MR-J4-TM-20160415.XML/D
+
+
+
+ Rack
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MITSUBISHIELECTRIC-MELSERVO_MR-J4-TM-20160415.XML/R/DAP
+
+
+
+ MELSERVO MR-J4-TM
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MITSUBISHIELECTRIC-MELSERVO_MR-J4-TM-20160415.XML/DAP/DAP
+
+
+
+ 0
+
+
+ true
+
+
+ 2025-06-04T10:22:57.8834534Z
+
+
+
+
+
+ X1
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.35
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+
+
+ DO with manufacturer telegr. 102
+
+
+ 1
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MITSUBISHIELECTRIC-MELSERVO_MR-J4-TM-20160415.XML/M/ID_MODULE_TGM102
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ 156
+
+
+ 384
+
+
+ Input
+
+
+
+
+ 144
+
+
+ 384
+
+
+ Output
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GSD:GSDML-V2.32-MITSUBISHIELECTRIC-MELSERVO_MR-J4-TM-20160415.XML/D
+
+
+
+ Rack
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MITSUBISHIELECTRIC-MELSERVO_MR-J4-TM-20160415.XML/R/DAP
+
+
+
+ MELSERVO MR-J4-TM
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MITSUBISHIELECTRIC-MELSERVO_MR-J4-TM-20160415.XML/DAP/DAP
+
+
+
+ 0
+
+
+ true
+
+
+ 2025-06-04T10:22:58.627736Z
+
+
+
+
+
+ X1
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.36
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+
+
+ DO with manufacturer telegr. 102
+
+
+ 1
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MITSUBISHIELECTRIC-MELSERVO_MR-J4-TM-20160415.XML/M/ID_MODULE_TGM102
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ 204
+
+
+ 384
+
+
+ Input
+
+
+
+
+ 192
+
+
+ 384
+
+
+ Output
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GSD:GSDML-V2.34-SEW-MOVI-C-DECENTRALIZED-ELECTRONICS-20200731-071447.XML/D
+
+
+
+ Rack
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.34-SEW-MOVI-C-DECENTRALIZED-ELECTRONICS-20200731-071447.XML/R/DFC2xA V1.0
+
+
+
+ DFC2xA V1.0
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.34-SEW-MOVI-C-DECENTRALIZED-ELECTRONICS-20200731-071447.XML/DAP/DFC2xA V1.0
+
+
+
+ 0
+
+
+ true
+
+
+ 2025-06-04T11:10:07.4878522Z
+
+
+
+
+
+ X1
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.40
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+
+
+ Module I/O (08 words)
+
+
+ 2
+
+
+ false
+
+
+ GSD:GSDML-V2.34-SEW-MOVI-C-DECENTRALIZED-ELECTRONICS-20200731-071447.XML/M/8PD_InOut
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ 272
+
+
+ 128
+
+
+ Input
+
+
+
+
+ 272
+
+
+ 128
+
+
+ Output
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GSD:GSDML-V2.34-SEW-MOVI-C-DECENTRALIZED-ELECTRONICS-20200731-071447.XML/D
+
+
+
+ Rack
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.34-SEW-MOVI-C-DECENTRALIZED-ELECTRONICS-20200731-071447.XML/R/DFC2xA V1.0
+
+
+
+ DFC2xA V1.0
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.34-SEW-MOVI-C-DECENTRALIZED-ELECTRONICS-20200731-071447.XML/DAP/DFC2xA V1.0
+
+
+
+ 0
+
+
+ true
+
+
+ 2025-06-04T11:11:12.5503077Z
+
+
+
+
+
+ X1
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.44
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+
+
+ Module I/O (08 words)
+
+
+ 2
+
+
+ false
+
+
+ GSD:GSDML-V2.34-SEW-MOVI-C-DECENTRALIZED-ELECTRONICS-20200731-071447.XML/M/8PD_InOut
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ 288
+
+
+ 128
+
+
+ Input
+
+
+
+
+ 288
+
+
+ 128
+
+
+ Output
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/D
+
+
+
+ Rack
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/R/DAP2
+
+
+
+ DBS55-XXX Extend-A
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/DAP/DAP2
+
+
+
+ 0
+
+
+ true
+
+
+ 2025-06-04T11:19:39.977912Z
+
+
+
+
+
+ X1
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.41
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+
+
+ 1
+
+
+ true
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/DAP/DAP2#BUILTIN
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ 4000
+
+
+ 176
+
+
+ Input
+
+
+
+
+ 4000
+
+
+ 352
+
+
+ Output
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/D
+
+
+
+ Rack
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/R/DAP2
+
+
+
+ DBS55-XXX Extend-A
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/DAP/DAP2
+
+
+
+ 0
+
+
+ true
+
+
+ 2025-06-04T11:35:53.5985271Z
+
+
+
+
+
+ X1
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.42
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+
+
+ 1
+
+
+ true
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/DAP/DAP2#BUILTIN
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ 4022
+
+
+ 176
+
+
+ Input
+
+
+
+
+ 4044
+
+
+ 352
+
+
+ Output
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/D
+
+
+
+ Rack
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/R/DAP2
+
+
+
+ DBS55-XXX Extend-A
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/DAP/DAP2
+
+
+
+ 0
+
+
+ true
+
+
+ 2025-06-04T11:36:17.8146442Z
+
+
+
+
+
+ X1
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.43
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+
+
+ 1
+
+
+ true
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/DAP/DAP2#BUILTIN
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ 4044
+
+
+ 176
+
+
+ Input
+
+
+
+
+ 4088
+
+
+ 352
+
+
+ Output
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/D
+
+
+
+ Rack
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/R/DAP2
+
+
+
+ DBS55-XXX Extend-A
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/DAP/DAP2
+
+
+
+ 0
+
+
+ true
+
+
+ 2025-06-04T11:36:43.4306961Z
+
+
+
+
+
+ X1
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.37
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+
+
+ 1
+
+
+ true
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/DAP/DAP2#BUILTIN
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ 4066
+
+
+ 176
+
+
+ Input
+
+
+
+
+ 4132
+
+
+ 352
+
+
+ Output
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GSD:GSDML-V2.34-SEW-MOVI-C-DECENTRALIZED-ELECTRONICS-20200731-071447.XML/D
+
+
+
+ Rack
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.34-SEW-MOVI-C-DECENTRALIZED-ELECTRONICS-20200731-071447.XML/R/DFC2xA V1.0
+
+
+
+ DFC2xA V1.0
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.34-SEW-MOVI-C-DECENTRALIZED-ELECTRONICS-20200731-071447.XML/DAP/DFC2xA V1.0
+
+
+
+ 0
+
+
+ true
+
+
+ 2025-06-04T12:21:47.7770347Z
+
+
+
+
+
+ X1
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.45
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+
+
+ Module I/O (08 words)
+
+
+ 2
+
+
+ false
+
+
+ GSD:GSDML-V2.34-SEW-MOVI-C-DECENTRALIZED-ELECTRONICS-20200731-071447.XML/M/8PD_InOut
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ 304
+
+
+ 128
+
+
+ Input
+
+
+
+
+ 304
+
+
+ 128
+
+
+ Output
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/D
+
+
+
+ Rack
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/R/DAP2
+
+
+
+ DBS55-XXX Extend-A
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/DAP/DAP2
+
+
+
+ 0
+
+
+ true
+
+
+ 2025-06-04T12:22:43.0240873Z
+
+
+
+
+
+ X1
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.46
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+
+
+ 1
+
+
+ true
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/DAP/DAP2#BUILTIN
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ 4088
+
+
+ 176
+
+
+ Input
+
+
+
+
+ 4176
+
+
+ 352
+
+
+ Output
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/D
+
+
+
+ Rack
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/R/DAP2
+
+
+
+ DBS55-XXX Extend-A
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/DAP/DAP2
+
+
+
+ 0
+
+
+ true
+
+
+ 2025-06-04T12:25:07.2968703Z
+
+
+
+
+
+ X1
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.47
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+
+
+ 1
+
+
+ true
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/DAP/DAP2#BUILTIN
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ 4110
+
+
+ 176
+
+
+ Input
+
+
+
+
+ 4220
+
+
+ 352
+
+
+ Output
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/D
+
+
+
+ Rack
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/R/DAP2
+
+
+
+ DBS55-XXX Extend-A
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/DAP/DAP2
+
+
+
+ 0
+
+
+ true
+
+
+ 2025-06-04T12:25:10.586042Z
+
+
+
+
+
+ X1
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.48
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+
+
+ 1
+
+
+ true
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/DAP/DAP2#BUILTIN
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ 4132
+
+
+ 176
+
+
+ Input
+
+
+
+
+ 4264
+
+
+ 352
+
+
+ Output
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/D
+
+
+
+ Rack
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/R/DAP2
+
+
+
+ DBS55-XXX Extend-A
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/DAP/DAP2
+
+
+
+ 0
+
+
+ true
+
+
+ 2025-06-04T12:25:11.1464652Z
+
+
+
+
+
+ X1
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.49
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+
+
+ 1
+
+
+ true
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/DAP/DAP2#BUILTIN
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ 4154
+
+
+ 176
+
+
+ Input
+
+
+
+
+ 4308
+
+
+ 352
+
+
+ Output
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/D
+
+
+
+ Rack
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/R/DAP2
+
+
+
+ DBS55-XXX Extend-A
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/DAP/DAP2
+
+
+
+ 0
+
+
+ true
+
+
+ 2025-06-04T12:33:42.5411931Z
+
+
+
+
+
+ X1
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.70
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+
+
+ 1
+
+
+ true
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/DAP/DAP2#BUILTIN
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ 4176
+
+
+ 176
+
+
+ Input
+
+
+
+
+ 4352
+
+
+ 352
+
+
+ Output
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/D
+
+
+
+ Rack
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/R/DAP2
+
+
+
+ DBS55-XXX Extend-A
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/DAP/DAP2
+
+
+
+ 0
+
+
+ true
+
+
+ 2025-06-04T12:34:37.9348593Z
+
+
+
+
+
+ X1
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.71
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+
+
+ 1
+
+
+ true
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/DAP/DAP2#BUILTIN
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ 4198
+
+
+ 176
+
+
+ Input
+
+
+
+
+ 4396
+
+
+ 352
+
+
+ Output
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/D
+
+
+
+ Rack
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/R/DAP2
+
+
+
+ DBS55-XXX Extend-A
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/DAP/DAP2
+
+
+
+ 0
+
+
+ true
+
+
+ 2025-06-04T12:34:38.7329655Z
+
+
+
+
+
+ X1
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.72
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+
+
+ 1
+
+
+ true
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/DAP/DAP2#BUILTIN
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ 4220
+
+
+ 176
+
+
+ Input
+
+
+
+
+ 4440
+
+
+ 352
+
+
+ Output
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GSD:GSDML-V2.34-SEW-MOVI-C-DECENTRALIZED-ELECTRONICS-20200731-071447.XML/D
+
+
+
+ Rack
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.34-SEW-MOVI-C-DECENTRALIZED-ELECTRONICS-20200731-071447.XML/R/DFC2xA V1.0
+
+
+
+ DFC2xA V1.0
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.34-SEW-MOVI-C-DECENTRALIZED-ELECTRONICS-20200731-071447.XML/DAP/DFC2xA V1.0
+
+
+
+ 0
+
+
+ true
+
+
+ 2025-06-04T12:34:50.1739775Z
+
+
+
+
+
+ X1
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.74
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+
+
+ Module I/O (08 words)
+
+
+ 2
+
+
+ false
+
+
+ GSD:GSDML-V2.34-SEW-MOVI-C-DECENTRALIZED-ELECTRONICS-20200731-071447.XML/M/8PD_InOut
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ 362
+
+
+ 128
+
+
+ Input
+
+
+
+
+ 340
+
+
+ 128
+
+
+ Output
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/D
+
+
+
+ Rack
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/R/DAP2
+
+
+
+ DBS55-XXX Extend-A
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/DAP/DAP2
+
+
+
+ 0
+
+
+ true
+
+
+ 2025-06-04T12:35:21.3008811Z
+
+
+
+
+
+ X1
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.73
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+
+
+ 1
+
+
+ true
+
+
+ GSD:GSDML-V2.32-MINIMOTOR-DBS55-20190315.XML/DAP/DAP2#BUILTIN
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ 4242
+
+
+ 176
+
+
+ Input
+
+
+
+
+ 4484
+
+
+ 352
+
+
+ Output
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ System:Device.ET200SP
+
+
+
+ Rack
+
+
+ 0
+
+
+ false
+
+
+ System:Rack.ET200SP
+
+
+
+ CPU 1514SP T-2 PN
+
+
+ CPU
+
+
+ 1
+
+
+ false
+
+
+ OrderNumber:6ES7 514-2VN03-0AB0
+
+
+ 2024-04-17T08:32:23.4139309Z
+
+
+ V3.1
+
+
+
+
+ "PD_TEL83_IN"
+
+ true
+
+
+
+ Input
+
+
+ 140.0
+
+
+
+
+ "PD_TEL83_OUT"
+
+ true
+
+
+
+ Output
+
+
+ 140.0
+
+
+
+
+ "PD_TEL105_IN"
+
+ true
+
+
+
+ Input
+
+
+ 100.0
+
+
+
+
+ "PD_TEL105_OUT"
+
+ true
+
+
+
+ Output
+
+
+ 100.0
+
+
+
+
+ "PD_TEL105_IN"
+
+ true
+
+
+
+ Input
+
+
+ 120.0
+
+
+
+
+ "PD_TEL105_OUT"
+
+ true
+
+
+
+ Output
+
+
+ 120.0
+
+
+
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 0.3
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 0.4
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 0.5
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 0.6
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 0.7
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 1.0
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 1.1
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 1.2
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 1.3
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 1.4
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 1.5
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 1.6
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 1.7
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 2.0
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 2.1
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 2.2
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 2.3
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 2.4
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 2.5
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 3.0
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 3.1
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 4.0
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 4.1
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 2.6
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 4.2
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 4.3
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 4.4
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 4.5
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 3.2
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 3.3
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 3.4
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 3.6
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 3.5
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 5.0
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 5.1
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 5.2
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 5.3
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 5.4
+
+
+
+
+ Bool
+
+
+ Input
+
+
+ 5.5
+
+
+
+
+
+
+
+ Bool
+
+
+ Output
+
+
+ 0.0
+
+
+
+
+ Bool
+
+
+ Output
+
+
+ 0.1
+
+
+
+
+ Bool
+
+
+ Output
+
+
+ 0.4
+
+
+
+
+ Bool
+
+
+ Output
+
+
+ 0.5
+
+
+
+
+ Bool
+
+
+ Output
+
+
+ 0.6
+
+
+
+
+ Bool
+
+
+ Output
+
+
+ 0.7
+
+
+
+
+ Bool
+
+
+ Output
+
+
+ 1.0
+
+
+
+
+ Bool
+
+
+ Output
+
+
+ 1.1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 4
+
+
+ true
+
+
+
+
+
+ 254
+
+
+ true
+
+
+
+
+
+ X2
+
+
+ 33024
+
+
+ true
+
+
+
+ 255.255.255.0
+
+
+ Project
+
+
+ Ethernet
+
+
+ 192.168.1.1
+
+
+
+
+
+
+ P1
+
+
+ 33025
+
+
+ true
+
+
+
+
+
+
+
+ BA 2xRJ45
+
+
+ 127
+
+
+ false
+
+
+ OrderNumber:6ES7 193-6AR00-0AA0
+
+
+ V0.0
+
+
+
+ X1
+
+
+ 32768
+
+
+ true
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.11
+
+
+
+
+
+
+
+ 100
+
+
+
+
+
+
+ P1R
+
+
+ 32769
+
+
+ true
+
+
+
+
+
+ P2R
+
+
+ 32770
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+ DI 8x24VDC ST
+
+
+ 2
+
+
+ false
+
+
+ OrderNumber:6ES7 131-6BF01-0BA0
+
+
+ 2024-04-17T08:34:49.0785292Z
+
+
+ V0.0
+
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ 0
+
+
+ 8
+
+
+ Input
+
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 0
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 1
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 2
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 3
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 4
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 5
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 6
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 7
+
+
+ 1
+
+
+
+
+
+
+
+
+ DI 8x24VDC ST
+
+
+ 3
+
+
+ false
+
+
+ OrderNumber:6ES7 131-6BF01-0BA0
+
+
+ 2024-04-17T08:36:19.2600882Z
+
+
+ V0.0
+
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ 1
+
+
+ 8
+
+
+ Input
+
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 0
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 1
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 2
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 3
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 4
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 5
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 6
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 7
+
+
+ 1
+
+
+
+
+
+
+
+
+ DI 8x24VDC ST
+
+
+ 4
+
+
+ false
+
+
+ OrderNumber:6ES7 131-6BF01-0BA0
+
+
+ 2024-04-17T08:36:22.830042Z
+
+
+ V0.0
+
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ 2
+
+
+ 8
+
+
+ Input
+
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 0
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 1
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 2
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 3
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 4
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 5
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 6
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 7
+
+
+ 1
+
+
+
+
+
+
+
+
+ DI 8x24VDC ST
+
+
+ 5
+
+
+ false
+
+
+ OrderNumber:6ES7 131-6BF01-0BA0
+
+
+ 2024-04-17T08:36:24.1275448Z
+
+
+ V0.0
+
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ 3
+
+
+ 8
+
+
+ Input
+
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 0
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 1
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 2
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 3
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 4
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 5
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 6
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Input
+
+
+ 7
+
+
+ 1
+
+
+
+
+
+
+
+
+ DQ 8x24VDC/0.5A ST
+
+
+ 6
+
+
+ false
+
+
+ OrderNumber:6ES7 132-6BF01-0BA0
+
+
+ 2024-04-17T08:38:16.428966Z
+
+
+ V0.0
+
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ 0
+
+
+ 8
+
+
+ Output
+
+
+
+
+
+ Digital
+
+
+ Output
+
+
+ 0
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Output
+
+
+ 1
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Output
+
+
+ 2
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Output
+
+
+ 3
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Output
+
+
+ 4
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Output
+
+
+ 5
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Output
+
+
+ 6
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Output
+
+
+ 7
+
+
+ 1
+
+
+
+
+
+
+
+
+ DQ 8x24VDC/0.5A ST
+
+
+ 7
+
+
+ false
+
+
+ OrderNumber:6ES7 132-6BF01-0BA0
+
+
+ 2024-04-17T08:38:19.110631Z
+
+
+ V0.0
+
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ 1
+
+
+ 8
+
+
+ Output
+
+
+
+
+
+ Digital
+
+
+ Output
+
+
+ 0
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Output
+
+
+ 1
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Output
+
+
+ 2
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Output
+
+
+ 3
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Output
+
+
+ 4
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Output
+
+
+ 5
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Output
+
+
+ 6
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Output
+
+
+ 7
+
+
+ 1
+
+
+
+
+
+
+
+
+ DQ 8x24VDC/0.5A ST
+
+
+ 8
+
+
+ false
+
+
+ OrderNumber:6ES7 132-6BF01-0BA0
+
+
+ 2025-03-27T14:28:23.3071593Z
+
+
+ V0.0
+
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ 2
+
+
+ 8
+
+
+ Output
+
+
+
+
+
+ Digital
+
+
+ Output
+
+
+ 0
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Output
+
+
+ 1
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Output
+
+
+ 2
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Output
+
+
+ 3
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Output
+
+
+ 4
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Output
+
+
+ 5
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Output
+
+
+ 6
+
+
+ 1
+
+
+
+
+ Digital
+
+
+ Output
+
+
+ 7
+
+
+ 1
+
+
+
+
+
+
+
+
+ Server module
+
+
+ 9
+
+
+ false
+
+
+ OrderNumber:6ES7 193-6PA00-0AA0
+
+
+ 2024-04-17T08:47:41.924663Z
+
+
+ V1.1
+
+
+
+ 1
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ System:Device.G120C-2
+
+
+
+ 0
+
+
+ false
+
+
+ System:Rack.G120CPN-2
+
+
+
+ G120C PN
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ OrderNumber:6SL3210-1KE13-2AF2
+
+
+ 4.7.13
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ X150
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.58
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+ 3
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+ System:Device.G120C-2
+
+
+
+ 0
+
+
+ false
+
+
+ System:Rack.G120CPN-2
+
+
+
+ G120C PN
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ OrderNumber:6SL3210-1KE13-2AF2
+
+
+ 4.7.13
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ X150
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.59
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+ 3
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+ System:Device.G120C-2
+
+
+
+ 0
+
+
+ false
+
+
+ System:Rack.G120CPN-2
+
+
+
+ G120C PN
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ OrderNumber:6SL3210-1KE13-2AF2
+
+
+ 4.7.13
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ X150
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.60
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+ 3
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+ System:Device.G120C-2
+
+
+
+ 0
+
+
+ false
+
+
+ System:Rack.G120CPN-2
+
+
+
+ G120C PN
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ OrderNumber:6SL3210-1KE13-2AF2
+
+
+ 4.7.13
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ X150
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.61
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+ 3
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+ System:Device.G120C-2
+
+
+
+ 0
+
+
+ false
+
+
+ System:Rack.G120CPN-2
+
+
+
+ G120C PN
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ OrderNumber:6SL3210-1KE13-2AF2
+
+
+ 4.7.13
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ X150
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.62
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+ 3
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+ System:Device.G120C-2
+
+
+
+ 0
+
+
+ false
+
+
+ System:Rack.G120CPN-2
+
+
+
+ G120C PN
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ OrderNumber:6SL3210-1KE13-2AF2
+
+
+ 4.7.13
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ X150
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.63
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+ 3
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+ System:Device.G120C-2
+
+
+
+ 0
+
+
+ false
+
+
+ System:Rack.G120CPN-2
+
+
+
+ G120C PN
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ OrderNumber:6SL3210-1KE13-2AF2
+
+
+ 4.7.13
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ X150
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.64
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+ 3
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+ System:Device.G120C-2
+
+
+
+ 0
+
+
+ false
+
+
+ System:Rack.G120CPN-2
+
+
+
+ G120C PN
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ OrderNumber:6SL3210-1KE13-2AF2
+
+
+ 4.7.13
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ X150
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.65
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+ 3
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+ System:Device.G120C-2
+
+
+
+ 0
+
+
+ false
+
+
+ System:Rack.G120CPN-2
+
+
+
+ G120C PN
+
+
+ HeadModule
+
+
+ 0
+
+
+ false
+
+
+ OrderNumber:6SL3210-1KE13-2AF2
+
+
+ 4.7.13
+
+
+
+ 0
+
+
+ true
+
+
+
+
+
+ X150
+
+
+ 1
+
+
+ true
+
+
+
+
+ 255.240.0.0
+
+
+ 10.1.30.1
+
+
+ Project
+
+
+ Ethernet
+
+
+ 10.1.30.66
+
+
+
+
+
+
+
+ P1R
+
+
+ 1
+
+
+ true
+
+
+
+
+
+ P2R
+
+
+ 2
+
+
+ true
+
+
+
+
+
+
+
+ 3
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/backend/script_groups/IO_adaptation/Hardware.md b/backend/script_groups/IO_adaptation/Hardware.md
new file mode 100644
index 0000000..b7f1ed8
--- /dev/null
+++ b/backend/script_groups/IO_adaptation/Hardware.md
@@ -0,0 +1,50 @@
+# IO Summary Table for PLC: A40510
+
+| Network | Type | Address | Device Name | Sub-Device | OrderNo | Type | IO Type | IO Address | Number of Bits |
+|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.31 | U30110-AxisX | DO SERVO_1 | N/A | DO SERVO | Input | `EW 100..119` | 160 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.31 | U30110-AxisX | DO SERVO_1 | N/A | DO SERVO | Output | `AW 100..119` | 160 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.32 | U30210-AxisY | DO SERVO_1 | N/A | DO SERVO | Input | `EW 120..139` | 160 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.32 | U30210-AxisY | DO SERVO_1 | N/A | DO SERVO | Output | `AW 120..139` | 160 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.33 | U30310 | DO with manufacturer telegr. 102_1 | N/A | DO with manufacturer telegr. 102 | Input | `EW 4..51` | 384 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.33 | U30310 | DO with manufacturer telegr. 102_1 | N/A | DO with manufacturer telegr. 102 | Output | `AW 3..50` | 384 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.34 | U30410 | DO with manufacturer telegr. 102_1 | N/A | DO with manufacturer telegr. 102 | Input | `EW 52..99` | 384 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.34 | U30410 | DO with manufacturer telegr. 102_1 | N/A | DO with manufacturer telegr. 102 | Output | `AW 51..98` | 384 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.35 | U30510 | DO with manufacturer telegr. 102_1 | N/A | DO with manufacturer telegr. 102 | Input | `EW 156..203` | 384 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.35 | U30510 | DO with manufacturer telegr. 102_1 | N/A | DO with manufacturer telegr. 102 | Output | `AW 144..191` | 384 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.36 | U30610 | DO with manufacturer telegr. 102_1 | N/A | DO with manufacturer telegr. 102 | Input | `EW 204..251` | 384 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.36 | U30610 | DO with manufacturer telegr. 102_1 | N/A | DO with manufacturer telegr. 102 | Output | `AW 192..239` | 384 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.37 | M30710 | DS402_Extend-A | N/A | N/A | Input | `EW 4066..4087` | 176 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.37 | M30710 | DS402_Extend-A | N/A | N/A | Output | `AW 4132..4175` | 352 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.40 | M31010 | Module I/O (08 words) | N/A | Module I/O (08 words) | Input | `EW 272..287` | 128 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.40 | M31010 | Module I/O (08 words) | N/A | Module I/O (08 words) | Output | `AW 272..287` | 128 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.41 | M31110 | DS402_Extend-A | N/A | N/A | Input | `EW 4000..4021` | 176 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.41 | M31110 | DS402_Extend-A | N/A | N/A | Output | `AW 4000..4043` | 352 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.42 | M31210 | DS402_Extend-A | N/A | N/A | Input | `EW 4022..4043` | 176 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.42 | M31210 | DS402_Extend-A | N/A | N/A | Output | `AW 4044..4087` | 352 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.43 | M31310 | DS402_Extend-A | N/A | N/A | Input | `EW 4044..4065` | 176 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.43 | M31310 | DS402_Extend-A | N/A | N/A | Output | `AW 4088..4131` | 352 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.44 | M31410 | Module I/O (08 words) | N/A | Module I/O (08 words) | Input | `EW 288..303` | 128 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.44 | M31410 | Module I/O (08 words) | N/A | Module I/O (08 words) | Output | `AW 288..303` | 128 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.45 | M31510 | Module I/O (08 words) | N/A | Module I/O (08 words) | Input | `EW 304..319` | 128 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.45 | M31510 | Module I/O (08 words) | N/A | Module I/O (08 words) | Output | `AW 304..319` | 128 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.46 | M31610 | DS402_Extend-A | N/A | N/A | Input | `EW 4088..4109` | 176 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.46 | M31610 | DS402_Extend-A | N/A | N/A | Output | `AW 4176..4219` | 352 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.47 | M31710 | DS402_Extend-A | N/A | N/A | Input | `EW 4110..4131` | 176 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.47 | M31710 | DS402_Extend-A | N/A | N/A | Output | `AW 4220..4263` | 352 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.48 | M31810 | DS402_Extend-A | N/A | N/A | Input | `EW 4132..4153` | 176 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.48 | M31810 | DS402_Extend-A | N/A | N/A | Output | `AW 4264..4307` | 352 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.49 | M31910 | DS402_Extend-A | N/A | N/A | Input | `EW 4154..4175` | 176 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.49 | M31910 | DS402_Extend-A | N/A | N/A | Output | `AW 4308..4351` | 352 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.70 | M34010 | DS402_Extend-A | N/A | N/A | Input | `EW 4176..4197` | 176 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.70 | M34010 | DS402_Extend-A | N/A | N/A | Output | `AW 4352..4395` | 352 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.71 | M34110 | DS402_Extend-A | N/A | N/A | Input | `EW 4198..4219` | 176 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.71 | M34110 | DS402_Extend-A | N/A | N/A | Output | `AW 4396..4439` | 352 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.72 | M34210 | DS402_Extend-A | N/A | N/A | Input | `EW 4220..4241` | 176 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.72 | M34210 | DS402_Extend-A | N/A | N/A | Output | `AW 4440..4483` | 352 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.73 | M34310 | DS402_Extend-A | N/A | N/A | Input | `EW 4242..4263` | 176 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.73 | M34310 | DS402_Extend-A | N/A | N/A | Output | `AW 4484..4527` | 352 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.74 | M34410 | Module I/O (08 words) | N/A | Module I/O (08 words) | Input | `EW 362..377` | 128 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.74 | M34410 | Module I/O (08 words) | N/A | Module I/O (08 words) | Output | `AW 340..355` | 128 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.170 | E44010-Encoder | EO Encoder Multiturn V2.x_1 | N/A | N/A | Input | `EW 140..155` | 128 |
+| PN/IE_1 | Ethernet/Profinet | 10.1.30.170 | E44010-Encoder | EO Encoder Multiturn V2.x_1 | N/A | N/A | Output | `AW 140..143` | 32 |
\ No newline at end of file
diff --git a/backend/script_groups/IO_adaptation/log_x1_export_CAx.txt b/backend/script_groups/IO_adaptation/log_x1_export_CAx.txt
index 06152c7..e1861e9 100644
--- a/backend/script_groups/IO_adaptation/log_x1_export_CAx.txt
+++ b/backend/script_groups/IO_adaptation/log_x1_export_CAx.txt
@@ -1,38 +1,14 @@
--- Log de Ejecución: x1_export_CAx.py ---
Grupo: IO_adaptation
Directorio de Trabajo: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia
-Inicio: 2025-06-06 16:30:18
-Fin: 2025-06-06 16:33:55
-Duración: 0:03:37.052535
+Inicio: 2025-06-06 18:25:09
+Fin: 2025-06-06 18:25:20
+Duración: 0:00:11.673530
Estado: SUCCESS (Código de Salida: 0)
--- SALIDA ESTÁNDAR (STDOUT) ---
--- TIA Portal Project CAx Exporter and Analyzer ---
-
-Selected Project: D:/Trabajo/VM/44 - 98050 - Fiera/InLavoro/PLC/98050_PLC_01/98050_PLC_01.ap19
-Using Output Directory (Working Directory): D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia
-Detected TIA Portal version: 19.0 (from extension .ap19)
-Will export CAx data to: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\98050_PLC_01_CAx_Export.aml
-Will generate summary to: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\98050_PLC_01_CAx_Summary.md
-Export log file: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\98050_PLC_01_CAx_Export.log
-
-Connecting to TIA Portal V19.0...
-2025-06-06 16:30:25,861 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Global OpenPortal - Start TIA Portal, please acknowledge the security dialog.
-2025-06-06 16:30:25,895 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Global OpenPortal - With user interface
-Connected.
-Opening project: 98050_PLC_01.ap19...
-2025-06-06 16:32:34,404 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Portal OpenProject - Open project... D:\Trabajo\VM\44 - 98050 - Fiera\InLavoro\PLC\98050_PLC_01\98050_PLC_01.ap19
-Project opened.
-Exporting CAx data for the project to D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\98050_PLC_01_CAx_Export.aml...
-CAx data exported successfully.
-
-Closing TIA Portal...
-2025-06-06 16:33:52,008 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Portal ClosePortal - Close TIA Portal
-TIA Portal closed.
-Parsing AML file: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\98050_PLC_01_CAx_Export.aml
-Markdown summary written to: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\98050_PLC_01_CAx_Summary.md
-
-Script finished.
+No project file selected. Exiting.
--- ERRORES (STDERR) ---
Ninguno
diff --git a/backend/script_groups/IO_adaptation/log_x2_process_CAx.txt b/backend/script_groups/IO_adaptation/log_x2_process_CAx.txt
index ee7fb94..d18720e 100644
--- a/backend/script_groups/IO_adaptation/log_x2_process_CAx.txt
+++ b/backend/script_groups/IO_adaptation/log_x2_process_CAx.txt
@@ -1,67 +1,76 @@
--- Log de Ejecución: x2_process_CAx.py ---
Grupo: IO_adaptation
Directorio de Trabajo: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia
-Inicio: 2025-06-06 16:34:01
-Fin: 2025-06-06 16:34:09
-Duración: 0:00:08.316649
+Inicio: 2025-06-07 14:29:10
+Fin: 2025-06-07 14:29:16
+Duración: 0:00:06.140835
Estado: SUCCESS (Código de Salida: 0)
--- SALIDA ESTÁNDAR (STDOUT) ---
---- AML (CAx Export) to Hierarchical JSON and Obsidian MD Converter (v31.1 - Corrected IO Summary Table Initialization) ---
+--- AML (CAx Export) to Hierarchical JSON and Obsidian MD Converter (v32.2 - Simplified IO Address Format (Separate Start/End)) ---
+Using configured working directory: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia
Using Working Directory for Output: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia
-Input AML: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\98050_PLC_01_CAx_Export.aml
+Input AML: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\98050_PLC_01.aml
Output Directory: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia
-Output JSON: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\98050_PLC_01_CAx_Export.hierarchical.json
-Output IO Debug Tree MD: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\98050_PLC_01_CAx_Export_IO_Upward_Debug.md
-Processing AML file: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\98050_PLC_01_CAx_Export.aml
+Output JSON: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\98050_PLC_01.hierarchical.json
+Output IO Debug Tree MD: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\98050_PLC_01_IO_Upward_Debug.md
+Processing AML file: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\98050_PLC_01.aml
Pass 1: Found 363 InternalElement(s). Populating device dictionary...
Pass 2: Identifying PLCs and Networks (Refined v2)...
- Identified Network: PN/IE_1 (fcbafb48-c53d-4af5-8143-794df99be4d6) Type: Unknown
+ Identified Network: PN/IE_1 (6ce86626-0043-4a58-b675-cc13ac87121c) Type: Ethernet/Profinet
Identified PLC: A40510 (fc0d3bac-267e-488a-8dcf-7dc8599d80e8) - Type: CPU 1514SP T-2 PN OrderNo: 6ES7 514-2VN03-0AB0
Pass 3: Processing InternalLinks (Robust Network Mapping & IO)...
Found 103 InternalLink(s).
- Mapping Device/Node 'E1' (NodeID:ffef8b7b-b6bf-46aa-b3b5-f5083c420563, Addr:10.1.30.11) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:221c248d-83d8-464c-9425-c949086b34e7, Addr:10.1.30.58) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:5c3bf795-ecec-47e7-a962-4d54c95b9887, Addr:10.1.30.59) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:4100c829-d889-489a-971c-a69207333e2f, Addr:10.1.30.60) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:a6aed467-1a4c-4a5a-bf3d-e7ce46e94a9f, Addr:10.1.30.61) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:b3d71b04-f99a-4af8-aa69-2ca02a30d391, Addr:10.1.30.62) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:eb59daf8-f59c-435e-bfe4-8e7afd0937bd, Addr:10.1.30.63) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:3e931f82-08a5-44de-89a5-b907f5aaeb24, Addr:10.1.30.64) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:f673d611-7a73-4a8e-912d-ea16c294d51b, Addr:10.1.30.65) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:09a2569a-4948-4830-9dd8-315ae638e391, Addr:10.1.30.66) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:719a9643-c903-454e-8325-0f03cf871c35, Addr:10.1.30.31) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:ef8c3829-2363-43b3-ae20-7e903c2517a5, Addr:10.1.30.32) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:7cece978-67aa-4707-b23c-375ebddfc2bc, Addr:10.1.30.170) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:ad86d223-8f60-41c0-8208-c88d68e42154, Addr:10.1.30.33) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:fa86bb0c-6142-41ce-ba6c-565e1e1f810e, Addr:10.1.30.34) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:441a0b56-5830-4595-ab8d-b073b6db8545, Addr:10.1.30.35) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:8dbc0c6b-a8f5-491c-832b-4af0757c259d, Addr:10.1.30.36) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:d06cdd21-62c3-4cff-9389-12a4e21869a2, Addr:10.1.30.40) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:f63db18d-dc19-48b8-afaa-be557db4d13e, Addr:10.1.30.44) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:21589a71-d4dd-4534-b457-deb72f3f7660, Addr:10.1.30.41) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:230ddec2-fa03-44d9-8350-0c0eeb463400, Addr:10.1.30.42) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:b2647d59-ed85-44c5-813f-167c41ea1ca1, Addr:10.1.30.43) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:9933a2a3-47db-448a-a724-ed583d5994bb, Addr:10.1.30.37) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:9b45edaa-0640-4e86-ba59-1b991c1a85ca, Addr:10.1.30.45) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:a5fbeadb-a8ab-42e0-b58f-296e44633ce5, Addr:10.1.30.46) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:67d1d9ad-cf1d-43aa-9dc4-9e574cda5e5b, Addr:10.1.30.47) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:08689cb8-1b00-403f-bc20-c5911a20e655, Addr:10.1.30.48) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:a06a0e94-b651-4510-bbe0-8a0c3b717283, Addr:10.1.30.49) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:cf339d67-1758-4462-85f0-9e6a002d1c3c, Addr:10.1.30.70) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:d80a9fcf-5e0d-45a9-b617-362a9cb4121a, Addr:10.1.30.71) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:7c28d11a-9673-4957-931d-8840a589da85, Addr:10.1.30.72) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:ad792043-fdb8-4695-a10a-aa2cad996cf0, Addr:10.1.30.74) to Network 'PN/IE_1'
- Mapping Device/Node 'IE1' (NodeID:b30940b8-6cb5-4143-854f-9b569f081703, Addr:10.1.30.73) to Network 'PN/IE_1'
+ Mapping Device/Node 'E1' (NodeID:ab796923-4471-4a60-98f4-f8ea5920b3b9, Addr:10.1.30.11) to Network 'PN/IE_1'
+ --> Found PLC in children: A40510 (ID: fc0d3bac-267e-488a-8dcf-7dc8599d80e8)
+ --> Associating Network 'PN/IE_1' with PLC 'A40510' (via Node 'E1' Addr: 10.1.30.11)
+ Mapping Device/Node 'IE1' (NodeID:c53ae31d-bee4-47ba-950d-15c31d2599b9, Addr:10.1.30.58) to Network 'PN/IE_1'
+ Mapping Device/Node 'IE1' (NodeID:1a8366c9-7d4c-4e49-b0a3-77d445eabc8b, Addr:10.1.30.59) to Network 'PN/IE_1'
+ Mapping Device/Node 'IE1' (NodeID:deeda41b-54d0-4c86-82c3-a311f753021e, Addr:10.1.30.60) to Network 'PN/IE_1'
+ Mapping Device/Node 'IE1' (NodeID:8a916a9d-895e-4a12-9190-516ef6a8f191, Addr:10.1.30.61) to Network 'PN/IE_1'
+ Mapping Device/Node 'IE1' (NodeID:c51471e0-9621-4ef7-b050-09bf4d695ea1, Addr:10.1.30.62) to Network 'PN/IE_1'
+ Mapping Device/Node 'IE1' (NodeID:77ca312c-3dd0-46f6-bd64-5da69a99cf6f, Addr:10.1.30.63) to Network 'PN/IE_1'
+ Mapping Device/Node 'IE1' (NodeID:011019c6-5925-4544-87aa-27288c3aa70c, Addr:10.1.30.64) to Network 'PN/IE_1'
+ Mapping Device/Node 'IE1' (NodeID:5ea1e894-b51c-44f9-8aff-80c58c6cb7ef, Addr:10.1.30.65) to Network 'PN/IE_1'
+ Mapping Device/Node 'IE1' (NodeID:612916a9-7a26-4712-9de2-d3c7894db862, Addr:10.1.30.66) to Network 'PN/IE_1'
+ Mapping Device/Node 'IE1' (NodeID:7be7cf9f-f7af-418c-8fe4-96b4a97a581d, Addr:10.1.30.31) to Network 'PN/IE_1'
+ Mapping Device/Node 'IE1' (NodeID:135492a8-02ab-4236-92ce-7a5585538297, Addr:10.1.30.32) to Network 'PN/IE_1'
+ Mapping Device/Node 'IE1' (NodeID:b7a06147-6428-4d95-ba0d-834fad49a1ae, Addr:10.1.30.170) to Network 'PN/IE_1'
+ Mapping Device/Node 'IE1' (NodeID:7ce83bdf-dc4d-40f0-85c8-a246dd2c44be, Addr:10.1.30.33) to Network 'PN/IE_1'
+ Mapping Device/Node 'IE1' (NodeID:e9a07506-2869-4c34-8541-ee021d1623f0, Addr:10.1.30.34) to Network 'PN/IE_1'
+ Mapping Device/Node 'IE1' (NodeID:3dd0f886-c3d0-4628-804b-ae18cf5931e8, Addr:10.1.30.35) to Network 'PN/IE_1'
+ Mapping Device/Node 'IE1' (NodeID:67c3fa72-a956-4363-9a4d-e3300d7d1429, Addr:10.1.30.36) to Network 'PN/IE_1'
+ Mapping Device/Node 'IE1' (NodeID:b35e73e8-a9ad-47e2-8ad5-00442c7a2df7, Addr:10.1.30.40) to Network 'PN/IE_1'
+ Mapping Device/Node 'IE1' (NodeID:867d0580-06cd-4722-a66f-8c5559b624f5, Addr:10.1.30.44) to Network 'PN/IE_1'
+ Mapping Device/Node 'IE1' (NodeID:6f1b4062-80ac-4d1a-b351-546c9d0157e2, Addr:10.1.30.41) to Network 'PN/IE_1'
+ Mapping Device/Node 'IE1' (NodeID:c0016a06-48cc-47af-83aa-d4a0a6cb44f6, Addr:10.1.30.42) to Network 'PN/IE_1'
+ Mapping Device/Node 'IE1' (NodeID:07fa5e8f-ffcf-4d81-9897-5ff9f73d6125, Addr:10.1.30.43) to Network 'PN/IE_1'
+ Mapping Device/Node 'IE1' (NodeID:5e8a4449-c958-4397-8b71-877af262333b, Addr:10.1.30.37) to Network 'PN/IE_1'
+ Mapping Device/Node 'IE1' (NodeID:79096325-dcb8-4650-bc44-2c9735a93f52, Addr:10.1.30.45) to Network 'PN/IE_1'
+ Mapping Device/Node 'IE1' (NodeID:957e5975-eafe-477c-a682-bebf330a2868, Addr:10.1.30.46) to Network 'PN/IE_1'
+ Mapping Device/Node 'IE1' (NodeID:379ccd79-27b4-4b53-a552-3da783bc5b25, Addr:10.1.30.47) to Network 'PN/IE_1'
+ Mapping Device/Node 'IE1' (NodeID:b53dd719-e8af-431f-b837-a0903ffb3a76, Addr:10.1.30.48) to Network 'PN/IE_1'
+ Mapping Device/Node 'IE1' (NodeID:0f28d88a-5208-4fc4-8ee1-f1bb33a947e8, Addr:10.1.30.49) to Network 'PN/IE_1'
+ Mapping Device/Node 'IE1' (NodeID:d1f8ea18-50d2-410e-9966-136d8a79471d, Addr:10.1.30.70) to Network 'PN/IE_1'
+ Mapping Device/Node 'IE1' (NodeID:1c86a627-5646-45e7-9c21-5d18d6544568, Addr:10.1.30.71) to Network 'PN/IE_1'
+ Mapping Device/Node 'IE1' (NodeID:e80a9939-59d7-44e0-9a46-1fade44e1b78, Addr:10.1.30.72) to Network 'PN/IE_1'
+ Mapping Device/Node 'IE1' (NodeID:8c51fa26-883a-468c-8c36-c0e1b31852e4, Addr:10.1.30.74) to Network 'PN/IE_1'
+ Mapping Device/Node 'IE1' (NodeID:17be2ccc-dede-4187-ba77-1ad8499a7349, Addr:10.1.30.73) to Network 'PN/IE_1'
Data extraction and structuring complete.
-Generating JSON output: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\98050_PLC_01_CAx_Export.hierarchical.json
+Generating JSON output: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\98050_PLC_01.hierarchical.json
JSON data written successfully.
-IO upward debug tree written to: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\98050_PLC_01_CAx_Export_IO_Upward_Debug.md
+IO upward debug tree written to: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\98050_PLC_01_IO_Upward_Debug.md
Found 1 PLC(s). Generating individual hardware trees...
- Generating Hardware Tree for PLC 'A40510' (ID: fc0d3bac-267e-488a-8dcf-7dc8599d80e8) at: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\A40510\Documentation\98050_PLC_01_CAx_Export_Hardware_Tree.md
-Markdown tree summary written to: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\A40510\Documentation\98050_PLC_01_CAx_Export_Hardware_Tree.md
+ Generating Hardware Tree for PLC 'A40510' (ID: fc0d3bac-267e-488a-8dcf-7dc8599d80e8) at: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\A40510\Documentation\98050_PLC_01_Hardware_Tree.md
+Markdown tree summary written to: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\A40510\Documentation\98050_PLC_01_Hardware_Tree.md
+IO summary table written to: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\Hardware.md
+IO summary table generated in separate file: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\Hardware.md
+ Generating Excel IO Report for PLC 'A40510' (ID: fc0d3bac-267e-488a-8dcf-7dc8599d80e8) at: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\A40510\Documentation\98050_PLC_01_IO_Report.xlsx
+Generating Excel IO report for PLC: A40510
+Excel IO report saved to: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\A40510\Documentation\98050_PLC_01_IO_Report.xlsx
+Total rows in report: 33
Script finished.
diff --git a/backend/script_groups/IO_adaptation/readme.md b/backend/script_groups/IO_adaptation/readme.md
index d0f4c93..4fad9b5 100644
--- a/backend/script_groups/IO_adaptation/readme.md
+++ b/backend/script_groups/IO_adaptation/readme.md
@@ -24,8 +24,29 @@ if __name__ == "__main__":
working_dir = configs.get("working_directory", "")
""""
- configs = load_configuration()
- working_directory = configs.get("working_directory")
+ try:
+ configs = load_configuration()
+ working_directory = configs.get("working_directory")
+ except Exception as e:
+ print(f"Warning: Could not load configuration (frontend not running): {e}")
+ configs = {}
+ working_directory = None
+
+ # Validate working directory with .debug fallback for standalone execution
+ if not working_directory or not os.path.isdir(working_directory):
+ print("Working directory not set or invalid in configuration.")
+ print("Using .debug directory as fallback for direct script execution.")
+
+ # Fallback to .debug directory under script location
+ script_dir = os.path.dirname(os.path.abspath(__file__))
+ debug_dir = os.path.join(script_dir, ".debug")
+
+ # Create .debug directory if it doesn't exist
+ os.makedirs(debug_dir, exist_ok=True)
+ working_directory = debug_dir
+ print(f"Using debug directory: {working_directory}")
+ else:
+ print(f"Using configured working directory: {working_directory}")
# Acceder a la configuración específica del grupo
group_config = configs.get("level2", {})
@@ -38,6 +59,34 @@ if __name__ == "__main__":
+### Debug Directory Fallback
+
+Cuando los scripts se ejecutan directamente (no desde el frontend), utilizan un sistema de fallback para determinar el directorio de trabajo:
+
+1. **Con Frontend**: Los scripts utilizan el `working_directory` configurado dinámicamente a través de `load_configuration()`
+2. **Ejecución Directa (Debug)**: Si no hay configuración válida, los scripts crean automáticamente un directorio `.debug` en la ubicación del script
+
+**Estructura del directorio de debug:**
+```
+IO_adaptation/
+├── .debug/ # ← Directorio creado automáticamente para debug
+│ ├── *.aml # Archivos AML procesados
+│ ├── *.hierarchical.json # Datos estructurados extraídos
+│ ├── *_IO_Upward_Debug.md # Archivo de debug de conexiones IO
+│ ├── Hardware.md # Tabla resumen de IO
+│ └── /
+│ └── Documentation/
+│ └── *_Hardware_Tree.md # Árbol de hardware por PLC
+├── x2_process_CAx.py # Script principal
+└── example/ # Archivos de ejemplo
+```
+
+**Ventajas del directorio .debug:**
+- ✅ Separación clara entre archivos de debug y archivos de producción
+- ✅ Fácil limpieza (se puede eliminar todo el directorio `.debug`)
+- ✅ No interfiere con archivos del proyecto principal
+- ✅ Creación automática sin configuración manual
+
### Directory structure for Tia Portal scripts
/
diff --git a/backend/script_groups/IO_adaptation/scripts_description.json b/backend/script_groups/IO_adaptation/scripts_description.json
index 22bb1a5..8b9c592 100644
--- a/backend/script_groups/IO_adaptation/scripts_description.json
+++ b/backend/script_groups/IO_adaptation/scripts_description.json
@@ -29,10 +29,46 @@
"long_description": "# Script de Adaptación IO para PLCTags\n\n## Descripción\n\nEste script automatiza la adaptación de tags PLC entre hardware físico Siemens TIA Portal y software master, actualizando las direcciones lógicas según un archivo de mapeo en formato Markdown.\n\n## Funcionamiento\n\n### Entradas\n- **Archivo Excel**: Exportación de tags desde TIA Portal\n- **Archivo Markdown**: Tabla de adaptación IO con mapeo entre hardware y master tags\n\n### Proceso\n1. **Análisis inicial**:\n - Lee la tabla Markdown de adaptación IO\n - Identifica las columnas de IO y Master Tag\n - Crea un diccionario de mapeo entre tags y direcciones IO\n\n2. **Procesamiento de tags**:\n - Filtra tags en los paths \"Inputs\", \"Outputs\", \"IO Not in Hardware\\InputsMaster\" y \"IO Not in Hardware\\OutputsMaster\"\n - Actualiza las direcciones lógicas de los tags encontrados en el mapeo\n - Reasigna paths según el tipo de señal (%E -> \"Inputs\", %A -> \"Outputs\")\n\n3. **Gestión de tags sin hardware**:\n - Asigna direcciones de memoria (%Mxxxx.x) para tags sin correspondencia\n - Tags de entrada: Asignados a \"IO Not in Hardware\\InputsMaster\" desde %M3600.0\n - Tags de salida: Asignados a \"IO Not in Hardware\\OutputsMaster\" desde %M3800.0\n\n4. **Manejo de direcciones**:\n - Convierte formatos (I0.0 → %E0.0, PEW100 → %EW100, etc.)\n - Gestiona bits incrementalmente (0.0, 0.1, ..., 0.7, luego 1.0)\n - Alinea words cada 2 bytes (%MW3600, %MW3602, etc.)\n\n### Salidas\n- **Archivo Excel actualizado**: Con las nuevas direcciones lógicas y paths\n- **Archivo de log**: Registro detallado del proceso con estadísticas\n\n## Uso\n1. Ejecute el script\n2. Seleccione el archivo Excel exportado de TIA Portal\n3. Seleccione el archivo Markdown con la tabla de adaptación\n4. El script generará automáticamente el archivo Excel actualizado\n\n## Detección de tipos\n- **Entradas**: Identificadas por prefijos (DI_, P_AI_, etc.)\n- **Salidas**: Identificadas por prefijos (DO_, P_AO_, etc.)\n- **Bits vs Words**: Determinados por el tipo de dato (Bool vs Word/Int)",
"hidden": false
},
+ "x7_update_CAx.py": {
+ "display_name": "7: Actualizar AML desde Excel modificado",
+ "short_description": "Actualiza un archivo AML original basándose en las modificaciones hechas en el archivo Excel de IOs.",
+ "long_description": "Este script permite hacer un 'round trip' de datos: extrae información del AML al Excel, permite ediciones manuales en el Excel, y luego aplica esos cambios de vuelta al AML original.\n***\n**Pipeline:**\n\n1. **Entrada:** Solicita el archivo AML original y el archivo Excel modificado (generado por x2_process_CAx.py)\n2. **Validación:** Genera un Excel de referencia desde el AML y compara con el Excel modificado para validar que la estructura base sea la misma (mismos nodos y nombres)\n3. **Detección de cambios:** Identifica modificaciones en:\n - Direcciones IP/nodos\n - Direcciones IO (inputs/outputs)\n - Tipos de dispositivos\n - Números de orden\n - Versiones de firmware\n4. **Aplicación:** Localiza los elementos correspondientes en el XML del AML y aplica los cambios detectados\n5. **Salida:** Genera un nuevo archivo AML con sufijo '_updated' que contiene todas las modificaciones\n\n**ID único:** Utiliza PLC+Device Name como identificador único para mapear cambios entre Excel y AML.\n\n**Restricciones:** Solo procede si el Excel modificado mantiene la misma cantidad de nodos y nombres que el Excel original.",
+ "hidden": false
+ },
"x0_documentation.py": {
"display_name": "0:Documentación",
"short_description": "Descripción del flujo de trabajo",
- "long_description": "### Flujo de trabajo:\n***\n1. Se usa [x1] para exportar los datos de configuración desde el proyecto de Tia Portal, incluidos los IO configurados en el hardware. Esto genera un archivo AML.\n2. Con [x2] se procesa el archivo AML y se convierte en markdown. Si hay un solo PLC se genera el archivo [Hardware.md]\n3. Se deben procesar los IO **desde el esquema eléctrico y agregarlos** a [Hardware.md]\n4. Se debe exportar todos los tags como un archivo excel desde el Tia Portal.\n5. Con [x3] se convierte y se filtran los tags según los path definidos en [io_paths_config] y se genera un archivo Master IO Tags.md\n6. [x4] Genera el prompt a usar con Claude usando MCP para que pueda acceder a los archivos originales y evitar tener que hacer uploads.\n7. Una vez que se genera el archivo procesado por el LLM se puede usar [x5] que convierte las adaptaciones a un archivo que luego se puede importar en Tia Portal\n8. Importar en Tia Portal el archivo [PLCTags_Updated.xlsx]",
+ "long_description": "### Flujo de trabajo:\n***\n1. Se usa [x1] para exportar los datos de configuración desde el proyecto de Tia Portal, incluidos los IO configurados en el hardware. Esto genera un archivo AML.\n2. Con [x2] se procesa el archivo AML y se convierte en markdown. Si hay un solo PLC se genera el archivo [Hardware.md]. **Además genera un archivo Excel con los IOs por nodos del PLC.**\n3. Se deben procesar los IO **desde el esquema eléctrico y agregarlos** a [Hardware.md]\n4. Se debe exportar todos los tags como un archivo excel desde el Tia Portal.\n5. Con [x3] se convierte y se filtran los tags según los path definidos en [io_paths_config] y se genera un archivo Master IO Tags.md\n6. [x4] Genera el prompt a usar con Claude usando MCP para que pueda acceder a los archivos originales y evitar tener que hacer uploads.\n7. Una vez que se genera el archivo procesado por el LLM se puede usar [x5] que convierte las adaptaciones a un archivo que luego se puede importar en Tia Portal\n8. Importar en Tia Portal el archivo [PLCTags_Updated.xlsx]\n\n**Nuevo flujo alternativo con Excel:**\nDesp¹és del paso 2, se puede usar [x7] para:\n- Modificar manualmente el archivo Excel de IOs generado\n- Aplicar los cambios de vuelta al archivo AML original\n- Generar un AML actualizado con las modificaciones",
+ "hidden": false
+ },
+ "analyze_u32810_specific.py": {
+ "display_name": "analyze_u32810_specific",
+ "short_description": "Sin descripción corta.",
+ "long_description": "",
+ "hidden": false
+ },
+ "compare_u32810_telegrams.py": {
+ "display_name": "compare_u32810_telegrams",
+ "short_description": "Sin descripción corta.",
+ "long_description": "",
+ "hidden": false
+ },
+ "comprehensive_address_search.py": {
+ "display_name": "comprehensive_address_search",
+ "short_description": "Sin descripción corta.",
+ "long_description": "",
+ "hidden": false
+ },
+ "find_address_differences.py": {
+ "display_name": "find_address_differences",
+ "short_description": "Sin descripción corta.",
+ "long_description": "",
+ "hidden": false
+ },
+ "find_u32810_addresses.py": {
+ "display_name": "find_u32810_addresses",
+ "short_description": "Sin descripción corta.",
+ "long_description": "",
"hidden": false
}
}
\ No newline at end of file
diff --git a/backend/script_groups/IO_adaptation/work_dir.json b/backend/script_groups/IO_adaptation/work_dir.json
index d181f0b..171212d 100644
--- a/backend/script_groups/IO_adaptation/work_dir.json
+++ b/backend/script_groups/IO_adaptation/work_dir.json
@@ -2,6 +2,7 @@
"path": "D:\\Trabajo\\VM\\44 - 98050 - Fiera\\Reporte\\ExportsTia",
"history": [
"D:\\Trabajo\\VM\\44 - 98050 - Fiera\\Reporte\\ExportsTia",
+ "D:\\Proyectos\\Scripts\\ParamManagerScripts\\backend\\script_groups\\IO_adaptation\\example",
"C:\\Trabajo\\SIDEL\\06 - E5.007363 - Modifica O&U - SAE196 (cip integrato)\\Reporte\\TAGsIO\\v2"
]
}
\ No newline at end of file
diff --git a/backend/script_groups/IO_adaptation/x2_process_CAx.py b/backend/script_groups/IO_adaptation/x2_process_CAx.py
index 1129aac..a11bc47 100644
--- a/backend/script_groups/IO_adaptation/x2_process_CAx.py
+++ b/backend/script_groups/IO_adaptation/x2_process_CAx.py
@@ -12,6 +12,7 @@ import json
from pathlib import Path
import re
import math # Needed for ceil
+import pandas as pd # For Excel generation
script_root = os.path.dirname(
os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
@@ -221,6 +222,7 @@ def extract_aml_data(root):
is_subnet_by_role = any("SUBNET" in rc.upper() for rc in role_classes)
if is_subnet_by_role:
is_network = True
+ # Check role classes first
for rc in role_classes:
rc_upper = rc.upper()
if "PROFINET" in rc_upper or "ETHERNET" in rc_upper:
@@ -229,12 +231,23 @@ def extract_aml_data(root):
elif "PROFIBUS" in rc_upper:
net_type = "Profibus"
break
+
+ # If still unknown, check the Type attribute (crucial for PROFINET)
+ if net_type == "Unknown":
+ type_attr = device.get("attributes", {}).get("Type", "")
+ if type_attr.upper() == "ETHERNET":
+ net_type = "Ethernet/Profinet"
+ elif type_attr.upper() == "PROFIBUS":
+ net_type = "Profibus"
+
+ # Finally, check device name as fallback
if net_type == "Unknown":
if "PROFIBUS" in device["name"].upper():
net_type = "Profibus"
elif (
"ETHERNET" in device["name"].upper()
or "PROFINET" in device["name"].upper()
+ or "PN/IE" in device["name"].upper() # Add common PROFINET naming pattern
):
net_type = "Ethernet/Profinet"
if is_network:
@@ -328,6 +341,33 @@ def extract_aml_data(root):
and interface_info["parent_id"] in data["plcs"]
):
potential_plc_id = interface_info["parent_id"]
+ # Enhanced PLC search: look for PLCs in the entire hierarchy
+ if not potential_plc_id:
+ # Search for PLCs in the hierarchy starting from linked_device_id
+ current_search_id = linked_device_id
+ search_depth = 0
+ max_search_depth = 10
+
+ while current_search_id and search_depth < max_search_depth:
+ # Check current device and all its children for PLCs
+ device_to_check = data["devices"].get(current_search_id)
+ if device_to_check:
+ # Check if current device has PLCs as children
+ for child_id in device_to_check.get("children_ids", []):
+ if child_id in data["plcs"]:
+ potential_plc_id = child_id
+ print(f" --> Found PLC in children: {data['plcs'][child_id].get('name', 'Unknown PLC')} (ID: {child_id})")
+ break
+
+ if potential_plc_id:
+ break
+
+ # Move up to parent
+ current_search_id = device_to_check.get("parent_id")
+ search_depth += 1
+ else:
+ break
+
if potential_plc_id:
plc_object = data["plcs"][potential_plc_id]
if "connected_networks" not in plc_object:
@@ -497,6 +537,337 @@ def generate_io_summary_file(all_plc_io_for_table, md_file_path, plc_name, proje
return hardware_file_path
+# --- generate_io_excel_report function ---
+def generate_io_excel_report(project_data, excel_file_path, target_plc_id, output_root_path):
+ """
+ Genera un archivo Excel con información detallada de IOs por nodos del PLC.
+ """
+
+ plc_info = project_data.get("plcs", {}).get(target_plc_id)
+ if not plc_info:
+ print(f"PLC ID '{target_plc_id}' not found in project data.")
+ return
+
+ plc_name = plc_info.get('name', target_plc_id)
+ print(f"Generating Excel IO report for PLC: {plc_name}")
+
+ # Lista para almacenar todas las filas del Excel
+ excel_rows = []
+
+ # Procesar las redes conectadas al PLC
+ plc_networks = plc_info.get("connected_networks", {})
+
+ if not plc_networks:
+ # Si no hay redes, crear una fila básica del PLC
+ excel_rows.append({
+ 'PLC Name': plc_name,
+ 'Network Path': 'No networks connected',
+ 'Network Type': 'N/A',
+ 'Device Address': 'N/A',
+ 'Device Name': plc_name,
+ 'Device Type': plc_info.get("type_name", "N/A"),
+ 'Order Number': plc_info.get("order_number", "N/A"),
+ 'Firmware Version': plc_info.get("firmware_version", "N/A"),
+ 'Position': plc_info.get("position", "N/A"),
+ 'IO Input Start Address': 'N/A',
+ 'IO Input End Address': 'N/A',
+ 'IO Output Start Address': 'N/A',
+ 'IO Output End Address': 'N/A',
+ 'Total Input Bits': 0,
+ 'Total Output Bits': 0,
+ 'Module Name': 'N/A',
+ 'Module Type': 'N/A',
+ 'Module Order Number': 'N/A'
+ })
+ else:
+ # Procesar cada red conectada
+ for net_id, plc_addr_on_net in plc_networks.items():
+ net_info = project_data.get("networks", {}).get(net_id)
+ if not net_info:
+ continue
+
+ network_name = net_info.get('name', net_id)
+ network_type = net_info.get('type', 'Unknown')
+ devices_on_net = net_info.get("devices_on_net", {})
+
+ # Identificar nodos que pertenecen al PLC para excluirlos de la lista de dispositivos
+ plc_interface_and_node_ids = set()
+ for node in plc_info.get("network_nodes", []):
+ plc_interface_and_node_ids.add(node["id"])
+ interface_id_lookup = project_data["devices"].get(node["id"], {}).get("parent_id")
+ if interface_id_lookup:
+ plc_interface_and_node_ids.add(interface_id_lookup)
+ plc_interface_and_node_ids.add(target_plc_id)
+
+ # Filtrar dispositivos que no son interfaces del PLC
+ other_devices = [
+ (node_id, node_addr)
+ for node_id, node_addr in devices_on_net.items()
+ if node_id not in plc_interface_and_node_ids
+ ]
+
+ if not other_devices:
+ # Si no hay otros dispositivos, crear fila solo para el PLC en esta red
+ excel_rows.append({
+ 'PLC Name': plc_name,
+ 'Network Path': f"{network_name} -> {plc_name}",
+ 'Network Type': network_type,
+ 'Device Address': plc_addr_on_net,
+ 'Device Name': plc_name,
+ 'Device Type': plc_info.get("type_name", "N/A"),
+ 'Order Number': plc_info.get("order_number", "N/A"),
+ 'Firmware Version': plc_info.get("firmware_version", "N/A"),
+ 'Position': plc_info.get("position", "N/A"),
+ 'IO Input Start Address': 'N/A',
+ 'IO Input End Address': 'N/A',
+ 'IO Output Start Address': 'N/A',
+ 'IO Output End Address': 'N/A',
+ 'Total Input Bits': 0,
+ 'Total Output Bits': 0,
+ 'Module Name': 'PLC Main Unit',
+ 'Module Type': plc_info.get("type_name", "N/A"),
+ 'Module Order Number': plc_info.get("order_number", "N/A")
+ })
+ else:
+ # Procesar cada dispositivo en la red
+ for node_id, node_addr in other_devices:
+ node_info = project_data.get("devices", {}).get(node_id)
+ if not node_info:
+ continue
+
+ # Determinar la estructura jerárquica del dispositivo
+ interface_id = node_info.get("parent_id")
+ interface_info = None
+ actual_device_id = None
+ actual_device_info = None
+
+ if interface_id:
+ interface_info = project_data.get("devices", {}).get(interface_id)
+ if interface_info:
+ actual_device_id = interface_info.get("parent_id")
+ if actual_device_id:
+ actual_device_info = project_data.get("devices", {}).get(actual_device_id)
+
+ # Determinar qué información mostrar
+ display_info = actual_device_info if actual_device_info else (interface_info if interface_info else node_info)
+ display_id = actual_device_id if actual_device_info else (interface_id if interface_info else node_id)
+
+ device_name = display_info.get("name", display_id)
+ device_type = display_info.get("type_name", "N/A")
+ device_order = display_info.get("order_number", "N/A")
+ device_position = display_info.get("position", "N/A")
+ firmware_version = display_info.get("firmware_version", "N/A")
+
+ # Construir el path de red
+ network_path = f"{network_name} ({network_type}) -> {device_name} @ {node_addr}"
+
+ # Buscar IOs recursivamente
+ io_search_root_id = display_id
+ io_search_root_info = project_data.get("devices", {}).get(io_search_root_id)
+
+ aggregated_io_addresses = []
+
+ # Buscar IOs en la estructura padre si existe
+ parent_structure_id = io_search_root_info.get("parent_id") if io_search_root_info else None
+
+ if parent_structure_id:
+ # Buscar IOs en dispositivos hermanos bajo la misma estructura padre
+ for dev_scan_id, dev_scan_info in project_data.get("devices", {}).items():
+ if dev_scan_info.get("parent_id") == parent_structure_id:
+ module_context = {
+ "id": dev_scan_id,
+ "name": dev_scan_info.get("name", dev_scan_id),
+ "order_number": dev_scan_info.get("order_number", "N/A"),
+ "type_name": dev_scan_info.get("type_name", "N/A")
+ }
+ io_from_sibling = find_io_recursively(dev_scan_id, project_data, module_context)
+ aggregated_io_addresses.extend(io_from_sibling)
+ elif io_search_root_id:
+ # Buscar IOs directamente en el dispositivo
+ module_context = {
+ "id": io_search_root_id,
+ "name": io_search_root_info.get("name", io_search_root_id),
+ "order_number": io_search_root_info.get("order_number", "N/A"),
+ "type_name": io_search_root_info.get("type_name", "N/A")
+ }
+ aggregated_io_addresses = find_io_recursively(io_search_root_id, project_data, module_context)
+
+ # Procesar IOs por módulo
+ if aggregated_io_addresses:
+ # Agrupar IOs por módulo
+ ios_by_module = {}
+ for addr_info in aggregated_io_addresses:
+ module_id = addr_info.get("module_id")
+ if module_id not in ios_by_module:
+ ios_by_module[module_id] = {
+ 'module_info': {
+ 'name': addr_info.get('module_name', '?'),
+ 'type': addr_info.get('module_type_name', 'N/A'),
+ 'order': addr_info.get('module_order_number', 'N/A'),
+ 'position': addr_info.get('module_pos', 'N/A')
+ },
+ 'inputs': [],
+ 'outputs': []
+ }
+
+ # Clasificar IO como input u output
+ io_type = addr_info.get("type", "").lower()
+ if io_type == "input":
+ ios_by_module[module_id]['inputs'].append(addr_info)
+ elif io_type == "output":
+ ios_by_module[module_id]['outputs'].append(addr_info)
+
+ # Crear una fila por cada módulo con IOs
+ for module_id, module_data in ios_by_module.items():
+ module_info = module_data['module_info']
+
+ # Calcular direcciones de entrada - formato simplificado
+ input_start_addr = 'N/A'
+ input_end_addr = 'N/A'
+ total_input_bits = 0
+
+ for addr_info in module_data['inputs']:
+ start_str = addr_info.get("start", "?")
+ length_str = addr_info.get("length", "?")
+ try:
+ start_byte = int(start_str)
+ length_bits = int(length_str)
+ length_bytes = math.ceil(length_bits / 8.0)
+ if length_bits > 0 and length_bytes == 0:
+ length_bytes = 1
+ end_byte = start_byte + length_bytes - 1
+
+ # Para múltiples rangos, tomar el primer inicio y último fin
+ if input_start_addr == 'N/A':
+ input_start_addr = start_byte
+ input_end_addr = end_byte
+ else:
+ input_start_addr = min(input_start_addr, start_byte)
+ input_end_addr = max(input_end_addr, end_byte)
+
+ total_input_bits += length_bits
+ except:
+ # En caso de error, mantener N/A
+ pass
+
+ # Calcular direcciones de salida - formato simplificado
+ output_start_addr = 'N/A'
+ output_end_addr = 'N/A'
+ total_output_bits = 0
+
+ for addr_info in module_data['outputs']:
+ start_str = addr_info.get("start", "?")
+ length_str = addr_info.get("length", "?")
+ try:
+ start_byte = int(start_str)
+ length_bits = int(length_str)
+ length_bytes = math.ceil(length_bits / 8.0)
+ if length_bits > 0 and length_bytes == 0:
+ length_bytes = 1
+ end_byte = start_byte + length_bytes - 1
+
+ # Para múltiples rangos, tomar el primer inicio y último fin
+ if output_start_addr == 'N/A':
+ output_start_addr = start_byte
+ output_end_addr = end_byte
+ else:
+ output_start_addr = min(output_start_addr, start_byte)
+ output_end_addr = max(output_end_addr, end_byte)
+
+ total_output_bits += length_bits
+ except:
+ # En caso de error, mantener N/A
+ pass
+
+ excel_rows.append({
+ 'PLC Name': plc_name,
+ 'Network Path': network_path,
+ 'Network Type': network_type,
+ 'Device Address': node_addr,
+ 'Device Name': device_name,
+ 'Device Type': device_type,
+ 'Order Number': device_order,
+ 'Firmware Version': firmware_version,
+ 'Position': device_position,
+ 'IO Input Start Address': input_start_addr,
+ 'IO Input End Address': input_end_addr,
+ 'IO Output Start Address': output_start_addr,
+ 'IO Output End Address': output_end_addr,
+ 'Total Input Bits': total_input_bits,
+ 'Total Output Bits': total_output_bits,
+ 'Module Name': module_info['name'],
+ 'Module Type': module_info['type'],
+ 'Module Order Number': module_info['order']
+ })
+ else:
+ # Dispositivo sin IOs
+ excel_rows.append({
+ 'PLC Name': plc_name,
+ 'Network Path': network_path,
+ 'Network Type': network_type,
+ 'Device Address': node_addr,
+ 'Device Name': device_name,
+ 'Device Type': device_type,
+ 'Order Number': device_order,
+ 'Firmware Version': firmware_version,
+ 'Position': device_position,
+ 'IO Input Start Address': 'N/A',
+ 'IO Input End Address': 'N/A',
+ 'IO Output Start Address': 'N/A',
+ 'IO Output End Address': 'N/A',
+ 'Total Input Bits': 0,
+ 'Total Output Bits': 0,
+ 'Module Name': 'N/A',
+ 'Module Type': 'N/A',
+ 'Module Order Number': 'N/A'
+ })
+
+ # Crear DataFrame y guardar Excel
+ if excel_rows:
+ df = pd.DataFrame(excel_rows)
+
+ # Agregar columna de ID único para compatibilidad con x7_update_CAx
+ df['Unique_ID'] = df['PLC Name'] + "+" + df['Device Name']
+
+ # Reordenar columnas para mejor legibilidad
+ column_order = [
+ 'PLC Name', 'Network Path', 'Network Type', 'Device Address', 'Device Name',
+ 'Device Type', 'Order Number', 'Firmware Version', 'Position',
+ 'Module Name', 'Module Type', 'Module Order Number',
+ 'IO Input Start Address', 'IO Input End Address', 'IO Output Start Address', 'IO Output End Address',
+ 'Total Input Bits', 'Total Output Bits', 'Unique_ID' # Agregar al final para compatibilidad
+ ]
+ df = df.reindex(columns=column_order)
+
+ try:
+ # Guardar como Excel con formato
+ with pd.ExcelWriter(excel_file_path, engine='openpyxl') as writer:
+ df.to_excel(writer, sheet_name='IO Report', index=False)
+
+ # Ajustar ancho de columnas
+ worksheet = writer.sheets['IO Report']
+ for column in worksheet.columns:
+ max_length = 0
+ column_letter = column[0].column_letter
+ for cell in column:
+ try:
+ if len(str(cell.value)) > max_length:
+ max_length = len(str(cell.value))
+ except:
+ pass
+ adjusted_width = min(max_length + 2, 50) # Máximo 50 caracteres
+ worksheet.column_dimensions[column_letter].width = adjusted_width
+
+ print(f"Excel IO report saved to: {excel_file_path}")
+ print(f"Total rows in report: {len(excel_rows)}")
+
+ except Exception as e:
+ print(f"ERROR saving Excel file {excel_file_path}: {e}")
+ traceback.print_exc()
+ else:
+ print("No data to write to Excel file.")
+
+
# --- generate_markdown_tree function ---
def generate_markdown_tree(project_data, md_file_path, target_plc_id, output_root_path):
"""(Modified) Generates hierarchical Markdown for a specific PLC."""
@@ -1151,25 +1522,34 @@ def sanitize_filename(name):
# --- Main Execution ---
if __name__ == "__main__":
- configs = load_configuration()
- working_directory = configs.get("working_directory")
+ try:
+ configs = load_configuration()
+ working_directory = configs.get("working_directory")
+ except Exception as e:
+ print(f"Warning: Could not load configuration (frontend not running): {e}")
+ configs = {}
+ working_directory = None
- script_version = "v31.1 - Corrected IO Summary Table Initialization" # Updated version
+ script_version = "v32.2 - Simplified IO Address Format (Separate Start/End)" # Updated version
print(
f"--- AML (CAx Export) to Hierarchical JSON and Obsidian MD Converter ({script_version}) ---"
)
- # Validate working directory
+ # Validate working directory with .debug fallback
if not working_directory or not os.path.isdir(working_directory):
- print("ERROR: Working directory not set or invalid in configuration.")
- print("Attempting to use script's directory as fallback.")
- # Fallback to script's directory or current directory if needed
- working_directory = os.path.dirname(os.path.abspath(__file__))
- if not os.path.isdir(working_directory):
- working_directory = os.getcwd()
- print(f"Using fallback directory: {working_directory}")
- # Optionally, prompt user to select a working directory here if critical
- # output_dir = select_output_directory() # Keep this if you want user selection on failure
+ print("Working directory not set or invalid in configuration.")
+ print("Using .debug directory as fallback for direct script execution.")
+
+ # Fallback to .debug directory under script location
+ script_dir = os.path.dirname(os.path.abspath(__file__))
+ debug_dir = os.path.join(script_dir, ".debug")
+
+ # Create .debug directory if it doesn't exist
+ os.makedirs(debug_dir, exist_ok=True)
+ working_directory = debug_dir
+ print(f"Using debug directory: {working_directory}")
+ else:
+ print(f"Using configured working directory: {working_directory}")
# Use working_directory as the output directory
output_dir = working_directory
@@ -1227,6 +1607,12 @@ if __name__ == "__main__":
print(f" Generating Hardware Tree for PLC '{plc_name_original}' (ID: {plc_id}) at: {output_plc_md_file.resolve()}")
# Pass output_path as the root directory for Hardware.md placement
generate_markdown_tree(project_data, str(output_plc_md_file), plc_id, str(output_path))
+
+ # Generate Excel IO report for this PLC
+ excel_io_filename = f"{input_path.stem}_IO_Report.xlsx"
+ output_excel_file = plc_doc_dir / excel_io_filename
+ print(f" Generating Excel IO Report for PLC '{plc_name_original}' (ID: {plc_id}) at: {output_excel_file.resolve()}")
+ generate_io_excel_report(project_data, str(output_excel_file), plc_id, str(output_path))
else:
print("\nFailed to process AML data. Halting before generating PLC-specific trees.")
diff --git a/backend/script_groups/IO_adaptation/x7_update_CAx.py b/backend/script_groups/IO_adaptation/x7_update_CAx.py
new file mode 100644
index 0000000..3422453
--- /dev/null
+++ b/backend/script_groups/IO_adaptation/x7_update_CAx.py
@@ -0,0 +1,619 @@
+"""
+x7_update_CAx.py : Script que actualiza un archivo AML original basándose en las modificaciones
+hechas en el archivo Excel de IOs generado por x2_process_CAx.py
+
+Pipeline:
+1. Lee el AML original
+2. Lee el Excel modificado
+3. Genera Excel de referencia desde el AML para comparar
+4. Valida que la estructura base sea la misma (mismos nodos, nombres)
+5. Identifica cambios en IOs, direcciones IP, etc.
+6. Aplica los cambios al AML original
+7. Genera un nuevo archivo AML con sufijo "_updated"
+"""
+
+import os
+import sys
+import tkinter as tk
+from tkinter import filedialog, messagebox
+import traceback
+from lxml import etree as ET
+import pandas as pd
+from pathlib import Path
+import re
+import math
+import tempfile
+
+script_root = os.path.dirname(
+ os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
+)
+sys.path.append(script_root)
+from backend.script_utils import load_configuration
+
+# Import functions from x2_process_CAx
+from x2_process_CAx import (
+ extract_aml_data,
+ generate_io_excel_report,
+ sanitize_filename
+)
+
+
+def select_aml_file(title="Select Original AML File", initial_dir=None):
+ """Abre un diálogo para seleccionar un archivo AML."""
+ root = tk.Tk()
+ root.withdraw()
+ file_path = filedialog.askopenfilename(
+ title=title,
+ filetypes=[("AML Files", "*.aml"), ("All Files", "*.*")],
+ initialdir=initial_dir
+ )
+ root.destroy()
+ if not file_path:
+ return None
+ return file_path
+
+
+def select_excel_file(title="Select Modified Excel File", initial_dir=None):
+ """Abre un diálogo para seleccionar un archivo Excel."""
+ root = tk.Tk()
+ root.withdraw()
+ file_path = filedialog.askopenfilename(
+ title=title,
+ filetypes=[("Excel Files", "*.xlsx"), ("Excel Files", "*.xls"), ("All Files", "*.*")],
+ initialdir=initial_dir
+ )
+ root.destroy()
+ if not file_path:
+ return None
+ return file_path
+
+
+def generate_reference_excel_from_aml(aml_file_path, temp_dir):
+ """
+ Genera un Excel de referencia desde el AML para comparar con el Excel modificado.
+ Retorna el path al Excel generado y los project_data.
+ """
+ print("Generando Excel de referencia desde AML original...")
+
+ # Extraer datos del AML
+ try:
+ parser = ET.XMLParser(remove_blank_text=True, huge_tree=True)
+ tree = ET.parse(aml_file_path, parser)
+ root = tree.getroot()
+ project_data = extract_aml_data(root)
+ except Exception as e:
+ print(f"ERROR procesando archivo AML {aml_file_path}: {e}")
+ return None, None
+
+ if not project_data or not project_data.get("plcs"):
+ print("No se encontraron PLCs en el archivo AML.")
+ return None, None
+
+ # Generar Excel para cada PLC y combinar en uno solo
+ all_excel_rows = []
+
+ for plc_id, plc_data in project_data.get("plcs", {}).items():
+ # Crear archivo temporal para este PLC
+ temp_excel_path = os.path.join(temp_dir, f"temp_plc_{plc_id}.xlsx")
+
+ # Generar Excel para este PLC (reutilizamos la función existente)
+ generate_io_excel_report(project_data, temp_excel_path, plc_id, temp_dir)
+
+ # Leer el Excel generado y agregar a la lista combinada
+ if os.path.exists(temp_excel_path):
+ try:
+ df_plc = pd.read_excel(temp_excel_path, sheet_name='IO Report')
+ # Agregar columna de ID único
+ df_plc['Unique_ID'] = df_plc['PLC Name'] + "+" + df_plc['Device Name']
+ all_excel_rows.append(df_plc)
+ os.remove(temp_excel_path) # Limpiar archivo temporal
+ except Exception as e:
+ print(f"ERROR leyendo Excel temporal para PLC {plc_id}: {e}")
+
+ if not all_excel_rows:
+ print("No se pudieron generar datos de Excel de referencia.")
+ return None, None
+
+ # Combinar todos los DataFrames
+ combined_df = pd.concat(all_excel_rows, ignore_index=True)
+
+ # Guardar Excel de referencia
+ reference_excel_path = os.path.join(temp_dir, "reference_excel.xlsx")
+ combined_df.to_excel(reference_excel_path, sheet_name='IO Report', index=False)
+
+ return reference_excel_path, project_data
+
+
+def compare_excel_files(reference_excel_path, modified_excel_path):
+ """
+ Compara el Excel de referencia con el Excel modificado.
+ Retorna (is_valid, changes_dict) donde:
+ - is_valid: True si la estructura básica es la misma
+ - changes_dict: diccionario con los cambios detectados
+ """
+ print("Comparando archivos Excel...")
+
+ try:
+ # Leer ambos archivos
+ df_ref = pd.read_excel(reference_excel_path, sheet_name='IO Report')
+ df_mod = pd.read_excel(modified_excel_path, sheet_name='IO Report')
+
+ # Agregar columna de ID único si no existe
+ if 'Unique_ID' not in df_ref.columns:
+ df_ref['Unique_ID'] = df_ref['PLC Name'] + "+" + df_ref['Device Name']
+ if 'Unique_ID' not in df_mod.columns:
+ df_mod['Unique_ID'] = df_mod['PLC Name'] + "+" + df_mod['Device Name']
+
+ except Exception as e:
+ print(f"ERROR leyendo archivos Excel: {e}")
+ return False, {}
+
+ # Validar estructura básica
+ if len(df_ref) != len(df_mod):
+ print(f"ERROR: Número de filas diferente. Referencia: {len(df_ref)}, Modificado: {len(df_mod)}")
+ return False, {}
+
+ # Verificar que todos los IDs únicos coincidan
+ ref_ids = set(df_ref['Unique_ID'].tolist())
+ mod_ids = set(df_mod['Unique_ID'].tolist())
+
+ if ref_ids != mod_ids:
+ missing_in_mod = ref_ids - mod_ids
+ extra_in_mod = mod_ids - ref_ids
+ print("ERROR: Los IDs únicos no coinciden entre archivos.")
+ if missing_in_mod:
+ print(f" Faltantes en modificado: {missing_in_mod}")
+ if extra_in_mod:
+ print(f" Extras en modificado: {extra_in_mod}")
+ return False, {}
+
+ print("Estructura básica validada correctamente.")
+
+ # Detectar cambios
+ changes = {}
+ columns_to_monitor = [
+ 'Device Address', 'IO Input Start Address', 'IO Input End Address',
+ 'IO Output Start Address', 'IO Output End Address',
+ 'Network Type', 'Device Type', 'Order Number', 'Firmware Version'
+ ]
+
+ for index, row_ref in df_ref.iterrows():
+ unique_id = row_ref['Unique_ID']
+ row_mod = df_mod[df_mod['Unique_ID'] == unique_id].iloc[0]
+
+ row_changes = {}
+ for col in columns_to_monitor:
+ if col in df_ref.columns and col in df_mod.columns:
+ ref_val = str(row_ref[col]).strip() if pd.notna(row_ref[col]) else 'N/A'
+ mod_val = str(row_mod[col]).strip() if pd.notna(row_mod[col]) else 'N/A'
+
+ if ref_val != mod_val:
+ row_changes[col] = {
+ 'original': ref_val,
+ 'modified': mod_val
+ }
+
+ if row_changes:
+ changes[unique_id] = {
+ 'plc_name': row_ref['PLC Name'],
+ 'device_name': row_ref['Device Name'],
+ 'changes': row_changes
+ }
+
+ print(f"Detectados {len(changes)} dispositivos con cambios.")
+ for unique_id, change_info in changes.items():
+ print(f" {unique_id}: {list(change_info['changes'].keys())}")
+
+ return True, changes
+
+
+def find_device_in_aml(project_data, plc_name, device_name):
+ """
+ Encuentra el device_id correspondiente en los datos del AML basándose en PLC y device name.
+ """
+ # Buscar el PLC por nombre
+ target_plc_id = None
+ for plc_id, plc_data in project_data.get("plcs", {}).items():
+ if plc_data.get('name', plc_id) == plc_name:
+ target_plc_id = plc_id
+ break
+
+ if not target_plc_id:
+ return None
+
+ # Buscar el dispositivo en las redes del PLC
+ plc_info = project_data["plcs"][target_plc_id]
+ plc_networks = plc_info.get("connected_networks", {})
+
+ for net_id, plc_addr_on_net in plc_networks.items():
+ net_info = project_data.get("networks", {}).get(net_id)
+ if not net_info:
+ continue
+
+ devices_on_net = net_info.get("devices_on_net", {})
+
+ # Identificar nodos que pertenecen al PLC
+ plc_interface_and_node_ids = set()
+ for node in plc_info.get("network_nodes", []):
+ plc_interface_and_node_ids.add(node["id"])
+ interface_id_lookup = project_data["devices"].get(node["id"], {}).get("parent_id")
+ if interface_id_lookup:
+ plc_interface_and_node_ids.add(interface_id_lookup)
+ plc_interface_and_node_ids.add(target_plc_id)
+
+ # Buscar en dispositivos de la red
+ for node_id, node_addr in devices_on_net.items():
+ if node_id in plc_interface_and_node_ids:
+ continue
+
+ node_info = project_data.get("devices", {}).get(node_id)
+ if not node_info:
+ continue
+
+ # Determinar información del dispositivo
+ interface_id = node_info.get("parent_id")
+ interface_info = None
+ actual_device_id = None
+ actual_device_info = None
+
+ if interface_id:
+ interface_info = project_data.get("devices", {}).get(interface_id)
+ if interface_info:
+ actual_device_id = interface_info.get("parent_id")
+ if actual_device_id:
+ actual_device_info = project_data.get("devices", {}).get(actual_device_id)
+
+ display_info = actual_device_info if actual_device_info else (interface_info if interface_info else node_info)
+ display_name = display_info.get("name", "Unknown")
+
+ if display_name == device_name:
+ return {
+ 'node_id': node_id,
+ 'display_id': actual_device_id if actual_device_info else (interface_id if interface_info else node_id),
+ 'node_info': node_info,
+ 'display_info': display_info,
+ 'network_id': net_id
+ }
+
+ return None
+
+
+def apply_changes_to_aml(aml_tree, project_data, changes_dict):
+ """
+ Aplica los cambios detectados al árbol XML del AML.
+ """
+ print("Aplicando cambios al archivo AML...")
+
+ root = aml_tree.getroot()
+ changes_applied = 0
+
+ for unique_id, change_info in changes_dict.items():
+ plc_name = change_info['plc_name']
+ device_name = change_info['device_name']
+ changes = change_info['changes']
+
+ print(f" Procesando cambios para: {unique_id}")
+
+ # Encontrar el dispositivo en los datos del AML
+ device_info = find_device_in_aml(project_data, plc_name, device_name)
+ if not device_info:
+ print(f" ERROR: No se pudo encontrar el dispositivo en el AML")
+ continue
+
+ # Encontrar el elemento XML correspondiente
+ device_id = device_info['node_id']
+ xml_element = root.xpath(f".//*[@ID='{device_id}']")
+
+ if not xml_element:
+ print(f" ERROR: No se pudo encontrar el elemento XML con ID {device_id}")
+ continue
+
+ device_element = xml_element[0]
+
+ # Aplicar cambios específicos
+ for field, change_data in changes.items():
+ original_val = change_data['original']
+ modified_val = change_data['modified']
+
+ if field == 'Device Address':
+ # Cambiar dirección de red del dispositivo
+ if apply_network_address_change(device_element, modified_val):
+ print(f" ✓ Dirección de red actualizada: {original_val} -> {modified_val}")
+ changes_applied += 1
+ else:
+ print(f" ✗ Error actualizando dirección de red")
+
+ elif field in ['IO Input Start Address', 'IO Input End Address', 'IO Output Start Address', 'IO Output End Address']:
+ # Cambiar direcciones IO específicas
+ if apply_io_address_change(device_element, field, original_val, modified_val, project_data, device_id):
+ print(f" ✓ {field} actualizada: {original_val} -> {modified_val}")
+ changes_applied += 1
+ else:
+ print(f" ✗ Error actualizando {field}")
+
+ elif field in ['Device Type', 'Order Number', 'Firmware Version']:
+ # Cambiar atributos del dispositivo
+ if apply_device_attribute_change(device_element, field, modified_val):
+ print(f" ✓ {field} actualizado: {original_val} -> {modified_val}")
+ changes_applied += 1
+ else:
+ print(f" ✗ Error actualizando {field}")
+
+ print(f"Total de cambios aplicados: {changes_applied}")
+ return changes_applied > 0
+
+
+def apply_network_address_change(device_element, new_address):
+ """
+ Aplica cambio de dirección de red a un elemento del dispositivo.
+ """
+ try:
+ # Buscar atributo NetworkAddress
+ addr_attr = device_element.xpath("./*[local-name()='Attribute'][@Name='NetworkAddress']")
+ if addr_attr:
+ value_elem = addr_attr[0].xpath("./*[local-name()='Value']")
+ if value_elem:
+ value_elem[0].text = new_address
+ return True
+
+ # Si no existe, crear el atributo
+ attr_elem = ET.SubElement(device_element, "Attribute")
+ attr_elem.set("Name", "NetworkAddress")
+ value_elem = ET.SubElement(attr_elem, "Value")
+ value_elem.text = new_address
+ return True
+
+ except Exception as e:
+ print(f" Error aplicando cambio de dirección: {e}")
+ return False
+
+
+def apply_device_attribute_change(device_element, field, new_value):
+ """
+ Aplica cambio de atributo del dispositivo.
+ """
+ try:
+ # Mapear campos a nombres de atributos XML
+ attr_mapping = {
+ 'Device Type': 'TypeName',
+ 'Order Number': 'OrderNumber',
+ 'Firmware Version': 'FirmwareVersion'
+ }
+
+ attr_name = attr_mapping.get(field)
+ if not attr_name:
+ return False
+
+ # Buscar atributo existente
+ attr_elem = device_element.xpath(f"./*[local-name()='Attribute'][@Name='{attr_name}']")
+ if attr_elem:
+ value_elem = attr_elem[0].xpath("./*[local-name()='Value']")
+ if value_elem:
+ value_elem[0].text = new_value
+ return True
+
+ # Si no existe, crear el atributo
+ attr_elem = ET.SubElement(device_element, "Attribute")
+ attr_elem.set("Name", attr_name)
+ value_elem = ET.SubElement(attr_elem, "Value")
+ value_elem.text = new_value
+ return True
+
+ except Exception as e:
+ print(f" Error aplicando cambio de atributo {field}: {e}")
+ return False
+
+
+def apply_io_address_change(device_element, field, original_val, modified_val, project_data, device_id):
+ """
+ Aplica cambios a las direcciones IO individuales. Ahora es más simple
+ porque las direcciones están separadas en campos específicos.
+ """
+ try:
+ # Validar que el nuevo valor sea numérico o N/A
+ if modified_val != 'N/A' and modified_val != '':
+ try:
+ new_addr_value = int(modified_val)
+ except ValueError:
+ print(f" Error: Valor de dirección no válido: {modified_val}")
+ return False
+ else:
+ # Si es N/A, no hay dirección IO para este tipo
+ return True
+
+ # Determinar tipo de IO y si es start o end
+ is_input = "Input" in field
+ is_start = "Start" in field
+ io_type = "Input" if is_input else "Output"
+
+ # Buscar la estructura IO en el dispositivo
+ # Esto requiere encontrar los elementos Address y sus sub-atributos
+ address_elements = device_element.xpath("./*[local-name()='Attribute'][@Name='Address']")
+
+ if not address_elements:
+ print(f" No se encontró elemento Address en el dispositivo")
+ return False
+
+ # Buscar dentro del Address el sub-atributo correcto
+ address_element = address_elements[0]
+ io_subelements = address_element.xpath(f"./*[local-name()='Attribute']")
+
+ target_io_element = None
+ for io_sub in io_subelements:
+ # Verificar si es el tipo correcto (Input/Output)
+ type_val = io_sub.xpath("./*[local-name()='Attribute'][@Name='IoType']/*[local-name()='Value']/text()")
+ if type_val and type_val[0].lower() == io_type.lower():
+ target_io_element = io_sub
+ break
+
+ if not target_io_element:
+ print(f" No se encontró elemento {io_type} en Address")
+ return False
+
+ # Actualizar StartAddress o calcular Length según el campo
+ if is_start:
+ # Actualizar StartAddress
+ start_attr = target_io_element.xpath("./*[local-name()='Attribute'][@Name='StartAddress']")
+ if start_attr:
+ value_elem = start_attr[0].xpath("./*[local-name()='Value']")
+ if value_elem:
+ value_elem[0].text = str(new_addr_value)
+ return True
+ else:
+ # Crear StartAddress si no existe
+ start_attr_elem = ET.SubElement(target_io_element, "Attribute")
+ start_attr_elem.set("Name", "StartAddress")
+ value_elem = ET.SubElement(start_attr_elem, "Value")
+ value_elem.text = str(new_addr_value)
+ return True
+ else:
+ # Es End Address - necesitamos calcular Length basándose en Start y End
+ # Primero obtener StartAddress
+ start_attr = target_io_element.xpath("./*[local-name()='Attribute'][@Name='StartAddress']/*[local-name()='Value']/text()")
+ if start_attr:
+ try:
+ start_value = int(start_attr[0])
+ # Length en bytes = (end - start + 1)
+ length_bytes = new_addr_value - start_value + 1
+ if length_bytes > 0:
+ # Convertir a bits (asumiendo 8 bits por byte)
+ length_bits = length_bytes * 8
+
+ # Actualizar Length
+ length_attr = target_io_element.xpath("./*[local-name()='Attribute'][@Name='Length']")
+ if length_attr:
+ value_elem = length_attr[0].xpath("./*[local-name()='Value']")
+ if value_elem:
+ value_elem[0].text = str(length_bits)
+ return True
+ else:
+ # Crear Length si no existe
+ length_attr_elem = ET.SubElement(target_io_element, "Attribute")
+ length_attr_elem.set("Name", "Length")
+ value_elem = ET.SubElement(length_attr_elem, "Value")
+ value_elem.text = str(length_bits)
+ return True
+ else:
+ print(f" Error: End address ({new_addr_value}) debe ser mayor que start address ({start_value})")
+ return False
+ except ValueError:
+ print(f" Error: No se pudo convertir start address: {start_attr[0]}")
+ return False
+ else:
+ print(f" Error: No se encontró StartAddress para calcular Length")
+ return False
+
+ return False
+
+ except Exception as e:
+ print(f" Error aplicando cambio de dirección IO {field}: {e}")
+ traceback.print_exc()
+ return False
+
+
+def save_updated_aml(aml_tree, original_aml_path):
+ """
+ Guarda el árbol XML modificado como un nuevo archivo AML con sufijo "_updated".
+ """
+ original_path = Path(original_aml_path)
+ updated_path = original_path.parent / f"{original_path.stem}_updated{original_path.suffix}"
+
+ try:
+ # Escribir el XML actualizado
+ aml_tree.write(
+ str(updated_path),
+ pretty_print=True,
+ xml_declaration=True,
+ encoding='utf-8'
+ )
+ print(f"Archivo AML actualizado guardado en: {updated_path}")
+ return str(updated_path)
+
+ except Exception as e:
+ print(f"ERROR guardando archivo AML actualizado: {e}")
+ return None
+
+
+def main():
+ """Función principal del script."""
+ try:
+ configs = load_configuration()
+ working_directory = configs.get("working_directory")
+ except Exception as e:
+ print(f"Warning: No se pudo cargar configuración: {e}")
+ configs = {}
+ working_directory = None
+
+ script_version = "v1.1 - Simplified IO Address Handling (Start/End Separated)"
+ print(f"--- Actualizador de AML desde Excel Modificado ({script_version}) ---")
+
+ # Validar directorio de trabajo
+ if not working_directory or not os.path.isdir(working_directory):
+ print("Directorio de trabajo no configurado. Usando directorio actual.")
+ working_directory = os.getcwd()
+
+ print(f"Directorio de trabajo: {working_directory}")
+
+ # 1. Seleccionar archivo AML original
+ print("\n1. Seleccione el archivo AML original:")
+ aml_file_path = select_aml_file(initial_dir=working_directory)
+ if not aml_file_path:
+ print("No se seleccionó archivo AML. Saliendo.")
+ return
+
+ # 2. Seleccionar archivo Excel modificado
+ print("\n2. Seleccione el archivo Excel modificado:")
+ excel_file_path = select_excel_file(initial_dir=working_directory)
+ if not excel_file_path:
+ print("No se seleccionó archivo Excel. Saliendo.")
+ return
+
+ print(f"\nArchivo AML original: {aml_file_path}")
+ print(f"Archivo Excel modificado: {excel_file_path}")
+
+ # 3. Crear directorio temporal para archivos intermedios
+ with tempfile.TemporaryDirectory() as temp_dir:
+ print(f"\nUsando directorio temporal: {temp_dir}")
+
+ # 4. Generar Excel de referencia desde AML
+ reference_excel_path, project_data = generate_reference_excel_from_aml(aml_file_path, temp_dir)
+ if not reference_excel_path or not project_data:
+ print("ERROR: No se pudo generar Excel de referencia.")
+ return
+
+ # 5. Comparar archivos Excel
+ is_valid, changes_dict = compare_excel_files(reference_excel_path, excel_file_path)
+ if not is_valid:
+ print("ERROR: El archivo Excel modificado no es compatible con el AML original.")
+ return
+
+ if not changes_dict:
+ print("No se detectaron cambios en el Excel. No hay nada que actualizar.")
+ return
+
+ # 6. Cargar y parsear AML original
+ print("\nCargando archivo AML original...")
+ try:
+ parser = ET.XMLParser(remove_blank_text=True, huge_tree=True)
+ aml_tree = ET.parse(aml_file_path, parser)
+ except Exception as e:
+ print(f"ERROR parseando archivo AML: {e}")
+ return
+
+ # 7. Aplicar cambios al AML
+ success = apply_changes_to_aml(aml_tree, project_data, changes_dict)
+ if not success:
+ print("No se pudieron aplicar cambios al AML.")
+ return
+
+ # 8. Guardar AML actualizado
+ updated_aml_path = save_updated_aml(aml_tree, aml_file_path)
+ if updated_aml_path:
+ print(f"\n¡Proceso completado exitosamente!")
+ print(f"Archivo AML actualizado: {updated_aml_path}")
+ else:
+ print("ERROR: No se pudo guardar el archivo AML actualizado.")
+
+
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/data/log.txt b/data/log.txt
index 6d68b34..8767003 100644
--- a/data/log.txt
+++ b/data/log.txt
@@ -1,82 +1,5 @@
-[16:30:18] Iniciando ejecución de x1_export_CAx.py en D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia...
-[16:30:19] --- TIA Portal Project CAx Exporter and Analyzer ---
-[16:30:24] Selected Project: D:/Trabajo/VM/44 - 98050 - Fiera/InLavoro/PLC/98050_PLC_01/98050_PLC_01.ap19
-[16:30:24] Using Output Directory (Working Directory): D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia
-[16:30:24] Detected TIA Portal version: 19.0 (from extension .ap19)
-[16:30:24] Will export CAx data to: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\98050_PLC_01_CAx_Export.aml
-[16:30:24] Will generate summary to: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\98050_PLC_01_CAx_Summary.md
-[16:30:24] Export log file: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\98050_PLC_01_CAx_Export.log
-[16:30:24] Connecting to TIA Portal V19.0...
-[16:30:25] 2025-06-06 16:30:25,861 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Global OpenPortal - Start TIA Portal, please acknowledge the security dialog.
-[16:30:25] 2025-06-06 16:30:25,895 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Global OpenPortal - With user interface
-[16:32:34] Connected.
-[16:32:34] Opening project: 98050_PLC_01.ap19...
-[16:32:34] 2025-06-06 16:32:34,404 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Portal OpenProject - Open project... D:\Trabajo\VM\44 - 98050 - Fiera\InLavoro\PLC\98050_PLC_01\98050_PLC_01.ap19
-[16:33:05] Project opened.
-[16:33:05] Exporting CAx data for the project to D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\98050_PLC_01_CAx_Export.aml...
-[16:33:52] CAx data exported successfully.
-[16:33:52] Closing TIA Portal...
-[16:33:52] 2025-06-06 16:33:52,008 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Portal ClosePortal - Close TIA Portal
-[16:33:52] TIA Portal closed.
-[16:33:52] Parsing AML file: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\98050_PLC_01_CAx_Export.aml
-[16:33:52] Markdown summary written to: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\98050_PLC_01_CAx_Summary.md
-[16:33:52] Script finished.
-[16:33:55] Ejecución de x1_export_CAx.py finalizada (success). Duración: 0:03:37.052535.
-[16:33:55] Log completo guardado en: D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\IO_adaptation\log_x1_export_CAx.txt
-[16:34:01] Iniciando ejecución de x2_process_CAx.py en D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia...
-[16:34:01] --- AML (CAx Export) to Hierarchical JSON and Obsidian MD Converter (v31.1 - Corrected IO Summary Table Initialization) ---
-[16:34:01] Using Working Directory for Output: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia
-[16:34:09] Input AML: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\98050_PLC_01_CAx_Export.aml
-[16:34:09] Output Directory: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia
-[16:34:09] Output JSON: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\98050_PLC_01_CAx_Export.hierarchical.json
-[16:34:09] Output IO Debug Tree MD: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\98050_PLC_01_CAx_Export_IO_Upward_Debug.md
-[16:34:09] Processing AML file: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\98050_PLC_01_CAx_Export.aml
-[16:34:09] Pass 1: Found 363 InternalElement(s). Populating device dictionary...
-[16:34:09] Pass 2: Identifying PLCs and Networks (Refined v2)...
-[16:34:09] Identified Network: PN/IE_1 (fcbafb48-c53d-4af5-8143-794df99be4d6) Type: Unknown
-[16:34:09] Identified PLC: A40510 (fc0d3bac-267e-488a-8dcf-7dc8599d80e8) - Type: CPU 1514SP T-2 PN OrderNo: 6ES7 514-2VN03-0AB0
-[16:34:09] Pass 3: Processing InternalLinks (Robust Network Mapping & IO)...
-[16:34:09] Found 103 InternalLink(s).
-[16:34:09] Mapping Device/Node 'E1' (NodeID:ffef8b7b-b6bf-46aa-b3b5-f5083c420563, Addr:10.1.30.11) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:221c248d-83d8-464c-9425-c949086b34e7, Addr:10.1.30.58) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:5c3bf795-ecec-47e7-a962-4d54c95b9887, Addr:10.1.30.59) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:4100c829-d889-489a-971c-a69207333e2f, Addr:10.1.30.60) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:a6aed467-1a4c-4a5a-bf3d-e7ce46e94a9f, Addr:10.1.30.61) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:b3d71b04-f99a-4af8-aa69-2ca02a30d391, Addr:10.1.30.62) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:eb59daf8-f59c-435e-bfe4-8e7afd0937bd, Addr:10.1.30.63) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:3e931f82-08a5-44de-89a5-b907f5aaeb24, Addr:10.1.30.64) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:f673d611-7a73-4a8e-912d-ea16c294d51b, Addr:10.1.30.65) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:09a2569a-4948-4830-9dd8-315ae638e391, Addr:10.1.30.66) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:719a9643-c903-454e-8325-0f03cf871c35, Addr:10.1.30.31) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:ef8c3829-2363-43b3-ae20-7e903c2517a5, Addr:10.1.30.32) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:7cece978-67aa-4707-b23c-375ebddfc2bc, Addr:10.1.30.170) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:ad86d223-8f60-41c0-8208-c88d68e42154, Addr:10.1.30.33) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:fa86bb0c-6142-41ce-ba6c-565e1e1f810e, Addr:10.1.30.34) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:441a0b56-5830-4595-ab8d-b073b6db8545, Addr:10.1.30.35) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:8dbc0c6b-a8f5-491c-832b-4af0757c259d, Addr:10.1.30.36) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:d06cdd21-62c3-4cff-9389-12a4e21869a2, Addr:10.1.30.40) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:f63db18d-dc19-48b8-afaa-be557db4d13e, Addr:10.1.30.44) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:21589a71-d4dd-4534-b457-deb72f3f7660, Addr:10.1.30.41) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:230ddec2-fa03-44d9-8350-0c0eeb463400, Addr:10.1.30.42) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:b2647d59-ed85-44c5-813f-167c41ea1ca1, Addr:10.1.30.43) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:9933a2a3-47db-448a-a724-ed583d5994bb, Addr:10.1.30.37) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:9b45edaa-0640-4e86-ba59-1b991c1a85ca, Addr:10.1.30.45) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:a5fbeadb-a8ab-42e0-b58f-296e44633ce5, Addr:10.1.30.46) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:67d1d9ad-cf1d-43aa-9dc4-9e574cda5e5b, Addr:10.1.30.47) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:08689cb8-1b00-403f-bc20-c5911a20e655, Addr:10.1.30.48) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:a06a0e94-b651-4510-bbe0-8a0c3b717283, Addr:10.1.30.49) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:cf339d67-1758-4462-85f0-9e6a002d1c3c, Addr:10.1.30.70) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:d80a9fcf-5e0d-45a9-b617-362a9cb4121a, Addr:10.1.30.71) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:7c28d11a-9673-4957-931d-8840a589da85, Addr:10.1.30.72) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:ad792043-fdb8-4695-a10a-aa2cad996cf0, Addr:10.1.30.74) to Network 'PN/IE_1'
-[16:34:09] Mapping Device/Node 'IE1' (NodeID:b30940b8-6cb5-4143-854f-9b569f081703, Addr:10.1.30.73) to Network 'PN/IE_1'
-[16:34:09] Data extraction and structuring complete.
-[16:34:09] Generating JSON output: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\98050_PLC_01_CAx_Export.hierarchical.json
-[16:34:09] JSON data written successfully.
-[16:34:09] IO upward debug tree written to: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\98050_PLC_01_CAx_Export_IO_Upward_Debug.md
-[16:34:09] Found 1 PLC(s). Generating individual hardware trees...
-[16:34:09] Generating Hardware Tree for PLC 'A40510' (ID: fc0d3bac-267e-488a-8dcf-7dc8599d80e8) at: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\A40510\Documentation\98050_PLC_01_CAx_Export_Hardware_Tree.md
-[16:34:09] Markdown tree summary written to: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia\A40510\Documentation\98050_PLC_01_CAx_Export_Hardware_Tree.md
-[16:34:09] Script finished.
-[16:34:09] Ejecución de x2_process_CAx.py finalizada (success). Duración: 0:00:08.316649.
-[16:34:09] Log completo guardado en: D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\IO_adaptation\log_x2_process_CAx.txt
+[15:36:49] Iniciando ejecución de x7_update_CAx.py en D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia...
+[15:36:49] --- Actualizador de AML desde Excel Modificado (v1.1 - Simplified IO Address Handling (Start/End Separated)) ---
+[15:36:49] Directorio de trabajo: D:\Trabajo\VM\44 - 98050 - Fiera\Reporte\ExportsTia
+[15:36:49] 1. Seleccione el archivo AML original:
+[15:36:57] 2. Seleccione el archivo Excel modificado: