Modificado x1 para mantener los enlaces de EN con rails multiples
This commit is contained in:
parent
3787411cf5
commit
c62ce45987
|
@ -52,9 +52,7 @@ BEGIN
|
|||
|
||||
// Network 5: Minute Counter
|
||||
|
||||
IF "m1MinONS" THEN
|
||||
"Blender_Variables_Pers"."gProdSec" := 0;
|
||||
END_IF;
|
||||
"Blender_Variables_Pers"."gProdSec" := 0;
|
||||
"Blender_Variables_Pers"."gProdMin" := "Blender_Variables_Pers"."gProdMin" + 1;
|
||||
|
||||
// Network 6: Hour
|
||||
|
@ -63,17 +61,13 @@ BEGIN
|
|||
|
||||
// Network 7: Hour Counter
|
||||
|
||||
IF "m1HourONS" THEN
|
||||
"Blender_Variables_Pers"."gProdMin" := 0;
|
||||
END_IF;
|
||||
"Blender_Variables_Pers"."gProdMin" := 0;
|
||||
"Blender_Variables_Pers"."gProdHour" := "Blender_Variables_Pers"."gProdHour" + 1;
|
||||
"Blender_Variables_Pers"."gBlendingMaintHour" := "Blender_Variables_Pers"."gBlendingMaintHour" + 1;
|
||||
|
||||
// Network 8: Counter reset
|
||||
|
||||
IF "gBlenderCIPMode" OR "gBlenderRinseMode" THEN
|
||||
"Blender_Variables_Pers"."gProdSec" := 0;
|
||||
END_IF;
|
||||
"Blender_Variables_Pers"."gProdSec" := 0;
|
||||
"Blender_Variables_Pers"."gProdMin" := 0;
|
||||
"Blender_Variables_Pers"."gProdHour" := 0;
|
||||
|
||||
|
@ -90,7 +84,7 @@ BEGIN
|
|||
IF ("MOD60" = DINT#0 AND "Procedure_Variables"."Blender_Run"."Running") AND "CLK_1.0S" THEN
|
||||
"Blender_Variables_Pers"."gRunningMinutes" := "Blender_Variables_Pers"."gRunningMinutes" + 1;
|
||||
END_IF;
|
||||
// Edge detection PBox 41 -> P_TRIG_FUNC(CLK := (("MOD60" = DINT#0 AND "Procedure_Variables"."Blender_Run"."Running") AND "CLK_1.0S"), M := "M19012") (CLK source inferred)
|
||||
// Edge detection PBox 41 -> P_TRIG_FUNC(CLK := (("MOD60" = DINT#0 AND "Procedure_Variables"."Blender_Run"."Running") AND "CLK_1.0S"), M := "M19012") (CLK inferred)
|
||||
"mRunMin" := P_TRIG_FUNC(CLK := (("MOD60" = DINT#0 AND "Procedure_Variables"."Blender_Run"."Running") AND "CLK_1.0S"), M := "M19012");
|
||||
|
||||
// Network 11: Running Hours for Maintenance
|
||||
|
|
|
@ -55,14 +55,14 @@
|
|||
"instruction_uid": "26",
|
||||
"type": "Contact",
|
||||
"inputs": {
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
},
|
||||
"operand": {
|
||||
"uid": "21",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"Procedure_Variables\".\"Blender_Run\".\"Running\""
|
||||
},
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
}
|
||||
},
|
||||
"outputs": {}
|
||||
|
@ -71,17 +71,17 @@
|
|||
"instruction_uid": "27",
|
||||
"type": "Contact",
|
||||
"inputs": {
|
||||
"operand": {
|
||||
"uid": "22",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"CLK_1.0S\""
|
||||
},
|
||||
"in": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "26",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
},
|
||||
"operand": {
|
||||
"uid": "22",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"CLK_1.0S\""
|
||||
}
|
||||
},
|
||||
"outputs": {}
|
||||
|
@ -90,6 +90,12 @@
|
|||
"instruction_uid": "28",
|
||||
"type": "Add",
|
||||
"inputs": {
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "27",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
},
|
||||
"in1": {
|
||||
"uid": "23",
|
||||
"scope": "GlobalVariable",
|
||||
|
@ -102,12 +108,6 @@
|
|||
"type": "constant",
|
||||
"datatype": "Int",
|
||||
"value": 1
|
||||
},
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "27",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
@ -132,14 +132,14 @@
|
|||
"instruction_uid": "24",
|
||||
"type": "Contact",
|
||||
"inputs": {
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
},
|
||||
"operand": {
|
||||
"uid": "21",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"SLIM_Variables\".\"ResetHour\""
|
||||
},
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
}
|
||||
},
|
||||
"outputs": {}
|
||||
|
@ -148,18 +148,18 @@
|
|||
"instruction_uid": "25",
|
||||
"type": "Move",
|
||||
"inputs": {
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "24",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
},
|
||||
"in": {
|
||||
"uid": "22",
|
||||
"scope": "LiteralConstant",
|
||||
"type": "constant",
|
||||
"datatype": "Int",
|
||||
"value": 0
|
||||
},
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "24",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
@ -184,14 +184,14 @@
|
|||
"instruction_uid": "26",
|
||||
"type": "Contact",
|
||||
"inputs": {
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
},
|
||||
"operand": {
|
||||
"uid": "21",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"gBlenderBlending\""
|
||||
},
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
}
|
||||
},
|
||||
"outputs": {}
|
||||
|
@ -200,17 +200,17 @@
|
|||
"instruction_uid": "27",
|
||||
"type": "Contact",
|
||||
"inputs": {
|
||||
"operand": {
|
||||
"uid": "22",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"CLK_1.0S\""
|
||||
},
|
||||
"in": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "26",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
},
|
||||
"operand": {
|
||||
"uid": "22",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"CLK_1.0S\""
|
||||
}
|
||||
},
|
||||
"outputs": {}
|
||||
|
@ -219,6 +219,12 @@
|
|||
"instruction_uid": "28",
|
||||
"type": "Add",
|
||||
"inputs": {
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "27",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
},
|
||||
"in1": {
|
||||
"uid": "23",
|
||||
"scope": "GlobalVariable",
|
||||
|
@ -231,12 +237,6 @@
|
|||
"type": "constant",
|
||||
"datatype": "Int",
|
||||
"value": 1
|
||||
},
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "27",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
@ -310,14 +310,14 @@
|
|||
"instruction_uid": "27",
|
||||
"type": "Contact",
|
||||
"inputs": {
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
},
|
||||
"operand": {
|
||||
"uid": "21",
|
||||
"scope": "LocalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"m1MinONS\""
|
||||
},
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
}
|
||||
},
|
||||
"outputs": {}
|
||||
|
@ -326,18 +326,18 @@
|
|||
"instruction_uid": "28",
|
||||
"type": "Move",
|
||||
"inputs": {
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "27",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
},
|
||||
"in": {
|
||||
"uid": "22",
|
||||
"scope": "LiteralConstant",
|
||||
"type": "constant",
|
||||
"datatype": "Int",
|
||||
"value": 0
|
||||
},
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "27",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
@ -367,6 +367,12 @@
|
|||
"type": "constant",
|
||||
"datatype": "Int",
|
||||
"value": 1
|
||||
},
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "27",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
@ -440,14 +446,14 @@
|
|||
"instruction_uid": "30",
|
||||
"type": "Contact",
|
||||
"inputs": {
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
},
|
||||
"operand": {
|
||||
"uid": "21",
|
||||
"scope": "LocalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"m1HourONS\""
|
||||
},
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
}
|
||||
},
|
||||
"outputs": {}
|
||||
|
@ -456,18 +462,18 @@
|
|||
"instruction_uid": "31",
|
||||
"type": "Move",
|
||||
"inputs": {
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "30",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
},
|
||||
"in": {
|
||||
"uid": "22",
|
||||
"scope": "LiteralConstant",
|
||||
"type": "constant",
|
||||
"datatype": "Int",
|
||||
"value": 0
|
||||
},
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "30",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
@ -497,6 +503,12 @@
|
|||
"type": "constant",
|
||||
"datatype": "Int",
|
||||
"value": 1
|
||||
},
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "30",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
@ -526,6 +538,12 @@
|
|||
"type": "constant",
|
||||
"datatype": "Int",
|
||||
"value": 1
|
||||
},
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "30",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
@ -550,14 +568,14 @@
|
|||
"instruction_uid": "29",
|
||||
"type": "Contact",
|
||||
"inputs": {
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
},
|
||||
"operand": {
|
||||
"uid": "21",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"gBlenderCIPMode\""
|
||||
},
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
}
|
||||
},
|
||||
"outputs": {}
|
||||
|
@ -598,18 +616,18 @@
|
|||
"instruction_uid": "32",
|
||||
"type": "Move",
|
||||
"inputs": {
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "31",
|
||||
"source_instruction_type": "O",
|
||||
"source_pin": "out"
|
||||
},
|
||||
"in": {
|
||||
"uid": "23",
|
||||
"scope": "LiteralConstant",
|
||||
"type": "constant",
|
||||
"datatype": "Int",
|
||||
"value": 0
|
||||
},
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "31",
|
||||
"source_instruction_type": "O",
|
||||
"source_pin": "out"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
@ -633,6 +651,12 @@
|
|||
"type": "constant",
|
||||
"datatype": "Int",
|
||||
"value": 0
|
||||
},
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "31",
|
||||
"source_instruction_type": "O",
|
||||
"source_pin": "out"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
@ -656,6 +680,12 @@
|
|||
"type": "constant",
|
||||
"datatype": "Int",
|
||||
"value": 0
|
||||
},
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "31",
|
||||
"source_instruction_type": "O",
|
||||
"source_pin": "out"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
@ -680,14 +710,14 @@
|
|||
"instruction_uid": "26",
|
||||
"type": "Contact",
|
||||
"inputs": {
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
},
|
||||
"operand": {
|
||||
"uid": "21",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"Procedure_Variables\".\"Blender_Run\".\"Running\""
|
||||
},
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
}
|
||||
},
|
||||
"outputs": {}
|
||||
|
@ -696,17 +726,17 @@
|
|||
"instruction_uid": "27",
|
||||
"type": "Contact",
|
||||
"inputs": {
|
||||
"operand": {
|
||||
"uid": "22",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"CLK_1.0S\""
|
||||
},
|
||||
"in": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "26",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
},
|
||||
"operand": {
|
||||
"uid": "22",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"CLK_1.0S\""
|
||||
}
|
||||
},
|
||||
"outputs": {}
|
||||
|
@ -715,6 +745,12 @@
|
|||
"instruction_uid": "28",
|
||||
"type": "Add",
|
||||
"inputs": {
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "27",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
},
|
||||
"in1": {
|
||||
"uid": "23",
|
||||
"scope": "GlobalVariable",
|
||||
|
@ -727,12 +763,6 @@
|
|||
"type": "constant",
|
||||
"datatype": "Int",
|
||||
"value": 1
|
||||
},
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "27",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
@ -757,14 +787,14 @@
|
|||
"instruction_uid": "35",
|
||||
"type": "Convert",
|
||||
"inputs": {
|
||||
"en": {
|
||||
"type": "powerrail"
|
||||
},
|
||||
"in": {
|
||||
"uid": "21",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"Blender_Variables_Pers\".\"gRunningSeconds\""
|
||||
},
|
||||
"en": {
|
||||
"type": "powerrail"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
@ -825,12 +855,6 @@
|
|||
"instruction_uid": "37",
|
||||
"type": "Eq",
|
||||
"inputs": {
|
||||
"pre": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "36",
|
||||
"source_instruction_type": "Mod",
|
||||
"source_pin": "eno"
|
||||
},
|
||||
"in1": {
|
||||
"uid": "26",
|
||||
"scope": "LocalVariable",
|
||||
|
@ -843,6 +867,12 @@
|
|||
"type": "constant",
|
||||
"datatype": "TypedConstant",
|
||||
"value": "DINT#0"
|
||||
},
|
||||
"pre": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "36",
|
||||
"source_instruction_type": "Mod",
|
||||
"source_pin": "eno"
|
||||
}
|
||||
},
|
||||
"outputs": {}
|
||||
|
@ -870,17 +900,17 @@
|
|||
"instruction_uid": "39",
|
||||
"type": "Contact",
|
||||
"inputs": {
|
||||
"operand": {
|
||||
"uid": "29",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"CLK_1.0S\""
|
||||
},
|
||||
"in": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "38",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
},
|
||||
"operand": {
|
||||
"uid": "29",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"CLK_1.0S\""
|
||||
}
|
||||
},
|
||||
"outputs": {}
|
||||
|
@ -889,6 +919,12 @@
|
|||
"instruction_uid": "40",
|
||||
"type": "Add",
|
||||
"inputs": {
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "39",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
},
|
||||
"in1": {
|
||||
"uid": "30",
|
||||
"scope": "GlobalVariable",
|
||||
|
@ -901,12 +937,6 @@
|
|||
"type": "constant",
|
||||
"datatype": "Int",
|
||||
"value": 1
|
||||
},
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "39",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
@ -963,14 +993,14 @@
|
|||
"instruction_uid": "32",
|
||||
"type": "Contact",
|
||||
"inputs": {
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
},
|
||||
"operand": {
|
||||
"uid": "21",
|
||||
"scope": "LocalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"mRunMin\""
|
||||
},
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
}
|
||||
},
|
||||
"outputs": {}
|
||||
|
@ -979,17 +1009,17 @@
|
|||
"instruction_uid": "33",
|
||||
"type": "Convert",
|
||||
"inputs": {
|
||||
"in": {
|
||||
"uid": "22",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"Blender_Variables_Pers\".\"gRunningMinutes\""
|
||||
},
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "32",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
},
|
||||
"in": {
|
||||
"uid": "22",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"Blender_Variables_Pers\".\"gRunningMinutes\""
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
@ -1050,12 +1080,6 @@
|
|||
"instruction_uid": "35",
|
||||
"type": "Eq",
|
||||
"inputs": {
|
||||
"pre": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "34",
|
||||
"source_instruction_type": "Mod",
|
||||
"source_pin": "eno"
|
||||
},
|
||||
"in1": {
|
||||
"uid": "27",
|
||||
"scope": "LocalVariable",
|
||||
|
@ -1068,6 +1092,12 @@
|
|||
"type": "constant",
|
||||
"datatype": "TypedConstant",
|
||||
"value": "DINT#0"
|
||||
},
|
||||
"pre": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "34",
|
||||
"source_instruction_type": "Mod",
|
||||
"source_pin": "eno"
|
||||
}
|
||||
},
|
||||
"outputs": {}
|
||||
|
@ -1118,14 +1148,14 @@
|
|||
"instruction_uid": "23",
|
||||
"type": "Move",
|
||||
"inputs": {
|
||||
"en": {
|
||||
"type": "powerrail"
|
||||
},
|
||||
"in": {
|
||||
"uid": "21",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"Blender_Variables_Pers\".\"gRunningMaintHour\""
|
||||
},
|
||||
"en": {
|
||||
"type": "powerrail"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
|
|
@ -55,14 +55,14 @@
|
|||
"instruction_uid": "26",
|
||||
"type": "Contact_scl",
|
||||
"inputs": {
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
},
|
||||
"operand": {
|
||||
"uid": "21",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"Procedure_Variables\".\"Blender_Run\".\"Running\""
|
||||
},
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
}
|
||||
},
|
||||
"outputs": {},
|
||||
|
@ -72,17 +72,17 @@
|
|||
"instruction_uid": "27",
|
||||
"type": "Contact_scl",
|
||||
"inputs": {
|
||||
"operand": {
|
||||
"uid": "22",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"CLK_1.0S\""
|
||||
},
|
||||
"in": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "26",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
},
|
||||
"operand": {
|
||||
"uid": "22",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"CLK_1.0S\""
|
||||
}
|
||||
},
|
||||
"outputs": {},
|
||||
|
@ -92,6 +92,12 @@
|
|||
"instruction_uid": "28",
|
||||
"type": "Add_scl",
|
||||
"inputs": {
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "27",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
},
|
||||
"in1": {
|
||||
"uid": "23",
|
||||
"scope": "GlobalVariable",
|
||||
|
@ -104,12 +110,6 @@
|
|||
"type": "constant",
|
||||
"datatype": "Int",
|
||||
"value": 1
|
||||
},
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "27",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
@ -135,14 +135,14 @@
|
|||
"instruction_uid": "24",
|
||||
"type": "Contact_scl",
|
||||
"inputs": {
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
},
|
||||
"operand": {
|
||||
"uid": "21",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"SLIM_Variables\".\"ResetHour\""
|
||||
},
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
}
|
||||
},
|
||||
"outputs": {},
|
||||
|
@ -152,18 +152,18 @@
|
|||
"instruction_uid": "25",
|
||||
"type": "Move_scl",
|
||||
"inputs": {
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "24",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
},
|
||||
"in": {
|
||||
"uid": "22",
|
||||
"scope": "LiteralConstant",
|
||||
"type": "constant",
|
||||
"datatype": "Int",
|
||||
"value": 0
|
||||
},
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "24",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
@ -189,14 +189,14 @@
|
|||
"instruction_uid": "26",
|
||||
"type": "Contact_scl",
|
||||
"inputs": {
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
},
|
||||
"operand": {
|
||||
"uid": "21",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"gBlenderBlending\""
|
||||
},
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
}
|
||||
},
|
||||
"outputs": {},
|
||||
|
@ -206,17 +206,17 @@
|
|||
"instruction_uid": "27",
|
||||
"type": "Contact_scl",
|
||||
"inputs": {
|
||||
"operand": {
|
||||
"uid": "22",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"CLK_1.0S\""
|
||||
},
|
||||
"in": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "26",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
},
|
||||
"operand": {
|
||||
"uid": "22",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"CLK_1.0S\""
|
||||
}
|
||||
},
|
||||
"outputs": {},
|
||||
|
@ -226,6 +226,12 @@
|
|||
"instruction_uid": "28",
|
||||
"type": "Add_scl",
|
||||
"inputs": {
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "27",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
},
|
||||
"in1": {
|
||||
"uid": "23",
|
||||
"scope": "GlobalVariable",
|
||||
|
@ -238,12 +244,6 @@
|
|||
"type": "constant",
|
||||
"datatype": "Int",
|
||||
"value": 1
|
||||
},
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "27",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
@ -320,14 +320,14 @@
|
|||
"instruction_uid": "27",
|
||||
"type": "Contact_scl",
|
||||
"inputs": {
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
},
|
||||
"operand": {
|
||||
"uid": "21",
|
||||
"scope": "LocalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"m1MinONS\""
|
||||
},
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
}
|
||||
},
|
||||
"outputs": {},
|
||||
|
@ -337,18 +337,18 @@
|
|||
"instruction_uid": "28",
|
||||
"type": "Move_scl",
|
||||
"inputs": {
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "27",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
},
|
||||
"in": {
|
||||
"uid": "22",
|
||||
"scope": "LiteralConstant",
|
||||
"type": "constant",
|
||||
"datatype": "Int",
|
||||
"value": 0
|
||||
},
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "27",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
@ -361,7 +361,8 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"scl": "IF \"m1MinONS\" THEN\n \"Blender_Variables_Pers\".\"gProdSec\" := 0;\nEND_IF;"
|
||||
"grouped": true,
|
||||
"scl": "\"Blender_Variables_Pers\".\"gProdSec\" := 0;"
|
||||
},
|
||||
{
|
||||
"instruction_uid": "29",
|
||||
|
@ -379,6 +380,12 @@
|
|||
"type": "constant",
|
||||
"datatype": "Int",
|
||||
"value": 1
|
||||
},
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "27",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
@ -391,6 +398,7 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"grouped": true,
|
||||
"scl": "\"Blender_Variables_Pers\".\"gProdMin\" := \"Blender_Variables_Pers\".\"gProdMin\" + 1;"
|
||||
}
|
||||
]
|
||||
|
@ -455,14 +463,14 @@
|
|||
"instruction_uid": "30",
|
||||
"type": "Contact_scl",
|
||||
"inputs": {
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
},
|
||||
"operand": {
|
||||
"uid": "21",
|
||||
"scope": "LocalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"m1HourONS\""
|
||||
},
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
}
|
||||
},
|
||||
"outputs": {},
|
||||
|
@ -472,18 +480,18 @@
|
|||
"instruction_uid": "31",
|
||||
"type": "Move_scl",
|
||||
"inputs": {
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "30",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
},
|
||||
"in": {
|
||||
"uid": "22",
|
||||
"scope": "LiteralConstant",
|
||||
"type": "constant",
|
||||
"datatype": "Int",
|
||||
"value": 0
|
||||
},
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "30",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
@ -496,7 +504,8 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"scl": "IF \"m1HourONS\" THEN\n \"Blender_Variables_Pers\".\"gProdMin\" := 0;\nEND_IF;"
|
||||
"grouped": true,
|
||||
"scl": "\"Blender_Variables_Pers\".\"gProdMin\" := 0;"
|
||||
},
|
||||
{
|
||||
"instruction_uid": "32",
|
||||
|
@ -514,6 +523,12 @@
|
|||
"type": "constant",
|
||||
"datatype": "Int",
|
||||
"value": 1
|
||||
},
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "30",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
@ -526,6 +541,7 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"grouped": true,
|
||||
"scl": "\"Blender_Variables_Pers\".\"gProdHour\" := \"Blender_Variables_Pers\".\"gProdHour\" + 1;"
|
||||
},
|
||||
{
|
||||
|
@ -544,6 +560,12 @@
|
|||
"type": "constant",
|
||||
"datatype": "Int",
|
||||
"value": 1
|
||||
},
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "30",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
@ -556,6 +578,7 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"grouped": true,
|
||||
"scl": "\"Blender_Variables_Pers\".\"gBlendingMaintHour\" := \"Blender_Variables_Pers\".\"gBlendingMaintHour\" + 1;"
|
||||
}
|
||||
]
|
||||
|
@ -569,14 +592,14 @@
|
|||
"instruction_uid": "29",
|
||||
"type": "Contact_scl",
|
||||
"inputs": {
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
},
|
||||
"operand": {
|
||||
"uid": "21",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"gBlenderCIPMode\""
|
||||
},
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
}
|
||||
},
|
||||
"outputs": {},
|
||||
|
@ -620,12 +643,43 @@
|
|||
"instruction_uid": "32",
|
||||
"type": "Move_scl",
|
||||
"inputs": {
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "31",
|
||||
"source_instruction_type": "O",
|
||||
"source_pin": "out"
|
||||
},
|
||||
"in": {
|
||||
"uid": "23",
|
||||
"scope": "LiteralConstant",
|
||||
"type": "constant",
|
||||
"datatype": "Int",
|
||||
"value": 0
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"out1": [
|
||||
{
|
||||
"uid": "24",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"Blender_Variables_Pers\".\"gProdSec\""
|
||||
}
|
||||
]
|
||||
},
|
||||
"grouped": true,
|
||||
"scl": "\"Blender_Variables_Pers\".\"gProdSec\" := 0;"
|
||||
},
|
||||
{
|
||||
"instruction_uid": "33",
|
||||
"type": "Move_scl",
|
||||
"inputs": {
|
||||
"in": {
|
||||
"uid": "25",
|
||||
"scope": "LiteralConstant",
|
||||
"type": "constant",
|
||||
"datatype": "Int",
|
||||
"value": 0
|
||||
},
|
||||
"en": {
|
||||
"type": "connection",
|
||||
|
@ -634,30 +688,6 @@
|
|||
"source_pin": "out"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"out1": [
|
||||
{
|
||||
"uid": "24",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"Blender_Variables_Pers\".\"gProdSec\""
|
||||
}
|
||||
]
|
||||
},
|
||||
"scl": "IF \"gBlenderCIPMode\" OR \"gBlenderRinseMode\" THEN\n \"Blender_Variables_Pers\".\"gProdSec\" := 0;\nEND_IF;"
|
||||
},
|
||||
{
|
||||
"instruction_uid": "33",
|
||||
"type": "Move_scl",
|
||||
"inputs": {
|
||||
"in": {
|
||||
"uid": "25",
|
||||
"scope": "LiteralConstant",
|
||||
"type": "constant",
|
||||
"datatype": "Int",
|
||||
"value": 0
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"out1": [
|
||||
{
|
||||
|
@ -668,6 +698,7 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"grouped": true,
|
||||
"scl": "\"Blender_Variables_Pers\".\"gProdMin\" := 0;"
|
||||
},
|
||||
{
|
||||
|
@ -680,6 +711,12 @@
|
|||
"type": "constant",
|
||||
"datatype": "Int",
|
||||
"value": 0
|
||||
},
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "31",
|
||||
"source_instruction_type": "O",
|
||||
"source_pin": "out"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
@ -692,6 +729,7 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"grouped": true,
|
||||
"scl": "\"Blender_Variables_Pers\".\"gProdHour\" := 0;"
|
||||
}
|
||||
]
|
||||
|
@ -705,14 +743,14 @@
|
|||
"instruction_uid": "26",
|
||||
"type": "Contact_scl",
|
||||
"inputs": {
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
},
|
||||
"operand": {
|
||||
"uid": "21",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"Procedure_Variables\".\"Blender_Run\".\"Running\""
|
||||
},
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
}
|
||||
},
|
||||
"outputs": {},
|
||||
|
@ -722,17 +760,17 @@
|
|||
"instruction_uid": "27",
|
||||
"type": "Contact_scl",
|
||||
"inputs": {
|
||||
"operand": {
|
||||
"uid": "22",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"CLK_1.0S\""
|
||||
},
|
||||
"in": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "26",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
},
|
||||
"operand": {
|
||||
"uid": "22",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"CLK_1.0S\""
|
||||
}
|
||||
},
|
||||
"outputs": {},
|
||||
|
@ -742,6 +780,12 @@
|
|||
"instruction_uid": "28",
|
||||
"type": "Add_scl",
|
||||
"inputs": {
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "27",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
},
|
||||
"in1": {
|
||||
"uid": "23",
|
||||
"scope": "GlobalVariable",
|
||||
|
@ -754,12 +798,6 @@
|
|||
"type": "constant",
|
||||
"datatype": "Int",
|
||||
"value": 1
|
||||
},
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "27",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
@ -785,14 +823,14 @@
|
|||
"instruction_uid": "35",
|
||||
"type": "Convert_scl",
|
||||
"inputs": {
|
||||
"en": {
|
||||
"type": "powerrail"
|
||||
},
|
||||
"in": {
|
||||
"uid": "21",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"Blender_Variables_Pers\".\"gRunningSeconds\""
|
||||
},
|
||||
"en": {
|
||||
"type": "powerrail"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
@ -855,12 +893,6 @@
|
|||
"instruction_uid": "37",
|
||||
"type": "Eq_scl",
|
||||
"inputs": {
|
||||
"pre": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "36",
|
||||
"source_instruction_type": "Mod",
|
||||
"source_pin": "eno"
|
||||
},
|
||||
"in1": {
|
||||
"uid": "26",
|
||||
"scope": "LocalVariable",
|
||||
|
@ -873,6 +905,12 @@
|
|||
"type": "constant",
|
||||
"datatype": "TypedConstant",
|
||||
"value": "DINT#0"
|
||||
},
|
||||
"pre": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "36",
|
||||
"source_instruction_type": "Mod",
|
||||
"source_pin": "eno"
|
||||
}
|
||||
},
|
||||
"outputs": {},
|
||||
|
@ -902,17 +940,17 @@
|
|||
"instruction_uid": "39",
|
||||
"type": "Contact_scl",
|
||||
"inputs": {
|
||||
"operand": {
|
||||
"uid": "29",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"CLK_1.0S\""
|
||||
},
|
||||
"in": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "38",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
},
|
||||
"operand": {
|
||||
"uid": "29",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"CLK_1.0S\""
|
||||
}
|
||||
},
|
||||
"outputs": {},
|
||||
|
@ -922,6 +960,12 @@
|
|||
"instruction_uid": "40",
|
||||
"type": "Add_scl",
|
||||
"inputs": {
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "39",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
},
|
||||
"in1": {
|
||||
"uid": "30",
|
||||
"scope": "GlobalVariable",
|
||||
|
@ -934,12 +978,6 @@
|
|||
"type": "constant",
|
||||
"datatype": "Int",
|
||||
"value": 1
|
||||
},
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "39",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
@ -966,7 +1004,7 @@
|
|||
}
|
||||
},
|
||||
"outputs": {},
|
||||
"scl": "// Edge detection PBox 41 -> P_TRIG_FUNC(CLK := ((\"MOD60\" = DINT#0 AND \"Procedure_Variables\".\"Blender_Run\".\"Running\") AND \"CLK_1.0S\"), M := \"M19012\") (CLK source inferred)"
|
||||
"scl": "// Edge detection PBox 41 -> P_TRIG_FUNC(CLK := ((\"MOD60\" = DINT#0 AND \"Procedure_Variables\".\"Blender_Run\".\"Running\") AND \"CLK_1.0S\"), M := \"M19012\") (CLK inferred)"
|
||||
},
|
||||
{
|
||||
"instruction_uid": "42",
|
||||
|
@ -999,14 +1037,14 @@
|
|||
"instruction_uid": "32",
|
||||
"type": "Contact_scl",
|
||||
"inputs": {
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
},
|
||||
"operand": {
|
||||
"uid": "21",
|
||||
"scope": "LocalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"mRunMin\""
|
||||
},
|
||||
"in": {
|
||||
"type": "powerrail"
|
||||
}
|
||||
},
|
||||
"outputs": {},
|
||||
|
@ -1016,17 +1054,17 @@
|
|||
"instruction_uid": "33",
|
||||
"type": "Convert_scl",
|
||||
"inputs": {
|
||||
"in": {
|
||||
"uid": "22",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"Blender_Variables_Pers\".\"gRunningMinutes\""
|
||||
},
|
||||
"en": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "32",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_pin": "out"
|
||||
},
|
||||
"in": {
|
||||
"uid": "22",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"Blender_Variables_Pers\".\"gRunningMinutes\""
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
@ -1089,12 +1127,6 @@
|
|||
"instruction_uid": "35",
|
||||
"type": "Eq_scl",
|
||||
"inputs": {
|
||||
"pre": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "34",
|
||||
"source_instruction_type": "Mod",
|
||||
"source_pin": "eno"
|
||||
},
|
||||
"in1": {
|
||||
"uid": "27",
|
||||
"scope": "LocalVariable",
|
||||
|
@ -1107,6 +1139,12 @@
|
|||
"type": "constant",
|
||||
"datatype": "TypedConstant",
|
||||
"value": "DINT#0"
|
||||
},
|
||||
"pre": {
|
||||
"type": "connection",
|
||||
"source_instruction_uid": "34",
|
||||
"source_instruction_type": "Mod",
|
||||
"source_pin": "eno"
|
||||
}
|
||||
},
|
||||
"outputs": {},
|
||||
|
@ -1159,14 +1197,14 @@
|
|||
"instruction_uid": "23",
|
||||
"type": "Move_scl",
|
||||
"inputs": {
|
||||
"en": {
|
||||
"type": "powerrail"
|
||||
},
|
||||
"in": {
|
||||
"uid": "21",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"Blender_Variables_Pers\".\"gRunningMaintHour\""
|
||||
},
|
||||
"en": {
|
||||
"type": "powerrail"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
|
546
x1_to_json.py
546
x1_to_json.py
|
@ -3,201 +3,193 @@ import json
|
|||
import os
|
||||
from lxml import etree
|
||||
import traceback
|
||||
from collections import defaultdict # Para facilitar el manejo de conexiones
|
||||
|
||||
# --- Namespaces ---
|
||||
ns = {
|
||||
'iface': 'http://www.siemens.com/automation/Openness/SW/Interface/v5',
|
||||
'flg': 'http://www.siemens.com/automation/Openness/SW/NetworkSource/FlgNet/v4'
|
||||
"iface": "http://www.siemens.com/automation/Openness/SW/Interface/v5",
|
||||
"flg": "http://www.siemens.com/automation/Openness/SW/NetworkSource/FlgNet/v4",
|
||||
}
|
||||
|
||||
|
||||
# --- Helper Functions ---
|
||||
# (get_multilingual_text, get_symbol_name, parse_access, parse_part sin cambios)
|
||||
def get_multilingual_text(element, default_lang='en-US', fallback_lang='it-IT'):
|
||||
"""
|
||||
Intenta extraer texto de un elemento MultilingualText, priorizando idiomas.
|
||||
Busca directamente los Text dentro de Items/AttributeList/Text bajo las Culture especificadas.
|
||||
"""
|
||||
# (get_multilingual_text, get_symbol_name, parse_access, parse_part - sin cambios)
|
||||
def get_multilingual_text(element, default_lang="en-US", fallback_lang="it-IT"):
|
||||
if element is None:
|
||||
return ""
|
||||
try:
|
||||
# Intenta encontrar el idioma por defecto
|
||||
xpath_expr = f".//*[local-name()='MultilingualTextItem'][*[local-name()='AttributeList']/*[local-name()='Culture' and text()='{default_lang}']]" \
|
||||
f"/*[local-name()='AttributeList']/*[local-name()='Text']"
|
||||
xpath_expr = (
|
||||
f".//*[local-name()='MultilingualTextItem'][*[local-name()='AttributeList']/*[local-name()='Culture' and text()='{default_lang}']]"
|
||||
f"/*[local-name()='AttributeList']/*[local-name()='Text']"
|
||||
)
|
||||
text_items = element.xpath(xpath_expr)
|
||||
if text_items and text_items[0].text is not None:
|
||||
return text_items[0].text.strip()
|
||||
|
||||
# Si no, intenta encontrar el idioma de fallback
|
||||
xpath_expr = f".//*[local-name()='MultilingualTextItem'][*[local-name()='AttributeList']/*[local-name()='Culture' and text()='{fallback_lang}']]" \
|
||||
f"/*[local-name()='AttributeList']/*[local-name()='Text']"
|
||||
xpath_expr = (
|
||||
f".//*[local-name()='MultilingualTextItem'][*[local-name()='AttributeList']/*[local-name()='Culture' and text()='{fallback_lang}']]"
|
||||
f"/*[local-name()='AttributeList']/*[local-name()='Text']"
|
||||
)
|
||||
text_items = element.xpath(xpath_expr)
|
||||
if text_items and text_items[0].text is not None:
|
||||
return text_items[0].text.strip()
|
||||
|
||||
# Si no, toma el primer texto que encuentre
|
||||
xpath_expr = f".//*[local-name()='MultilingualTextItem']/*[local-name()='AttributeList']/*[local-name()='Text']"
|
||||
text_items = element.xpath(xpath_expr)
|
||||
if text_items and text_items[0].text is not None:
|
||||
return text_items[0].text.strip()
|
||||
|
||||
return "" # Devuelve cadena vacía si no se encuentra nada
|
||||
return ""
|
||||
except Exception as e:
|
||||
print(f"Advertencia: Error extrayendo MultilingualText desde {etree.tostring(element, encoding='unicode')[:100]}...: {e}")
|
||||
print(f"Advertencia: Error extrayendo MultilingualText: {e}")
|
||||
return ""
|
||||
|
||||
|
||||
def get_symbol_name(symbol_element):
|
||||
"""
|
||||
Construye el nombre completo del símbolo (variable) a partir de sus elementos Component.
|
||||
Encapsula cada componente entre comillas dobles y los une con puntos.
|
||||
"""
|
||||
if symbol_element is None:
|
||||
return None
|
||||
try:
|
||||
# Selecciona el atributo 'Name' de cada elemento 'Component' hijo directo del Symbol
|
||||
components = symbol_element.xpath("./*[local-name()='Component']/@Name")
|
||||
if components:
|
||||
# Une los componentes, asegurándose de que cada uno esté entre comillas dobles
|
||||
full_name = ".".join(f'"{c}"' for c in components)
|
||||
return full_name
|
||||
else:
|
||||
return None # Indica que no se pudo formar un nombre
|
||||
return ".".join(f'"{c}"' for c in components) if components else None
|
||||
except Exception as e:
|
||||
print(f"Advertencia: Excepción en get_symbol_name para {etree.tostring(symbol_element, encoding='unicode')[:100]}...: {e}")
|
||||
print(f"Advertencia: Excepción en get_symbol_name: {e}")
|
||||
return None
|
||||
|
||||
|
||||
def parse_access(access_element):
|
||||
"""
|
||||
Parsea un elemento Access (acceso a operando) para obtener información
|
||||
detallada sobre si es una variable (Symbol) o una constante (Constant).
|
||||
Devuelve un diccionario con la información o None si hay un error crítico.
|
||||
"""
|
||||
if access_element is None:
|
||||
return None
|
||||
|
||||
uid = access_element.get('UId')
|
||||
scope = access_element.get('Scope')
|
||||
|
||||
info = {'uid': uid, 'scope': scope, 'type': 'unknown'} # Inicializa info
|
||||
|
||||
uid = access_element.get("UId")
|
||||
scope = access_element.get("Scope")
|
||||
info = {"uid": uid, "scope": scope, "type": "unknown"}
|
||||
symbol = access_element.xpath("./*[local-name()='Symbol']")
|
||||
constant = access_element.xpath("./*[local-name()='Constant']")
|
||||
|
||||
if symbol:
|
||||
info['type'] = 'variable'
|
||||
info['name'] = get_symbol_name(symbol[0])
|
||||
if info['name'] is None:
|
||||
info['type'] = 'error_parsing_symbol'
|
||||
print(f"Error: No se pudo parsear el nombre del símbolo para Access UID={uid}")
|
||||
info["type"] = "variable"
|
||||
info["name"] = get_symbol_name(symbol[0])
|
||||
if info["name"] is None:
|
||||
info["type"] = "error_parsing_symbol"
|
||||
print(f"Error: No se pudo parsear nombre símbolo Access UID={uid}")
|
||||
return info
|
||||
|
||||
elif constant:
|
||||
info['type'] = 'constant'
|
||||
info["type"] = "constant"
|
||||
const_type_elem = constant[0].xpath("./*[local-name()='ConstantType']")
|
||||
const_val_elem = constant[0].xpath("./*[local-name()='ConstantValue']")
|
||||
info['datatype'] = const_type_elem[0].text if const_type_elem and const_type_elem[0].text is not None else 'Unknown'
|
||||
value_str = const_val_elem[0].text if const_val_elem and const_val_elem[0].text is not None else None
|
||||
|
||||
info["datatype"] = (
|
||||
const_type_elem[0].text
|
||||
if const_type_elem and const_type_elem[0].text is not None
|
||||
else "Unknown"
|
||||
)
|
||||
value_str = (
|
||||
const_val_elem[0].text
|
||||
if const_val_elem and const_val_elem[0].text is not None
|
||||
else None
|
||||
)
|
||||
if value_str is None:
|
||||
info['type'] = 'error_parsing_constant'
|
||||
info['value'] = None
|
||||
print(f"Error: Constante sin valor encontrada para Access UID={uid}")
|
||||
info["type"] = "error_parsing_constant"
|
||||
info["value"] = None
|
||||
print(f"Error: Constante sin valor Access UID={uid}")
|
||||
return info
|
||||
|
||||
if info['datatype'] == 'Unknown':
|
||||
if info["datatype"] == "Unknown":
|
||||
val_lower = value_str.lower()
|
||||
if val_lower in ['true', 'false']: info['datatype'] = 'Bool'
|
||||
elif value_str.isdigit() or (value_str.startswith('-') and value_str[1:].isdigit()): info['datatype'] = 'Int'
|
||||
elif '.' in value_str:
|
||||
try: float(value_str); info['datatype'] = 'Real'
|
||||
except ValueError: pass
|
||||
elif '#' in value_str: info['datatype'] = 'TypedConstant'
|
||||
|
||||
info['value'] = value_str
|
||||
dtype_lower = info['datatype'].lower()
|
||||
val_str_processed = value_str.split('#')[-1] if '#' in value_str else value_str
|
||||
if val_lower in ["true", "false"]:
|
||||
info["datatype"] = "Bool"
|
||||
elif value_str.isdigit() or (
|
||||
value_str.startswith("-") and value_str[1:].isdigit()
|
||||
):
|
||||
info["datatype"] = "Int"
|
||||
elif "." in value_str:
|
||||
try:
|
||||
float(value_str)
|
||||
info["datatype"] = "Real"
|
||||
except ValueError:
|
||||
pass # Si no es float, sigue siendo Unknown (o lo que fuera antes)
|
||||
elif "#" in value_str:
|
||||
info["datatype"] = "TypedConstant"
|
||||
info["value"] = value_str
|
||||
dtype_lower = info["datatype"].lower()
|
||||
val_str_processed = value_str.split("#")[-1] if "#" in value_str else value_str
|
||||
try:
|
||||
if dtype_lower in ['int', 'dint', 'udint', 'sint', 'usint', 'lint', 'ulint', 'word', 'dword', 'lword', 'byte']:
|
||||
info['value'] = int(val_str_processed)
|
||||
elif dtype_lower == 'bool':
|
||||
info['value'] = val_str_processed.lower() == 'true' or val_str_processed == '1'
|
||||
elif dtype_lower in ['real', 'lreal']:
|
||||
info['value'] = float(val_str_processed)
|
||||
elif dtype_lower == 'typedconstant':
|
||||
info['value'] = value_str
|
||||
if dtype_lower in [
|
||||
"int",
|
||||
"dint",
|
||||
"udint",
|
||||
"sint",
|
||||
"usint",
|
||||
"lint",
|
||||
"ulint",
|
||||
"word",
|
||||
"dword",
|
||||
"lword",
|
||||
"byte",
|
||||
]:
|
||||
info["value"] = int(val_str_processed)
|
||||
elif dtype_lower == "bool":
|
||||
info["value"] = (
|
||||
val_str_processed.lower() == "true" or val_str_processed == "1"
|
||||
)
|
||||
elif dtype_lower in ["real", "lreal"]:
|
||||
info["value"] = float(val_str_processed)
|
||||
elif dtype_lower == "typedconstant":
|
||||
info["value"] = value_str
|
||||
except (ValueError, TypeError) as e:
|
||||
print(f"Advertencia: No se pudo convertir el valor '{val_str_processed}' a tipo {dtype_lower} para UID={uid}. Se mantiene como string. Error: {e}")
|
||||
info['value'] = value_str
|
||||
|
||||
print(
|
||||
f"Advertencia: No se pudo convertir valor '{val_str_processed}' a {dtype_lower} UID={uid}. Error: {e}"
|
||||
)
|
||||
info["value"] = value_str
|
||||
else:
|
||||
info['type'] = 'unknown_structure'
|
||||
print(f"Advertencia: Access UID={uid} no es ni Symbol ni Constant.")
|
||||
info["type"] = "unknown_structure"
|
||||
print(f"Advertencia: Access UID={uid} no es Symbol ni Constant.")
|
||||
return info
|
||||
if info["type"] == "variable" and info.get("name") is None:
|
||||
print(f"Error Interno: parse_access var sin nombre UID {uid}.")
|
||||
info["type"] = "error_no_name"
|
||||
return info
|
||||
|
||||
if info['type'] == 'variable' and info.get('name') is None:
|
||||
print(f"Error Interno: parse_access terminó con tipo 'variable' pero sin nombre para UID {uid}.")
|
||||
info['type'] = 'error_no_name'
|
||||
return info
|
||||
|
||||
return info
|
||||
|
||||
|
||||
def parse_part(part_element):
|
||||
"""
|
||||
Parsea un elemento Part (representa una instrucción como Add, Move, Contact, Coil)
|
||||
y extrae su UID, nombre y valores de plantilla (TemplateValue).
|
||||
Devuelve un diccionario con la información o None si el elemento es inválido.
|
||||
"""
|
||||
if part_element is None:
|
||||
return None
|
||||
|
||||
uid = part_element.get('UId')
|
||||
name = part_element.get('Name')
|
||||
|
||||
uid = part_element.get("UId")
|
||||
name = part_element.get("Name")
|
||||
if not uid or not name:
|
||||
print(f"Error: Part encontrado sin UID o Name: {etree.tostring(part_element, encoding='unicode')}")
|
||||
print(
|
||||
f"Error: Part sin UID o Name: {etree.tostring(part_element, encoding='unicode')}"
|
||||
)
|
||||
return None
|
||||
|
||||
template_values = {}
|
||||
try:
|
||||
for tv in part_element.xpath("./*[local-name()='TemplateValue']"):
|
||||
tv_name = tv.get('Name')
|
||||
tv_type = tv.get('Type')
|
||||
tv_name = tv.get("Name")
|
||||
tv_type = tv.get("Type")
|
||||
if tv_name and tv_type:
|
||||
template_values[tv_name] = tv_type
|
||||
except Exception as e:
|
||||
print(f"Advertencia: Error extrayendo TemplateValues para Part UID={uid}: {e}")
|
||||
print(f"Advertencia: Error extrayendo TemplateValues Part UID={uid}: {e}")
|
||||
return {"uid": uid, "name": name, "template_values": template_values}
|
||||
|
||||
return {
|
||||
'uid': uid,
|
||||
'name': name,
|
||||
'template_values': template_values # Mantenemos esto por si acaso, aunque no se use prominentemente
|
||||
}
|
||||
|
||||
# --- Main Parsing Logic ---
|
||||
|
||||
def parse_network(network_element):
|
||||
"""
|
||||
Parsea un elemento SW.Blocks.CompileUnit (representa una red de lógica)
|
||||
y extrae su ID, título, comentario y la lógica interna simplificada en formato JSON,
|
||||
incluyendo la lógica conectada a ENO si no es un simple EN->ENO.
|
||||
Parsea una red (CompileUnit), extrae lógica, infiere conexiones EN implícitas,
|
||||
y añade lógica ENO interesante.
|
||||
"""
|
||||
if network_element is None:
|
||||
print("Error: parse_network llamado con network_element=None")
|
||||
return {'id': 'ERROR', 'title': 'Invalid Network Element', 'comment': '', 'logic': [], 'error': 'Input element was None'}
|
||||
|
||||
network_id = network_element.get('ID')
|
||||
# print(f"--- Parseando Red ID={network_id} ---") # Descomentar para depuración detallada
|
||||
|
||||
# Extrae el título de la red
|
||||
title_element = network_element.xpath(".//*[local-name()='MultilingualText'][@CompositionName='Title']")
|
||||
network_title = get_multilingual_text(title_element[0]) if title_element else f"Network {network_id}"
|
||||
|
||||
# *** NUEVO: Extrae el comentario de la red ***
|
||||
# Extrae el comentario de la red
|
||||
network_comment = ""
|
||||
comment_title_element = network_element.xpath("./*[local-name()='ObjectList']/*[local-name()='MultilingualText'][@CompositionName='Comment']")
|
||||
if comment_title_element:
|
||||
network_comment = get_multilingual_text(comment_title_element[0])
|
||||
# print(f"DEBUG: Comentario Red {network_id}: '{network_comment[:50]}...'")
|
||||
|
||||
|
||||
# Encuentra FlgNet
|
||||
flgnet_list = network_element.xpath(".//flg:FlgNet", namespaces=ns)
|
||||
if not flgnet_list:
|
||||
print(f"Error: No se encontró FlgNet en la red ID={network_id}")
|
||||
|
@ -205,28 +197,20 @@ def parse_network(network_element):
|
|||
flgnet = flgnet_list[0]
|
||||
|
||||
# 1. Parsear Access y Parts
|
||||
access_map = {}
|
||||
for acc in flgnet.xpath(".//flg:Access", namespaces=ns):
|
||||
acc_info = parse_access(acc)
|
||||
if acc_info and 'uid' in acc_info:
|
||||
access_map[acc_info['uid']] = acc_info
|
||||
access_map = {acc_info['uid']: acc_info for acc in flgnet.xpath(".//flg:Access", namespaces=ns) if (acc_info := parse_access(acc))}
|
||||
parts_map = {part_info['uid']: part_info for part in flgnet.xpath(".//flg:Part", namespaces=ns) if (part_info := parse_part(part))}
|
||||
# print(f"DEBUG: Red {network_id} - Access={len(access_map)}, Parts={len(parts_map)}") # Debug
|
||||
|
||||
parts_map = {}
|
||||
for part in flgnet.xpath(".//flg:Part", namespaces=ns):
|
||||
part_info = parse_part(part)
|
||||
if part_info and 'uid' in part_info:
|
||||
parts_map[part_info['uid']] = part_info
|
||||
|
||||
# 2. Parsear Wires y construir mapa de conexiones de entrada y *salida ENO*
|
||||
wire_connections = {} # Clave=(dest_uid, dest_pin), Valor=lista de (source_uid, source_pin)
|
||||
eno_outputs = {} # Clave=source_part_uid, Valor=lista de (dest_uid, dest_pin)
|
||||
# 2. Parsear Wires y construir mapas de conexiones
|
||||
wire_connections = defaultdict(list) # key=(dest_uid, dest_pin), value=list of (src_uid, src_pin)
|
||||
source_connections = defaultdict(list) # key=(src_uid, src_pin), value=list of (dest_uid, dest_pin)
|
||||
eno_outputs = defaultdict(list) # key=src_uid, value=list of (dest_uid, dest_pin) from ENO
|
||||
flg_ns_uri = ns['flg']
|
||||
|
||||
for wire in flgnet.xpath(".//flg:Wire", namespaces=ns):
|
||||
source_uid, source_pin, dest_uid, dest_pin = None, None, None, None
|
||||
children = wire.getchildren()
|
||||
if len(children) < 2: continue
|
||||
|
||||
source_elem, dest_elem = children[0], children[1]
|
||||
|
||||
# Determina la fuente
|
||||
|
@ -238,181 +222,184 @@ def parse_network(network_element):
|
|||
if dest_elem.tag == etree.QName(flg_ns_uri, 'IdentCon'): dest_uid, dest_pin = dest_elem.get('UId'), 'value'
|
||||
elif dest_elem.tag == etree.QName(flg_ns_uri, 'NameCon'): dest_uid, dest_pin = dest_elem.get('UId'), dest_elem.get('Name')
|
||||
|
||||
# Registrar conexión de entrada normal
|
||||
# Registrar conexiones si son válidas
|
||||
if dest_uid and dest_pin and source_uid is not None:
|
||||
dest_key = (dest_uid, dest_pin)
|
||||
source_info = (source_uid, source_pin)
|
||||
if dest_key not in wire_connections: wire_connections[dest_key] = []
|
||||
dest_key = (dest_uid, dest_pin); source_key = (source_uid, source_pin)
|
||||
source_info = (source_uid, source_pin); dest_info = (dest_uid, dest_pin)
|
||||
|
||||
if source_info not in wire_connections[dest_key]: wire_connections[dest_key].append(source_info)
|
||||
if dest_info not in source_connections[source_key]: source_connections[source_key].append(dest_info)
|
||||
|
||||
# *** NUEVO: Registrar conexiones que SALEN de un pin ENO ***
|
||||
# Registrar conexiones que SALEN de un pin ENO
|
||||
if source_pin == 'eno' and source_uid in parts_map:
|
||||
if source_uid not in eno_outputs: eno_outputs[source_uid] = []
|
||||
eno_dest_info = (dest_uid, dest_pin)
|
||||
if eno_dest_info not in eno_outputs[source_uid]:
|
||||
eno_outputs[source_uid].append(eno_dest_info)
|
||||
# print(f"DEBUG: Red {network_id} - ENO de {source_uid} conectado a ({dest_uid}, {dest_pin})")
|
||||
if dest_info not in eno_outputs[source_uid]:
|
||||
eno_outputs[source_uid].append(dest_info)
|
||||
|
||||
|
||||
# 3. Construir la representación lógica principal
|
||||
# 3. Construir la representación lógica INICIAL
|
||||
all_logic_steps = {}
|
||||
functional_block_types = ['Move', 'Add', 'Sub', 'Mul', 'Div', 'Mod', 'Convert'] # Ampliar si es necesario
|
||||
rlo_generators = ['Contact', 'O', 'Eq', 'Ne', 'Gt', 'Lt', 'Ge', 'Le', 'And', 'Xor', 'PBox'] # Ampliar si es necesario
|
||||
|
||||
for part_uid, part_info in parts_map.items():
|
||||
instruction_repr = {'instruction_uid': part_uid, 'type': part_info['name'], 'inputs': {}, 'outputs': {}}
|
||||
# Rellenar inputs explícitos
|
||||
for dest_pin_name in ['en', 'in', 'in1', 'in2', 'in3', 'in4', 'bit', 'operand', 'pre', 'clk']: # Añadir pines comunes
|
||||
dest_key = (part_uid, dest_pin_name)
|
||||
if dest_key in wire_connections:
|
||||
sources_list = wire_connections[dest_key]
|
||||
input_sources_repr = []
|
||||
for source_uid, source_pin in sources_list:
|
||||
if source_uid == 'POWERRAIL': input_sources_repr.append({'type': 'powerrail'})
|
||||
elif source_uid in access_map: input_sources_repr.append(access_map[source_uid])
|
||||
elif source_uid in parts_map:
|
||||
input_sources_repr.append({'type': 'connection', 'source_instruction_uid': source_uid,
|
||||
'source_instruction_type': parts_map[source_uid]['name'], 'source_pin': source_pin})
|
||||
else: input_sources_repr.append({'type': 'unknown_source', 'uid': source_uid})
|
||||
if len(input_sources_repr) == 1: instruction_repr['inputs'][dest_pin_name] = input_sources_repr[0]
|
||||
elif len(input_sources_repr) > 1: instruction_repr['inputs'][dest_pin_name] = input_sources_repr # Rama OR/Multiple
|
||||
|
||||
# Procesar Entradas (igual que antes)
|
||||
for (conn_dest_uid, conn_dest_pin), sources_list in wire_connections.items():
|
||||
if conn_dest_uid == part_uid:
|
||||
input_sources_repr = []
|
||||
for source_uid, source_pin in sources_list:
|
||||
if source_uid == 'POWERRAIL': input_sources_repr.append({'type': 'powerrail'})
|
||||
elif source_uid in access_map: input_sources_repr.append(access_map[source_uid])
|
||||
elif source_uid in parts_map:
|
||||
input_sources_repr.append({'type': 'connection', 'source_instruction_uid': source_uid,
|
||||
'source_instruction_type': parts_map[source_uid]['name'], 'source_pin': source_pin})
|
||||
else: input_sources_repr.append({'type': 'unknown_source', 'uid': source_uid})
|
||||
|
||||
if len(input_sources_repr) == 1: instruction_repr['inputs'][conn_dest_pin] = input_sources_repr[0]
|
||||
elif len(input_sources_repr) > 1: instruction_repr['inputs'][conn_dest_pin] = input_sources_repr
|
||||
|
||||
# Procesar Salidas (igual que antes)
|
||||
for (conn_dest_uid, conn_dest_pin), sources_list in wire_connections.items():
|
||||
for source_uid, source_pin in sources_list:
|
||||
if source_uid == part_uid and conn_dest_uid in access_map:
|
||||
if source_pin not in instruction_repr['outputs']: instruction_repr['outputs'][source_pin] = []
|
||||
if access_map[conn_dest_uid] not in instruction_repr['outputs'][source_pin]:
|
||||
instruction_repr['outputs'][source_pin].append(access_map[conn_dest_uid])
|
||||
# Rellenar outputs explícitos (hacia Access)
|
||||
for source_pin_name in ['out', 'out1', 'Q', 'eno']: # Añadir pines comunes
|
||||
source_key = (part_uid, source_pin_name)
|
||||
if source_key in source_connections:
|
||||
for dest_uid, dest_pin in source_connections[source_key]:
|
||||
if dest_uid in access_map:
|
||||
if source_pin_name not in instruction_repr['outputs']: instruction_repr['outputs'][source_pin_name] = []
|
||||
if access_map[dest_uid] not in instruction_repr['outputs'][source_pin_name]:
|
||||
instruction_repr['outputs'][source_pin_name].append(access_map[dest_uid])
|
||||
|
||||
all_logic_steps[part_uid] = instruction_repr
|
||||
|
||||
# --- 4. INFERENCIA Y PROPAGACIÓN DE CONEXIONES 'EN' IMPLÍCITAS ---
|
||||
# print(f"DEBUG: Iniciando inferencia EN para Red {network_id}...") # Debug
|
||||
processed_blocks_en_inference = set() # Evitar procesar el mismo bloque múltiples veces en inferencia EN
|
||||
something_changed = True
|
||||
inference_passes = 0
|
||||
max_inference_passes = len(all_logic_steps) + 5
|
||||
|
||||
# *** NUEVO: Procesar y añadir lógica ENO "interesante" ***
|
||||
while something_changed and inference_passes < max_inference_passes:
|
||||
something_changed = False
|
||||
inference_passes += 1
|
||||
# print(f"DEBUG: Pase de inferencia EN {inference_passes}...") # Debug
|
||||
|
||||
# Ordenar por UID para intentar procesar en orden lógico
|
||||
try:
|
||||
sorted_uids_for_pass = sorted(all_logic_steps.keys(), key=lambda x: int(x) if x.isdigit() else float('inf'))
|
||||
except ValueError:
|
||||
sorted_uids_for_pass = sorted(all_logic_steps.keys())
|
||||
|
||||
for part_uid in sorted_uids_for_pass:
|
||||
if part_uid not in all_logic_steps: continue # Seguridad
|
||||
instruction = all_logic_steps[part_uid]
|
||||
part_type = instruction['type']
|
||||
|
||||
if part_type in functional_block_types and 'en' not in instruction['inputs'] and part_uid not in processed_blocks_en_inference:
|
||||
# print(f"DEBUG: Intentando inferir EN para {part_type} UID {part_uid}") # Debug
|
||||
inferred_en_source = None
|
||||
# Usar la lista ordenada por UID para buscar atrás
|
||||
my_index = -1
|
||||
current_logic_list = [all_logic_steps[uid] for uid in sorted_uids_for_pass if uid in all_logic_steps] # Lista actual ordenada
|
||||
for i, instr in enumerate(current_logic_list):
|
||||
if instr['instruction_uid'] == part_uid:
|
||||
my_index = i
|
||||
break
|
||||
|
||||
if my_index > 0:
|
||||
for i in range(my_index - 1, -1, -1):
|
||||
prev_instr = current_logic_list[i]
|
||||
prev_uid = prev_instr['instruction_uid']
|
||||
prev_type = prev_instr['type']
|
||||
if prev_type in rlo_generators:
|
||||
inferred_en_source = {'type': 'connection', 'source_instruction_uid': prev_uid, 'source_instruction_type': prev_type, 'source_pin': 'out'}
|
||||
# print(f"DEBUG: Inferido EN para {part_uid} desde RLO de {prev_type} {prev_uid}.out") # Debug
|
||||
break
|
||||
elif prev_type in functional_block_types:
|
||||
source_key_eno = (prev_uid, 'eno')
|
||||
# Verificar si el ENO del bloque anterior está conectado a *algo*
|
||||
if source_key_eno in source_connections:
|
||||
inferred_en_source = {'type': 'connection', 'source_instruction_uid': prev_uid, 'source_instruction_type': prev_type, 'source_pin': 'eno'}
|
||||
# print(f"DEBUG: Inferido EN para {part_uid} desde ENO de {prev_type} {prev_uid}.eno") # Debug
|
||||
break
|
||||
# Si no hay conexión ENO explícita, podríamos asumir que sigue el RLO del EN de ese bloque? Más complejo.
|
||||
# Por ahora, solo usamos ENO si está conectado.
|
||||
|
||||
if inferred_en_source:
|
||||
instruction['inputs']['en'] = inferred_en_source
|
||||
# print(f"INFO: Conexión EN inferida añadida a {part_type} UID {part_uid}") # Info
|
||||
processed_blocks_en_inference.add(part_uid)
|
||||
something_changed = True
|
||||
# else:
|
||||
# print(f"DEBUG: No se pudo inferir EN para {part_type} UID {part_uid}") # Debug
|
||||
|
||||
|
||||
# --- 5. Añadir lógica ENO interesante ---
|
||||
for source_instr_uid, eno_destinations in eno_outputs.items():
|
||||
if source_instr_uid not in all_logic_steps: continue # Seguridad
|
||||
|
||||
if source_instr_uid not in all_logic_steps: continue
|
||||
interesting_eno_logic = []
|
||||
for dest_uid, dest_pin in eno_destinations:
|
||||
# Determinar si es una conexión directa a EN de otra instrucción
|
||||
is_direct_en_connection = (dest_uid in parts_map and dest_pin == 'en')
|
||||
|
||||
if not is_direct_en_connection:
|
||||
# Si NO es directa a EN, es "interesante"
|
||||
target_info = {'target_pin': dest_pin}
|
||||
if dest_uid in parts_map:
|
||||
target_info['target_type'] = 'instruction'
|
||||
target_info['target_uid'] = dest_uid
|
||||
target_info['target_name'] = parts_map[dest_uid]['name']
|
||||
elif dest_uid in access_map:
|
||||
# El destino es una variable o constante
|
||||
target_info['target_type'] = 'operand'
|
||||
target_info['target_details'] = access_map[dest_uid] # Incluye toda la info del Access
|
||||
else:
|
||||
target_info['target_type'] = 'unknown'
|
||||
target_info['target_uid'] = dest_uid
|
||||
|
||||
if dest_uid in parts_map: target_info.update({'target_type': 'instruction', 'target_uid': dest_uid, 'target_name': parts_map[dest_uid]['name']})
|
||||
elif dest_uid in access_map: target_info.update({'target_type': 'operand', 'target_details': access_map[dest_uid]})
|
||||
else: target_info.update({'target_type': 'unknown', 'target_uid': dest_uid})
|
||||
interesting_eno_logic.append(target_info)
|
||||
# print(f"DEBUG: Red {network_id} - ENO de {source_instr_uid}: Lógica interesante -> {target_info}")
|
||||
|
||||
# Añadir la lista de lógica ENO interesante a la instrucción fuente, si existe
|
||||
if interesting_eno_logic:
|
||||
all_logic_steps[source_instr_uid]['eno_logic'] = interesting_eno_logic
|
||||
# print(f"DEBUG: Red {network_id} - Añadida lógica ENO interesante para {source_instr_uid}") # Debug
|
||||
|
||||
|
||||
# 4. Ordenar y finalizar
|
||||
try:
|
||||
sorted_uids = sorted(all_logic_steps.keys(), key=lambda x: int(x) if x.isdigit() else float('inf'))
|
||||
except ValueError:
|
||||
print(f"Advertencia: UIDs no puramente numéricos en red {network_id}. Ordenando alfabéticamente.")
|
||||
sorted_uids = sorted(all_logic_steps.keys())
|
||||
|
||||
# --- 6. Ordenar Lógica Final y Devolver ---
|
||||
try: sorted_uids = sorted(all_logic_steps.keys(), key=lambda x: int(x) if x.isdigit() else float('inf'))
|
||||
except ValueError: print(f"Advertencia: UIDs no numéricos red {network_id}. Orden alfabético."); sorted_uids = sorted(all_logic_steps.keys())
|
||||
network_logic = [all_logic_steps[uid] for uid in sorted_uids if uid in all_logic_steps]
|
||||
|
||||
# Devolver estructura de red con ID, título, comentario y lógica
|
||||
# print(f"--- Fin Parseo Red ID={network_id} ---") # Debug
|
||||
return {'id': network_id, 'title': network_title, 'comment': network_comment, 'logic': network_logic}
|
||||
|
||||
|
||||
# --- Función Principal convert_xml_to_json (sin cambios respecto a la versión anterior) ---
|
||||
def convert_xml_to_json(xml_filepath, json_filepath):
|
||||
"""
|
||||
Función principal que orquesta la conversión del archivo XML de Openness
|
||||
a un archivo JSON simplificado que representa la estructura del bloque FC,
|
||||
incluyendo comentarios y lógica ENO no trivial.
|
||||
incluyendo comentarios, inferencia EN y lógica ENO no trivial.
|
||||
"""
|
||||
print(f"Iniciando conversión de '{xml_filepath}' a '{json_filepath}'...")
|
||||
|
||||
if not os.path.exists(xml_filepath):
|
||||
print(f"Error Crítico: Archivo XML no encontrado en '{xml_filepath}'")
|
||||
return
|
||||
if not os.path.exists(xml_filepath): print(f"Error Crítico: Archivo XML no encontrado: '{xml_filepath}'"); return
|
||||
|
||||
try:
|
||||
print("Paso 1: Parseando archivo XML...")
|
||||
parser = etree.XMLParser(remove_blank_text=True)
|
||||
tree = etree.parse(xml_filepath, parser)
|
||||
root = tree.getroot()
|
||||
print("Paso 1: Parseo XML completado.")
|
||||
|
||||
print("Paso 2: Buscando el bloque SW.Blocks.FC...")
|
||||
fc_block_list = root.xpath("//*[local-name()='SW.Blocks.FC']")
|
||||
if not fc_block_list:
|
||||
print("Error Crítico: No se encontró el elemento <SW.Blocks.FC> en el archivo.")
|
||||
return
|
||||
fc_block = fc_block_list[0]
|
||||
print(f"Paso 2: Bloque SW.Blocks.FC encontrado (ID={fc_block.get('ID')}).")
|
||||
|
||||
print("Paso 3: Extrayendo atributos del bloque...")
|
||||
attribute_list_node = fc_block.xpath("./*[local-name()='AttributeList']")
|
||||
block_name_val = "Unknown"
|
||||
block_number_val = None
|
||||
block_lang_val = "Unknown"
|
||||
print("Paso 1: Parseando archivo XML..."); parser = etree.XMLParser(remove_blank_text=True); tree = etree.parse(xml_filepath, parser); root = tree.getroot(); print("Paso 1: Parseo XML completado.")
|
||||
print("Paso 2: Buscando el bloque SW.Blocks.FC..."); fc_block_list = root.xpath("//*[local-name()='SW.Blocks.FC']");
|
||||
if not fc_block_list: print("Error Crítico: No se encontró <SW.Blocks.FC>."); return
|
||||
fc_block = fc_block_list[0]; print(f"Paso 2: Bloque SW.Blocks.FC encontrado (ID={fc_block.get('ID')}).")
|
||||
print("Paso 3: Extrayendo atributos del bloque..."); attribute_list_node = fc_block.xpath("./*[local-name()='AttributeList']")
|
||||
block_name_val, block_number_val, block_lang_val = "Unknown", None, "Unknown"
|
||||
if attribute_list_node:
|
||||
attr_list = attribute_list_node[0]
|
||||
name_node = attr_list.xpath("./*[local-name()='Name']/text()")
|
||||
if name_node: block_name_val = name_node[0].strip()
|
||||
num_node = attr_list.xpath("./*[local-name()='Number']/text()")
|
||||
if num_node and num_node[0].isdigit(): block_number_val = int(num_node[0])
|
||||
lang_node = attr_list.xpath("./*[local-name()='ProgrammingLanguage']/text()")
|
||||
if lang_node: block_lang_val = lang_node[0].strip()
|
||||
print(f"Paso 3: Atributos extraídos: Nombre='{block_name_val}', Número={block_number_val}, Lenguaje='{block_lang_val}'")
|
||||
name_node = attr_list.xpath("./*[local-name()='Name']/text()"); block_name_val = name_node[0].strip() if name_node else block_name_val
|
||||
num_node = attr_list.xpath("./*[local-name()='Number']/text()"); block_number_val = int(num_node[0]) if num_node and num_node[0].isdigit() else block_number_val
|
||||
lang_node = attr_list.xpath("./*[local-name()='ProgrammingLanguage']/text()"); block_lang_val = lang_node[0].strip() if lang_node else block_lang_val
|
||||
print(f"Paso 3: Atributos: Nombre='{block_name_val}', Número={block_number_val}, Lenguaje='{block_lang_val}'")
|
||||
else: print("Advertencia: No se encontró AttributeList para el bloque FC.")
|
||||
|
||||
# *** NUEVO: Extraer comentario del bloque ***
|
||||
block_comment_val = ""
|
||||
# El comentario del bloque suele estar en ObjectList > MultilingualText[@CompositionName='Comment']
|
||||
comment_node_list = fc_block.xpath("./*[local-name()='ObjectList']/*[local-name()='MultilingualText'][@CompositionName='Comment']")
|
||||
if comment_node_list:
|
||||
block_comment_val = get_multilingual_text(comment_node_list[0])
|
||||
print(f"Paso 3b: Comentario del bloque extraído: '{block_comment_val[:50]}...'")
|
||||
|
||||
|
||||
result = {
|
||||
"block_name": block_name_val,
|
||||
"block_number": block_number_val,
|
||||
"language": block_lang_val,
|
||||
"block_comment": block_comment_val, # Añadido comentario del bloque
|
||||
"interface": {},
|
||||
"networks": []
|
||||
}
|
||||
|
||||
block_comment_val = ""; comment_node_list = fc_block.xpath("./*[local-name()='ObjectList']/*[local-name()='MultilingualText'][@CompositionName='Comment']")
|
||||
if comment_node_list: block_comment_val = get_multilingual_text(comment_node_list[0]); print(f"Paso 3b: Comentario bloque: '{block_comment_val[:50]}...'")
|
||||
result = {"block_name": block_name_val, "block_number": block_number_val, "language": block_lang_val, "block_comment": block_comment_val, "interface": {}, "networks": []}
|
||||
print("Paso 4: Extrayendo la interfaz del bloque...")
|
||||
interface_found = False
|
||||
if attribute_list_node:
|
||||
interface_node_list = attribute_list_node[0].xpath("./*[local-name()='Interface']")
|
||||
if interface_node_list:
|
||||
interface_node = interface_node_list[0]
|
||||
interface_found = True
|
||||
print("Paso 4: Nodo Interface encontrado dentro de AttributeList.")
|
||||
interface_node = interface_node_list[0]; print("Paso 4: Nodo Interface encontrado.")
|
||||
for section in interface_node.xpath(".//iface:Section", namespaces=ns):
|
||||
section_name = section.get('Name')
|
||||
members = []
|
||||
section_name = section.get('Name'); members = []
|
||||
for member in section.xpath("./iface:Member", namespaces=ns):
|
||||
member_name = member.get('Name')
|
||||
member_dtype = member.get('Datatype')
|
||||
member_name = member.get('Name'); member_dtype = member.get('Datatype')
|
||||
if member_name and member_dtype: members.append({"name": member_name, "datatype": member_dtype})
|
||||
if members: result["interface"][section_name] = members
|
||||
if not result["interface"]: print("Advertencia: Nodo Interface encontrado, pero no contenía secciones iface:Section válidas.")
|
||||
else: print("Advertencia: No se encontró el nodo <Interface> DENTRO de <AttributeList>.")
|
||||
if not result["interface"]: print("Advertencia: Interface sin secciones iface:Section válidas.")
|
||||
else: print("Advertencia: No se encontró <Interface> DENTRO de <AttributeList>.")
|
||||
if not result["interface"]: print("Advertencia: No se pudo extraer información de la interfaz.")
|
||||
|
||||
if not interface_found and not result["interface"]: print("Advertencia: No se pudo extraer ninguna información de la interfaz.")
|
||||
|
||||
print("Paso 5: Extrayendo la lógica de las redes (CompileUnits)...")
|
||||
print("Paso 5: Extrayendo y PROCESANDO lógica de redes (CompileUnits)...")
|
||||
networks_processed_count = 0
|
||||
object_list_node = fc_block.xpath("./*[local-name()='ObjectList']")
|
||||
if object_list_node:
|
||||
|
@ -420,39 +407,30 @@ def convert_xml_to_json(xml_filepath, json_filepath):
|
|||
print(f"Paso 5: Se encontraron {len(compile_units)} elementos SW.Blocks.CompileUnit.")
|
||||
for network_elem in compile_units:
|
||||
networks_processed_count += 1
|
||||
print(f"DEBUG: Procesando red #{networks_processed_count} (ID={network_elem.get('ID')})...")
|
||||
parsed_network = parse_network(network_elem) # Ahora parse_network incluye comentario
|
||||
# print(f"DEBUG: Procesando red #{networks_processed_count} (ID={network_elem.get('ID')})...")
|
||||
parsed_network = parse_network(network_elem) # Llamada a la función modificada
|
||||
if parsed_network and parsed_network.get('error') is None: result["networks"].append(parsed_network)
|
||||
elif parsed_network:
|
||||
print(f"Error: Falló el parseo de la red ID={parsed_network.get('id')}: {parsed_network.get('error')}")
|
||||
result["networks"].append(parsed_network)
|
||||
else: print(f"Error: parse_network devolvió None para un CompileUnit (ID={network_elem.get('ID')}).")
|
||||
if networks_processed_count == 0: print("Advertencia: ObjectList encontrado, pero no contenía SW.Blocks.CompileUnit.")
|
||||
else: print("Advertencia: No se encontró ObjectList para el bloque FC.")
|
||||
elif parsed_network: print(f"Error: Falló parseo red ID={parsed_network.get('id')}: {parsed_network.get('error')}"); result["networks"].append(parsed_network)
|
||||
else: print(f"Error: parse_network devolvió None para CompileUnit (ID={network_elem.get('ID')}).")
|
||||
if networks_processed_count == 0: print("Advertencia: ObjectList sin SW.Blocks.CompileUnit.")
|
||||
else: print("Advertencia: No se encontró ObjectList.")
|
||||
|
||||
print("Paso 6: Escribiendo el resultado en el archivo JSON...")
|
||||
# Chequeos finales
|
||||
if not result["interface"]: print("ADVERTENCIA FINAL: La sección 'interface' está vacía.")
|
||||
if not result["networks"]: print("ADVERTENCIA FINAL: La sección 'networks' está vacía.")
|
||||
else:
|
||||
# Chequea si alguna instrucción tiene lógica ENO interesante
|
||||
eno_logic_found = any(instr.get('eno_logic') for net in result.get('networks', []) if net.get('error') is None for instr in net.get('logic', []))
|
||||
if eno_logic_found: print("INFO FINAL: Se detectó lógica ENO interesante en al menos una instrucción.")
|
||||
else: print("INFO FINAL: No se detectó lógica ENO interesante (solo conexiones directas ENO->EN o ENO no conectado).")
|
||||
if not result["interface"]: print("ADVERTENCIA FINAL: 'interface' está vacía.")
|
||||
if not result["networks"]: print("ADVERTENCIA FINAL: 'networks' está vacía.")
|
||||
# else: # Chequeo ENO logic
|
||||
# eno_logic_found = any(instr.get('eno_logic') for net in result.get('networks', []) if net.get('error') is None for instr in net.get('logic', []))
|
||||
# if eno_logic_found: print("INFO FINAL: Lógica ENO interesante detectada.")
|
||||
# else: print("INFO FINAL: No se detectó lógica ENO interesante.")
|
||||
|
||||
try:
|
||||
with open(json_filepath, 'w', encoding='utf-8') as f:
|
||||
json.dump(result, f, indent=4, ensure_ascii=False)
|
||||
print(f"Paso 6: Escritura completada.")
|
||||
print(f"Conversión finalizada con éxito. Archivo JSON guardado en: '{json_filepath}'")
|
||||
except IOError as e: print(f"Error Crítico: No se pudo escribir el archivo JSON en '{json_filepath}'. Error: {e}")
|
||||
except TypeError as e: print(f"Error Crítico: Problema al serializar datos a JSON. Error: {e}")
|
||||
with open(json_filepath, 'w', encoding='utf-8') as f: json.dump(result, f, indent=4, ensure_ascii=False)
|
||||
print(f"Paso 6: Escritura completada."); print(f"Conversión finalizada. JSON guardado en: '{json_filepath}'")
|
||||
except IOError as e: print(f"Error Crítico: No se pudo escribir JSON en '{json_filepath}'. Error: {e}")
|
||||
except TypeError as e: print(f"Error Crítico: Problema al serializar a JSON. Error: {e}")
|
||||
|
||||
except etree.XMLSyntaxError as e:
|
||||
print(f"Error Crítico: Error de sintaxis en el archivo XML '{xml_filepath}'. Detalles: {e}")
|
||||
except Exception as e:
|
||||
print(f"Error Crítico: Ocurrió un error inesperado durante el procesamiento: {e}")
|
||||
print("--- Traceback ---"); traceback.print_exc(); print("--- Fin Traceback ---")
|
||||
except etree.XMLSyntaxError as e: print(f"Error Crítico: Sintaxis XML en '{xml_filepath}'. Detalles: {e}")
|
||||
except Exception as e: print(f"Error Crítico: Error inesperado: {e}"); print("--- Traceback ---"); traceback.print_exc(); print("--- Fin Traceback ---")
|
||||
|
||||
# --- Punto de Entrada Principal ---
|
||||
if __name__ == "__main__":
|
||||
|
|
1270
x2_process.py
1270
x2_process.py
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue