diff --git a/.vci/workspace.vci.config b/.vci/workspace.vci.config
new file mode 100644
index 0000000..8f032fd
--- /dev/null
+++ b/.vci/workspace.vci.config
@@ -0,0 +1 @@
+en-US
\ No newline at end of file
diff --git a/BlenderCtrl__Main_simplified.json b/BlenderCtrl__Main_simplified.json
index 45f937b..67f545b 100644
--- a/BlenderCtrl__Main_simplified.json
+++ b/BlenderCtrl__Main_simplified.json
@@ -92,6 +92,7 @@
"uid": "25",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -112,6 +113,7 @@
"template_values": {
"blk_type": "Type"
},
+ "negated_pins": {},
"inputs": {
"en": {
"type": "connection",
@@ -134,6 +136,7 @@
"uid": "24",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -152,18 +155,19 @@
"uid": "25",
"type": "NBox",
"template_values": {},
+ "negated_pins": {},
"inputs": {
- "in": {
- "type": "connection",
- "source_instruction_type": "Contact",
- "source_instruction_uid": "24",
- "source_pin": "out"
- },
"bit": {
"uid": "22",
"scope": "GlobalVariable",
"type": "variable",
"name": "\"M19000\""
+ },
+ "in": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "24",
+ "source_pin": "out"
}
},
"outputs": {}
@@ -173,6 +177,7 @@
"uid": "26",
"type": "Coil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "23",
@@ -201,6 +206,7 @@
"uid": "29",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -219,6 +225,7 @@
"uid": "30",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -234,6 +241,9 @@
"uid": "31",
"type": "Contact",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "23",
@@ -255,6 +265,9 @@
"uid": "32",
"type": "Contact",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "24",
@@ -278,6 +291,7 @@
"template_values": {
"Card": "Cardinality"
},
+ "negated_pins": {},
"inputs": {
"in2": {
"type": "connection",
@@ -299,6 +313,7 @@
"uid": "34",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "25",
@@ -320,6 +335,9 @@
"uid": "35",
"type": "Contact",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "26",
@@ -337,6 +355,7 @@
"template_values": {
"Card": "Cardinality"
},
+ "negated_pins": {},
"inputs": {
"in2": {
"type": "connection",
@@ -358,6 +377,7 @@
"uid": "37",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "27",
@@ -379,6 +399,7 @@
"uid": "38",
"type": "Coil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "28",
@@ -409,6 +430,7 @@
"template_values": {
"Card": "Cardinality"
},
+ "negated_pins": {},
"inputs": {
"in": {
"uid": "21",
@@ -444,6 +466,7 @@
"uid": "24",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -462,6 +485,7 @@
"uid": "25",
"type": "Se",
"template_values": {},
+ "negated_pins": {},
"inputs": {},
"outputs": {}
}
@@ -477,6 +501,7 @@
"uid": "23",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -495,6 +520,7 @@
"uid": "24",
"type": "Coil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -523,6 +549,9 @@
"uid": "25",
"type": "Contact",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "21",
@@ -541,6 +570,7 @@
"uid": "26",
"type": "Coil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -564,6 +594,7 @@
"template_values": {
"Card": "Cardinality"
},
+ "negated_pins": {},
"inputs": {
"in": {
"uid": "23",
@@ -602,6 +633,9 @@
"uid": "26",
"type": "Contact",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "21",
@@ -620,6 +654,7 @@
"uid": "27",
"type": "RCoil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -641,6 +676,7 @@
"uid": "28",
"type": "RCoil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "23",
@@ -656,6 +692,7 @@
"uid": "29",
"type": "RCoil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "24",
@@ -671,6 +708,7 @@
"uid": "30",
"type": "RCoil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "25",
@@ -693,6 +731,9 @@
"uid": "23",
"type": "Contact",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "21",
@@ -711,6 +752,7 @@
"uid": "24",
"type": "Coil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -739,6 +781,7 @@
"uid": "27",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -757,6 +800,7 @@
"uid": "28",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -772,6 +816,9 @@
"uid": "29",
"type": "Contact",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "23",
@@ -795,6 +842,7 @@
"template_values": {
"Card": "Cardinality"
},
+ "negated_pins": {},
"inputs": {
"in2": {
"type": "connection",
@@ -816,6 +864,7 @@
"uid": "31",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "24",
@@ -837,6 +886,9 @@
"uid": "32",
"type": "Contact",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "25",
@@ -858,6 +910,7 @@
"uid": "33",
"type": "Coil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "26",
@@ -886,6 +939,7 @@
"uid": "26",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -904,6 +958,7 @@
"uid": "27",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -925,6 +980,7 @@
"uid": "28",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "23",
@@ -946,6 +1002,9 @@
"uid": "29",
"type": "Contact",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "24",
@@ -967,6 +1026,7 @@
"uid": "30",
"type": "Coil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "25",
@@ -995,6 +1055,7 @@
"uid": "30",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -1013,6 +1074,9 @@
"uid": "31",
"type": "Contact",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "22",
@@ -1034,6 +1098,9 @@
"uid": "32",
"type": "Contact",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "23",
@@ -1055,6 +1122,7 @@
"uid": "33",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "24",
@@ -1076,6 +1144,9 @@
"uid": "34",
"type": "Contact",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "25",
@@ -1097,6 +1168,7 @@
"uid": "35",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "26",
@@ -1112,6 +1184,7 @@
"uid": "36",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "27",
@@ -1133,6 +1206,7 @@
"uid": "37",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "28",
@@ -1156,6 +1230,7 @@
"template_values": {
"Card": "Cardinality"
},
+ "negated_pins": {},
"inputs": {
"in2": {
"type": "connection",
@@ -1177,6 +1252,7 @@
"uid": "39",
"type": "Coil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "29",
@@ -1205,6 +1281,7 @@
"uid": "25",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -1223,6 +1300,7 @@
"uid": "26",
"type": "Sd",
"template_values": {},
+ "negated_pins": {},
"inputs": {},
"outputs": {}
},
@@ -1231,6 +1309,7 @@
"uid": "27",
"type": "Coil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "24",
@@ -1259,6 +1338,7 @@
"uid": "24",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -1279,13 +1359,8 @@
"template_values": {
"SrcType": "Type"
},
+ "negated_pins": {},
"inputs": {
- "pre": {
- "type": "connection",
- "source_instruction_type": "Contact",
- "source_instruction_uid": "24",
- "source_pin": "out"
- },
"in2": {
"uid": "23",
"scope": "LiteralConstant",
@@ -1298,6 +1373,12 @@
"scope": "GlobalVariable",
"type": "variable",
"name": "\"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_MeterType\""
+ },
+ "pre": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "24",
+ "source_pin": "out"
}
},
"outputs": {}
@@ -1330,6 +1411,7 @@
"uid": "24",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -1350,13 +1432,8 @@
"template_values": {
"SrcType": "Type"
},
+ "negated_pins": {},
"inputs": {
- "pre": {
- "type": "connection",
- "source_instruction_type": "Contact",
- "source_instruction_uid": "24",
- "source_pin": "out"
- },
"in2": {
"uid": "23",
"scope": "LiteralConstant",
@@ -1369,6 +1446,12 @@
"scope": "GlobalVariable",
"type": "variable",
"name": "\"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_MeterType\""
+ },
+ "pre": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "24",
+ "source_pin": "out"
}
},
"outputs": {}
@@ -1401,6 +1484,7 @@
"uid": "22",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -1442,6 +1526,7 @@
"uid": "24",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -1462,13 +1547,8 @@
"template_values": {
"SrcType": "Type"
},
+ "negated_pins": {},
"inputs": {
- "pre": {
- "type": "connection",
- "source_instruction_type": "Contact",
- "source_instruction_uid": "24",
- "source_pin": "out"
- },
"in2": {
"uid": "23",
"scope": "LiteralConstant",
@@ -1481,6 +1561,12 @@
"scope": "GlobalVariable",
"type": "variable",
"name": "\"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_MeterType\""
+ },
+ "pre": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "24",
+ "source_pin": "out"
}
},
"outputs": {}
@@ -1574,6 +1660,7 @@
"uid": "22",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -1635,6 +1722,7 @@
"uid": "25",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -1653,18 +1741,19 @@
"uid": "26",
"type": "PBox",
"template_values": {},
+ "negated_pins": {},
"inputs": {
- "in": {
- "type": "connection",
- "source_instruction_type": "Contact",
- "source_instruction_uid": "25",
- "source_pin": "out"
- },
"bit": {
"uid": "22",
"scope": "GlobalVariable",
"type": "variable",
"name": "\"M19001\""
+ },
+ "in": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "25",
+ "source_pin": "out"
}
},
"outputs": {}
@@ -1674,6 +1763,9 @@
"uid": "27",
"type": "Contact",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "23",
@@ -1695,6 +1787,7 @@
"uid": "28",
"type": "Coil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "24",
@@ -1723,6 +1816,7 @@
"uid": "24",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -1741,6 +1835,7 @@
"uid": "25",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -1758,6 +1853,7 @@
"template_values": {
"Card": "Cardinality"
},
+ "negated_pins": {},
"inputs": {
"in2": {
"type": "connection",
@@ -1779,6 +1875,9 @@
"uid": "27",
"type": "Contact",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "23",
@@ -1823,6 +1922,7 @@
"uid": "25",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -1841,18 +1941,19 @@
"uid": "26",
"type": "PBox",
"template_values": {},
+ "negated_pins": {},
"inputs": {
- "in": {
- "type": "connection",
- "source_instruction_type": "Contact",
- "source_instruction_uid": "25",
- "source_pin": "out"
- },
"bit": {
"uid": "22",
"scope": "GlobalVariable",
"type": "variable",
"name": "\"M19002\""
+ },
+ "in": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "25",
+ "source_pin": "out"
}
},
"outputs": {}
@@ -1862,6 +1963,9 @@
"uid": "27",
"type": "Contact",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "23",
@@ -1883,6 +1987,7 @@
"uid": "28",
"type": "Coil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "24",
@@ -1911,6 +2016,7 @@
"uid": "25",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -1929,18 +2035,19 @@
"uid": "26",
"type": "PBox",
"template_values": {},
+ "negated_pins": {},
"inputs": {
- "in": {
- "type": "connection",
- "source_instruction_type": "Contact",
- "source_instruction_uid": "25",
- "source_pin": "out"
- },
"bit": {
"uid": "22",
"scope": "GlobalVariable",
"type": "variable",
"name": "\"M19003\""
+ },
+ "in": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "25",
+ "source_pin": "out"
}
},
"outputs": {}
@@ -1950,6 +2057,9 @@
"uid": "27",
"type": "Contact",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "23",
@@ -1971,6 +2081,7 @@
"uid": "28",
"type": "Coil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "24",
@@ -1999,6 +2110,7 @@
"uid": "22",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -2261,6 +2373,9 @@
"uid": "22",
"type": "Contact",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "21",
@@ -2343,6 +2458,7 @@
"uid": "22",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -2484,6 +2600,7 @@
"uid": "24",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -2502,6 +2619,7 @@
"uid": "25",
"type": "Se",
"template_values": {},
+ "negated_pins": {},
"inputs": {},
"outputs": {}
}
@@ -2517,6 +2635,7 @@
"uid": "26",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -2535,6 +2654,7 @@
"uid": "27",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -2552,6 +2672,7 @@
"template_values": {
"Card": "Cardinality"
},
+ "negated_pins": {},
"inputs": {
"in2": {
"type": "connection",
@@ -2573,6 +2694,7 @@
"uid": "29",
"type": "Se",
"template_values": {},
+ "negated_pins": {},
"inputs": {},
"outputs": {}
},
@@ -2581,6 +2703,7 @@
"uid": "30",
"type": "Coil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "25",
@@ -2609,6 +2732,7 @@
"uid": "23",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -2627,6 +2751,7 @@
"uid": "24",
"type": "RCoil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -2655,6 +2780,7 @@
"uid": "27",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -2673,6 +2799,7 @@
"uid": "28",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -2690,6 +2817,7 @@
"template_values": {
"Card": "Cardinality"
},
+ "negated_pins": {},
"inputs": {
"in2": {
"type": "connection",
@@ -2711,6 +2839,7 @@
"uid": "30",
"type": "Se",
"template_values": {},
+ "negated_pins": {},
"inputs": {},
"outputs": {}
},
@@ -2719,6 +2848,7 @@
"uid": "31",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "25",
@@ -2740,6 +2870,7 @@
"uid": "32",
"type": "Coil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "26",
@@ -2768,6 +2899,7 @@
"uid": "23",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -2786,6 +2918,7 @@
"uid": "24",
"type": "RCoil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -2814,6 +2947,7 @@
"uid": "26",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -2832,6 +2966,7 @@
"uid": "27",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -2849,6 +2984,7 @@
"template_values": {
"Card": "Cardinality"
},
+ "negated_pins": {},
"inputs": {
"in2": {
"type": "connection",
@@ -2870,6 +3006,7 @@
"uid": "29",
"type": "Se",
"template_values": {},
+ "negated_pins": {},
"inputs": {},
"outputs": {}
},
@@ -2878,6 +3015,7 @@
"uid": "30",
"type": "Coil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "25",
@@ -2906,6 +3044,7 @@
"uid": "23",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -2924,6 +3063,7 @@
"uid": "24",
"type": "RCoil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -2952,6 +3092,7 @@
"uid": "26",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -2970,6 +3111,7 @@
"uid": "27",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -2987,6 +3129,7 @@
"template_values": {
"Card": "Cardinality"
},
+ "negated_pins": {},
"inputs": {
"in2": {
"type": "connection",
@@ -3008,6 +3151,7 @@
"uid": "29",
"type": "Se",
"template_values": {},
+ "negated_pins": {},
"inputs": {},
"outputs": {}
},
@@ -3016,6 +3160,7 @@
"uid": "30",
"type": "Coil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "25",
@@ -3044,6 +3189,7 @@
"uid": "23",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -3062,6 +3208,7 @@
"uid": "24",
"type": "RCoil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -3090,6 +3237,7 @@
"uid": "23",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -3108,6 +3256,7 @@
"uid": "24",
"type": "RCoil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -3136,6 +3285,9 @@
"uid": "26",
"type": "Contact",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "21",
@@ -3237,6 +3389,7 @@
"uid": "25",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -3255,6 +3408,7 @@
"uid": "26",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -3276,18 +3430,19 @@
"uid": "27",
"type": "NBox",
"template_values": {},
+ "negated_pins": {},
"inputs": {
- "in": {
- "type": "connection",
- "source_instruction_type": "Contact",
- "source_instruction_uid": "26",
- "source_pin": "out"
- },
"bit": {
"uid": "23",
"scope": "GlobalVariable",
"type": "variable",
"name": "\"M19011\""
+ },
+ "in": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "26",
+ "source_pin": "out"
}
},
"outputs": {}
@@ -3313,6 +3468,7 @@
"uid": "29",
"type": "Coil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "24",
@@ -3355,6 +3511,7 @@
"uid": "33",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -3373,6 +3530,9 @@
"uid": "34",
"type": "Contact",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "22",
@@ -3394,6 +3554,7 @@
"uid": "35",
"type": "Coil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "23",
@@ -3415,6 +3576,7 @@
"uid": "36",
"type": "Coil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "24",
@@ -3430,6 +3592,7 @@
"uid": "37",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "25",
@@ -3445,6 +3608,7 @@
"uid": "38",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "26",
@@ -3466,6 +3630,7 @@
"uid": "39",
"type": "SdCoil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "27",
@@ -3487,6 +3652,7 @@
"uid": "40",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "29",
@@ -3508,6 +3674,7 @@
"uid": "41",
"type": "RCoil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "30",
@@ -3529,6 +3696,7 @@
"uid": "42",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "31",
@@ -3544,6 +3712,7 @@
"uid": "43",
"type": "SCoil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "32",
@@ -3572,6 +3741,7 @@
"uid": "42",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
diff --git a/BlenderCtrl__Main_simplified_processed.json b/BlenderCtrl__Main_simplified_processed.json
index 5cb12f9..4adeb1e 100644
--- a/BlenderCtrl__Main_simplified_processed.json
+++ b/BlenderCtrl__Main_simplified_processed.json
@@ -59,7 +59,7 @@
}
},
"outputs": {},
- "scl": "Clock Signal();"
+ "scl": "Clock_Signal();"
}
]
},
@@ -94,6 +94,7 @@
"uid": "25",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -115,6 +116,7 @@
"template_values": {
"blk_type": "Type"
},
+ "negated_pins": {},
"inputs": {
"en": {
"type": "connection",
@@ -137,6 +139,7 @@
"uid": "24",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -156,18 +159,19 @@
"uid": "25",
"type": "NBox",
"template_values": {},
+ "negated_pins": {},
"inputs": {
- "in": {
- "type": "connection",
- "source_instruction_type": "Contact",
- "source_instruction_uid": "24",
- "source_pin": "out"
- },
"bit": {
"uid": "22",
"scope": "GlobalVariable",
"type": "variable",
"name": "\"M19000\""
+ },
+ "in": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "24",
+ "source_pin": "out"
}
},
"outputs": {}
@@ -177,6 +181,7 @@
"uid": "26",
"type": "Coil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "23",
@@ -205,6 +210,7 @@
"uid": "29",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -224,6 +230,7 @@
"uid": "30",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -240,6 +247,9 @@
"uid": "31",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "23",
@@ -255,13 +265,16 @@
}
},
"outputs": {},
- "scl": "// RLO: \"gWorkshopTest\" AND \"gWorkshop_Co2_Presence\""
+ "scl": "// RLO: \"gWorkshopTest\" AND (NOT \"gWorkshop_Co2_Presence\")"
},
{
"instruction_uid": "32",
"uid": "32",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "24",
@@ -277,7 +290,7 @@
}
},
"outputs": {},
- "scl": "// RLO: (\"gWorkshopTest\" AND \"gWorkshop_Co2_Presence\") AND \"gWorkshop_CIP_Signals\""
+ "scl": "// RLO: (\"gWorkshopTest\" AND (NOT \"gWorkshop_Co2_Presence\")) AND (NOT \"gWorkshop_CIP_Signals\")"
},
{
"instruction_uid": "33",
@@ -286,6 +299,7 @@
"template_values": {
"Card": "Cardinality"
},
+ "negated_pins": {},
"inputs": {
"in2": {
"type": "connection",
@@ -301,13 +315,14 @@
}
},
"outputs": {},
- "scl": "// Logic O 33: \"gIN_LinePressCO2Ok\" OR ((\"gWorkshopTest\" AND \"gWorkshop_Co2_Presence\") AND \"gWorkshop_CIP_Signals\")"
+ "scl": "// Logic O 33: \"gIN_LinePressCO2Ok\" OR (\"gWorkshopTest\" AND (NOT \"gWorkshop_Co2_Presence\")) AND (NOT \"gWorkshop_CIP_Signals\")"
},
{
"instruction_uid": "34",
"uid": "34",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "25",
@@ -323,13 +338,16 @@
}
},
"outputs": {},
- "scl": "// RLO: (\"gIN_LinePressCO2Ok\" OR ((\"gWorkshopTest\" AND \"gWorkshop_Co2_Presence\") AND \"gWorkshop_CIP_Signals\")) AND \"HMI_Digital\".\"_PAL_S11\".\"Filtered\""
+ "scl": "// RLO: (\"gIN_LinePressCO2Ok\" OR (\"gWorkshopTest\" AND (NOT \"gWorkshop_Co2_Presence\")) AND (NOT \"gWorkshop_CIP_Signals\")) AND \"HMI_Digital\".\"_PAL_S11\".\"Filtered\""
},
{
"instruction_uid": "35",
"uid": "35",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "26",
@@ -339,7 +357,7 @@
}
},
"outputs": {},
- "scl": "// RLO: \"Disable_Bit\""
+ "scl": "// RLO: (NOT \"Disable_Bit\")"
},
{
"instruction_uid": "36",
@@ -348,6 +366,7 @@
"template_values": {
"Card": "Cardinality"
},
+ "negated_pins": {},
"inputs": {
"in2": {
"type": "connection",
@@ -363,13 +382,14 @@
}
},
"outputs": {},
- "scl": "// Logic O 36: ((\"gIN_LinePressCO2Ok\" OR ((\"gWorkshopTest\" AND \"gWorkshop_Co2_Presence\") AND \"gWorkshop_CIP_Signals\")) AND \"HMI_Digital\".\"_PAL_S11\".\"Filtered\") OR \"Disable_Bit\""
+ "scl": "// Logic O 36: ((\"gIN_LinePressCO2Ok\" OR (\"gWorkshopTest\" AND (NOT \"gWorkshop_Co2_Presence\")) AND (NOT \"gWorkshop_CIP_Signals\")) AND \"HMI_Digital\".\"_PAL_S11\".\"Filtered\") OR (NOT \"Disable_Bit\")"
},
{
"instruction_uid": "37",
"uid": "37",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "27",
@@ -385,13 +405,14 @@
}
},
"outputs": {},
- "scl": "// RLO: (((\"gIN_LinePressCO2Ok\" OR ((\"gWorkshopTest\" AND \"gWorkshop_Co2_Presence\") AND \"gWorkshop_CIP_Signals\")) AND \"HMI_Digital\".\"_PAL_S11\".\"Filtered\") OR \"Disable_Bit\") AND \"gIN_VoltageOk\""
+ "scl": "// RLO: ((\"gIN_LinePressCO2Ok\" OR (\"gWorkshopTest\" AND (NOT \"gWorkshop_Co2_Presence\")) AND (NOT \"gWorkshop_CIP_Signals\")) AND \"HMI_Digital\".\"_PAL_S11\".\"Filtered\") OR (NOT \"Disable_Bit\") AND \"gIN_VoltageOk\""
},
{
"instruction_uid": "38",
"uid": "38",
"type": "Coil_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "28",
@@ -407,7 +428,7 @@
}
},
"outputs": {},
- "scl": "\"gBlenderSuppliesOk\" := (((\"gIN_LinePressCO2Ok\" OR ((\"gWorkshopTest\" AND \"gWorkshop_Co2_Presence\") AND \"gWorkshop_CIP_Signals\")) AND \"HMI_Digital\".\"_PAL_S11\".\"Filtered\") OR \"Disable_Bit\") AND \"gIN_VoltageOk\";"
+ "scl": "\"gBlenderSuppliesOk\" := ((\"gIN_LinePressCO2Ok\" OR (\"gWorkshopTest\" AND (NOT \"gWorkshop_Co2_Presence\")) AND (NOT \"gWorkshop_CIP_Signals\")) AND \"HMI_Digital\".\"_PAL_S11\".\"Filtered\") OR (NOT \"Disable_Bit\") AND \"gIN_VoltageOk\";"
}
]
},
@@ -423,6 +444,7 @@
"template_values": {
"Card": "Cardinality"
},
+ "negated_pins": {},
"inputs": {
"in": {
"uid": "21",
@@ -459,6 +481,7 @@
"uid": "24",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -478,6 +501,7 @@
"uid": "25",
"type": "Se",
"template_values": {},
+ "negated_pins": {},
"inputs": {},
"outputs": {}
}
@@ -493,6 +517,7 @@
"uid": "23",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -512,6 +537,7 @@
"uid": "24",
"type": "Coil_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -541,6 +567,9 @@
"uid": "25",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "21",
@@ -553,13 +582,14 @@
}
},
"outputs": {},
- "scl": "// RLO: \"HMI_Variables_Status\".\"System\".\"Blender_Prod_CIP\""
+ "scl": "// RLO: (NOT \"HMI_Variables_Status\".\"System\".\"Blender_Prod_CIP\")"
},
{
"instruction_uid": "26",
"uid": "26",
"type": "Coil_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -575,7 +605,7 @@
}
},
"outputs": {},
- "scl": "\"gBlenderCIPMode\" := \"HMI_Variables_Status\".\"System\".\"Blender_Prod_CIP\";"
+ "scl": "\"gBlenderCIPMode\" := (NOT \"HMI_Variables_Status\".\"System\".\"Blender_Prod_CIP\");"
},
{
"instruction_uid": "27",
@@ -584,6 +614,7 @@
"template_values": {
"Card": "Cardinality"
},
+ "negated_pins": {},
"inputs": {
"in": {
"uid": "23",
@@ -609,7 +640,7 @@
}
]
},
- "scl": "IF \"HMI_Variables_Status\".\"System\".\"Blender_Prod_CIP\" THEN\n \"HMI_Variables_Status\".\"Procedures\".\"BlenderStateNum\" := 19;\nEND_IF;"
+ "scl": "IF (NOT \"HMI_Variables_Status\".\"System\".\"Blender_Prod_CIP\") THEN\n \"HMI_Variables_Status\".\"Procedures\".\"BlenderStateNum\" := 19;\nEND_IF;"
}
]
},
@@ -623,6 +654,9 @@
"uid": "26",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "21",
@@ -635,13 +669,14 @@
}
},
"outputs": {},
- "scl": "// RLO: \"AUX FALSE\""
+ "scl": "// RLO: (NOT \"AUX FALSE\")"
},
{
"instruction_uid": "27",
"uid": "27",
"type": "RCoil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -663,6 +698,7 @@
"uid": "28",
"type": "RCoil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "23",
@@ -678,6 +714,7 @@
"uid": "29",
"type": "RCoil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "24",
@@ -693,6 +730,7 @@
"uid": "30",
"type": "RCoil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "25",
@@ -715,6 +753,9 @@
"uid": "23",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "21",
@@ -727,13 +768,14 @@
}
},
"outputs": {},
- "scl": "// RLO: \"System_RunOut_Variables\".\"ProdPipeRunOutWaterCount\""
+ "scl": "// RLO: (NOT \"System_RunOut_Variables\".\"ProdPipeRunOutWaterCount\")"
},
{
"instruction_uid": "24",
"uid": "24",
"type": "Coil_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -749,7 +791,7 @@
}
},
"outputs": {},
- "scl": "\"System_RunOut_Variables\".\"ProdPipeRunOutFillerBott\" := \"System_RunOut_Variables\".\"ProdPipeRunOutWaterCount\";"
+ "scl": "\"System_RunOut_Variables\".\"ProdPipeRunOutFillerBott\" := (NOT \"System_RunOut_Variables\".\"ProdPipeRunOutWaterCount\");"
}
]
},
@@ -763,6 +805,7 @@
"uid": "27",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -782,6 +825,7 @@
"uid": "28",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -798,6 +842,9 @@
"uid": "29",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "23",
@@ -813,7 +860,7 @@
}
},
"outputs": {},
- "scl": "// RLO: \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_ByPassDeair\" AND \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_Deaireation\""
+ "scl": "// RLO: \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_ByPassDeair\" AND (NOT \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_Deaireation\")"
},
{
"instruction_uid": "30",
@@ -822,6 +869,7 @@
"template_values": {
"Card": "Cardinality"
},
+ "negated_pins": {},
"inputs": {
"in2": {
"type": "connection",
@@ -837,13 +885,14 @@
}
},
"outputs": {},
- "scl": "// Logic O 30: \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_StillWaterByPass\" OR (\"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_ByPassDeair\" AND \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_Deaireation\")"
+ "scl": "// Logic O 30: \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_StillWaterByPass\" OR (\"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_ByPassDeair\" AND (NOT \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_Deaireation\"))"
},
{
"instruction_uid": "31",
"uid": "31",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "24",
@@ -859,13 +908,16 @@
}
},
"outputs": {},
- "scl": "// RLO: (\"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_StillWaterByPass\" OR (\"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_ByPassDeair\" AND \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_Deaireation\")) AND \"Blender_Variables_Pers\".\"gWaterRecipe\""
+ "scl": "// RLO: (\"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_StillWaterByPass\" OR (\"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_ByPassDeair\" AND (NOT \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_Deaireation\"))) AND \"Blender_Variables_Pers\".\"gWaterRecipe\""
},
{
"instruction_uid": "32",
"uid": "32",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "25",
@@ -881,13 +933,14 @@
}
},
"outputs": {},
- "scl": "// RLO: ((\"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_StillWaterByPass\" OR (\"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_ByPassDeair\" AND \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_Deaireation\")) AND \"Blender_Variables_Pers\".\"gWaterRecipe\") AND \"Blender_Variables_Pers\".\"gCarboStillRecipe\""
+ "scl": "// RLO: ((\"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_StillWaterByPass\" OR (\"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_ByPassDeair\" AND (NOT \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_Deaireation\"))) AND \"Blender_Variables_Pers\".\"gWaterRecipe\") AND (NOT \"Blender_Variables_Pers\".\"gCarboStillRecipe\")"
},
{
"instruction_uid": "33",
"uid": "33",
"type": "Coil_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "26",
@@ -903,7 +956,7 @@
}
},
"outputs": {},
- "scl": "\"gStillWaterByPassEn\" := ((\"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_StillWaterByPass\" OR (\"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_ByPassDeair\" AND \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_Deaireation\")) AND \"Blender_Variables_Pers\".\"gWaterRecipe\") AND \"Blender_Variables_Pers\".\"gCarboStillRecipe\";"
+ "scl": "\"gStillWaterByPassEn\" := ((\"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_StillWaterByPass\" OR (\"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_ByPassDeair\" AND (NOT \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_Deaireation\"))) AND \"Blender_Variables_Pers\".\"gWaterRecipe\") AND (NOT \"Blender_Variables_Pers\".\"gCarboStillRecipe\");"
}
]
},
@@ -917,6 +970,7 @@
"uid": "26",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -936,6 +990,7 @@
"uid": "27",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -958,6 +1013,7 @@
"uid": "28",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "23",
@@ -980,6 +1036,9 @@
"uid": "29",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "24",
@@ -995,13 +1054,14 @@
}
},
"outputs": {},
- "scl": "// RLO: ((\"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_BlendFillSystem\" AND \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_StillWaterByPass\") AND \"Blender_Variables_Pers\".\"gWaterRecipe\") AND \"Blender_Variables_Pers\".\"gCarboStillRecipe\""
+ "scl": "// RLO: ((\"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_BlendFillSystem\" AND \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_StillWaterByPass\") AND \"Blender_Variables_Pers\".\"gWaterRecipe\") AND (NOT \"Blender_Variables_Pers\".\"gCarboStillRecipe\")"
},
{
"instruction_uid": "30",
"uid": "30",
"type": "Coil_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "25",
@@ -1017,7 +1077,7 @@
}
},
"outputs": {},
- "scl": "\"gBlendFiStillWaterByPass\" := ((\"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_BlendFillSystem\" AND \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_StillWaterByPass\") AND \"Blender_Variables_Pers\".\"gWaterRecipe\") AND \"Blender_Variables_Pers\".\"gCarboStillRecipe\";"
+ "scl": "\"gBlendFiStillWaterByPass\" := ((\"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_BlendFillSystem\" AND \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_StillWaterByPass\") AND \"Blender_Variables_Pers\".\"gWaterRecipe\") AND (NOT \"Blender_Variables_Pers\".\"gCarboStillRecipe\");"
}
]
},
@@ -1031,6 +1091,7 @@
"uid": "30",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -1050,6 +1111,9 @@
"uid": "31",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "22",
@@ -1065,13 +1129,16 @@
}
},
"outputs": {},
- "scl": "// RLO: \"gSyrupRoomEn\" AND \"gIN_HVP301_Aux\""
+ "scl": "// RLO: \"gSyrupRoomEn\" AND (NOT \"gIN_HVP301_Aux\")"
},
{
"instruction_uid": "32",
"uid": "32",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "23",
@@ -1087,13 +1154,14 @@
}
},
"outputs": {},
- "scl": "// RLO: (\"gSyrupRoomEn\" AND \"gIN_HVP301_Aux\") AND \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_FastChangeOverEnabled\""
+ "scl": "// RLO: (\"gSyrupRoomEn\" AND (NOT \"gIN_HVP301_Aux\")) AND (NOT \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_FastChangeOverEnabled\")"
},
{
"instruction_uid": "33",
"uid": "33",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "24",
@@ -1109,13 +1177,16 @@
}
},
"outputs": {},
- "scl": "// RLO: ((\"gSyrupRoomEn\" AND \"gIN_HVP301_Aux\") AND \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_FastChangeOverEnabled\") AND \"Procedure_Variables\".\"FTP302Line_Preparation\".\"Done\""
+ "scl": "// RLO: (\"gSyrupRoomEn\" AND (NOT \"gIN_HVP301_Aux\")) AND (NOT \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_FastChangeOverEnabled\") AND \"Procedure_Variables\".\"FTP302Line_Preparation\".\"Done\""
},
{
"instruction_uid": "34",
"uid": "34",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "25",
@@ -1131,13 +1202,14 @@
}
},
"outputs": {},
- "scl": "// RLO: (((\"gSyrupRoomEn\" AND \"gIN_HVP301_Aux\") AND \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_FastChangeOverEnabled\") AND \"Procedure_Variables\".\"FTP302Line_Preparation\".\"Done\") AND \"Procedure_Variables\".\"Syr_RunOut\".\"Done\""
+ "scl": "// RLO: ((\"gSyrupRoomEn\" AND (NOT \"gIN_HVP301_Aux\")) AND (NOT \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_FastChangeOverEnabled\") AND \"Procedure_Variables\".\"FTP302Line_Preparation\".\"Done\") AND (NOT \"Procedure_Variables\".\"Syr_RunOut\".\"Done\")"
},
{
"instruction_uid": "35",
"uid": "35",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "26",
@@ -1154,6 +1226,7 @@
"uid": "36",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "27",
@@ -1176,6 +1249,7 @@
"uid": "37",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "28",
@@ -1200,6 +1274,7 @@
"template_values": {
"Card": "Cardinality"
},
+ "negated_pins": {},
"inputs": {
"in2": {
"type": "connection",
@@ -1215,13 +1290,14 @@
}
},
"outputs": {},
- "scl": "// Logic O 38: ((((\"gSyrupRoomEn\" AND \"gIN_HVP301_Aux\") AND \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_FastChangeOverEnabled\") AND \"Procedure_Variables\".\"FTP302Line_Preparation\".\"Done\") AND \"Procedure_Variables\".\"Syr_RunOut\".\"Done\") OR ((\"gBlenderCIPMode\" AND \"gIN_CIP_CIPRunning\") AND \"Procedure_Variables\".\"Blender_Run\".\"Running\")"
+ "scl": "// Logic O 38: ((\"gSyrupRoomEn\" AND (NOT \"gIN_HVP301_Aux\")) AND (NOT \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_FastChangeOverEnabled\") AND \"Procedure_Variables\".\"FTP302Line_Preparation\".\"Done\") AND (NOT \"Procedure_Variables\".\"Syr_RunOut\".\"Done\") OR ((\"gBlenderCIPMode\" AND \"gIN_CIP_CIPRunning\") AND \"Procedure_Variables\".\"Blender_Run\".\"Running\")"
},
{
"instruction_uid": "39",
"uid": "39",
"type": "Coil_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "29",
@@ -1237,7 +1313,7 @@
}
},
"outputs": {},
- "scl": "\"gHVP301_Open\" := ((((\"gSyrupRoomEn\" AND \"gIN_HVP301_Aux\") AND \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_FastChangeOverEnabled\") AND \"Procedure_Variables\".\"FTP302Line_Preparation\".\"Done\") AND \"Procedure_Variables\".\"Syr_RunOut\".\"Done\") OR ((\"gBlenderCIPMode\" AND \"gIN_CIP_CIPRunning\") AND \"Procedure_Variables\".\"Blender_Run\".\"Running\");"
+ "scl": "\"gHVP301_Open\" := ((\"gSyrupRoomEn\" AND (NOT \"gIN_HVP301_Aux\")) AND (NOT \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_FastChangeOverEnabled\") AND \"Procedure_Variables\".\"FTP302Line_Preparation\".\"Done\") AND (NOT \"Procedure_Variables\".\"Syr_RunOut\".\"Done\") OR ((\"gBlenderCIPMode\" AND \"gIN_CIP_CIPRunning\") AND \"Procedure_Variables\".\"Blender_Run\".\"Running\");"
}
]
},
@@ -1251,6 +1327,7 @@
"uid": "25",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -1270,6 +1347,7 @@
"uid": "26",
"type": "Sd",
"template_values": {},
+ "negated_pins": {},
"inputs": {},
"outputs": {}
},
@@ -1278,6 +1356,7 @@
"uid": "27",
"type": "Coil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "24",
@@ -1306,6 +1385,7 @@
"uid": "24",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -1327,13 +1407,8 @@
"template_values": {
"SrcType": "Type"
},
+ "negated_pins": {},
"inputs": {
- "pre": {
- "type": "connection",
- "source_instruction_type": "Contact",
- "source_instruction_uid": "24",
- "source_pin": "out"
- },
"in2": {
"uid": "23",
"scope": "LiteralConstant",
@@ -1346,10 +1421,16 @@
"scope": "GlobalVariable",
"type": "variable",
"name": "\"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_MeterType\""
+ },
+ "pre": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "24",
+ "source_pin": "out"
}
},
"outputs": {},
- "scl": "// Cond: \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_MeterType\" = 6"
+ "scl": "// Comparison Eq 25: \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_MeterType\" = 6"
},
{
"instruction_uid": "26",
@@ -1380,6 +1461,7 @@
"uid": "24",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -1401,13 +1483,8 @@
"template_values": {
"SrcType": "Type"
},
+ "negated_pins": {},
"inputs": {
- "pre": {
- "type": "connection",
- "source_instruction_type": "Contact",
- "source_instruction_uid": "24",
- "source_pin": "out"
- },
"in2": {
"uid": "23",
"scope": "LiteralConstant",
@@ -1420,10 +1497,16 @@
"scope": "GlobalVariable",
"type": "variable",
"name": "\"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_MeterType\""
+ },
+ "pre": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "24",
+ "source_pin": "out"
}
},
"outputs": {},
- "scl": "// Cond: \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_MeterType\" = 5"
+ "scl": "// Comparison Eq 25: \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_MeterType\" = 5"
},
{
"instruction_uid": "26",
@@ -1454,6 +1537,7 @@
"uid": "22",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -1497,6 +1581,7 @@
"uid": "24",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -1518,13 +1603,8 @@
"template_values": {
"SrcType": "Type"
},
+ "negated_pins": {},
"inputs": {
- "pre": {
- "type": "connection",
- "source_instruction_type": "Contact",
- "source_instruction_uid": "24",
- "source_pin": "out"
- },
"in2": {
"uid": "23",
"scope": "LiteralConstant",
@@ -1537,10 +1617,16 @@
"scope": "GlobalVariable",
"type": "variable",
"name": "\"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_MeterType\""
+ },
+ "pre": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "24",
+ "source_pin": "out"
}
},
"outputs": {},
- "scl": "// Cond: \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_MeterType\" = 3"
+ "scl": "// Comparison Eq 25: \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_MeterType\" = 3"
},
{
"instruction_uid": "26",
@@ -1590,7 +1676,7 @@
{
"instruction_uid": "21",
"uid": "21",
- "type": "Call_FB_scl",
+ "type": "Call_FB_error",
"block_name": "Input",
"block_type": "FB",
"instance_scope": "GlobalVariable",
@@ -1600,7 +1686,7 @@
}
},
"outputs": {},
- "scl": "// ERROR: Call a bloque no soportado: Input"
+ "scl": "// ERROR: FB Call Input sin instancia"
}
]
},
@@ -1635,6 +1721,7 @@
"uid": "22",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -1699,6 +1786,7 @@
"uid": "25",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -1718,28 +1806,32 @@
"uid": "26",
"type": "PBox_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
- "in": {
- "type": "connection",
- "source_instruction_type": "Contact",
- "source_instruction_uid": "25",
- "source_pin": "out"
- },
"bit": {
"uid": "22",
"scope": "GlobalVariable",
"type": "variable",
"name": "\"M19001\""
+ },
+ "in": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "25",
+ "source_pin": "out"
}
},
"outputs": {},
- "scl": "// PBox 26 - Passing bit: \"M19001\""
+ "scl": "// // PBox 26 - Passing memory bit: \"M19001\""
},
{
"instruction_uid": "27",
"uid": "27",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "23",
@@ -1755,13 +1847,14 @@
}
},
"outputs": {},
- "scl": "// RLO: \"M19001\" AND \"mDelayPowerOnTmr\""
+ "scl": "// RLO: \"M19001\" AND (NOT \"mDelayPowerOnTmr\")"
},
{
"instruction_uid": "28",
"uid": "28",
"type": "Coil_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "24",
@@ -1777,7 +1870,7 @@
}
},
"outputs": {},
- "scl": "\"gProductionONS\" := \"M19001\" AND \"mDelayPowerOnTmr\";"
+ "scl": "\"gProductionONS\" := \"M19001\" AND (NOT \"mDelayPowerOnTmr\");"
}
]
},
@@ -1791,6 +1884,7 @@
"uid": "24",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -1810,6 +1904,7 @@
"uid": "25",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -1828,6 +1923,7 @@
"template_values": {
"Card": "Cardinality"
},
+ "negated_pins": {},
"inputs": {
"in2": {
"type": "connection",
@@ -1850,6 +1946,9 @@
"uid": "27",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "23",
@@ -1865,7 +1964,7 @@
}
},
"outputs": {},
- "scl": "// RLO: (\"gProductionONS\" OR \"Procedure_Variables\".\"Blender_Rinse\".\"ONS_Done\") AND \"Blender_Variables_Pers\".\"gBlenderStarted\""
+ "scl": "// RLO: (\"gProductionONS\" OR \"Procedure_Variables\".\"Blender_Rinse\".\"ONS_Done\") AND (NOT \"Blender_Variables_Pers\".\"gBlenderStarted\")"
},
{
"instruction_uid": "28",
@@ -1882,7 +1981,7 @@
}
},
"outputs": {},
- "scl": "IF (\"gProductionONS\" OR \"Procedure_Variables\".\"Blender_Rinse\".\"ONS_Done\") AND \"Blender_Variables_Pers\".\"gBlenderStarted\" THEN\n BlenderCtrl_ProdModeInit();\nEND_IF;"
+ "scl": "IF (\"gProductionONS\" OR \"Procedure_Variables\".\"Blender_Rinse\".\"ONS_Done\") AND (NOT \"Blender_Variables_Pers\".\"gBlenderStarted\") THEN\n BlenderCtrl_ProdModeInit();\nEND_IF;"
}
]
},
@@ -1896,6 +1995,7 @@
"uid": "25",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -1915,28 +2015,32 @@
"uid": "26",
"type": "PBox_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
- "in": {
- "type": "connection",
- "source_instruction_type": "Contact",
- "source_instruction_uid": "25",
- "source_pin": "out"
- },
"bit": {
"uid": "22",
"scope": "GlobalVariable",
"type": "variable",
"name": "\"M19002\""
+ },
+ "in": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "25",
+ "source_pin": "out"
}
},
"outputs": {},
- "scl": "// PBox 26 - Passing bit: \"M19002\""
+ "scl": "// // PBox 26 - Passing memory bit: \"M19002\""
},
{
"instruction_uid": "27",
"uid": "27",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "23",
@@ -1952,13 +2056,14 @@
}
},
"outputs": {},
- "scl": "// RLO: \"M19002\" AND \"mDelayPowerOnTmr\""
+ "scl": "// RLO: \"M19002\" AND (NOT \"mDelayPowerOnTmr\")"
},
{
"instruction_uid": "28",
"uid": "28",
"type": "Coil_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "24",
@@ -1974,7 +2079,7 @@
}
},
"outputs": {},
- "scl": "\"gRinseONS\" := \"M19002\" AND \"mDelayPowerOnTmr\";"
+ "scl": "\"gRinseONS\" := \"M19002\" AND (NOT \"mDelayPowerOnTmr\");"
}
]
},
@@ -1988,6 +2093,7 @@
"uid": "25",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -2007,28 +2113,32 @@
"uid": "26",
"type": "PBox_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
- "in": {
- "type": "connection",
- "source_instruction_type": "Contact",
- "source_instruction_uid": "25",
- "source_pin": "out"
- },
"bit": {
"uid": "22",
"scope": "GlobalVariable",
"type": "variable",
"name": "\"M19003\""
+ },
+ "in": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "25",
+ "source_pin": "out"
}
},
"outputs": {},
- "scl": "// PBox 26 - Passing bit: \"M19003\""
+ "scl": "// // PBox 26 - Passing memory bit: \"M19003\""
},
{
"instruction_uid": "27",
"uid": "27",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "23",
@@ -2044,13 +2154,14 @@
}
},
"outputs": {},
- "scl": "// RLO: \"M19003\" AND \"mDelayPowerOnTmr\""
+ "scl": "// RLO: \"M19003\" AND (NOT \"mDelayPowerOnTmr\")"
},
{
"instruction_uid": "28",
"uid": "28",
"type": "Coil_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "24",
@@ -2066,7 +2177,7 @@
}
},
"outputs": {},
- "scl": "\"gCIPONS\" := \"M19003\" AND \"mDelayPowerOnTmr\";"
+ "scl": "\"gCIPONS\" := \"M19003\" AND (NOT \"mDelayPowerOnTmr\");"
}
]
},
@@ -2080,6 +2191,7 @@
"uid": "22",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -2172,7 +2284,7 @@
}
},
"outputs": {},
- "scl": "Prod Tank PressCtrl();"
+ "scl": "Prod_Tank_PressCtrl();"
}
]
},
@@ -2205,7 +2317,7 @@
{
"instruction_uid": "21",
"uid": "21",
- "type": "Call_FB_scl",
+ "type": "Call_FB_error",
"block_name": "ProcedureFirstProduction",
"block_type": "FB",
"instance_scope": "GlobalVariable",
@@ -2215,7 +2327,7 @@
}
},
"outputs": {},
- "scl": "// ERROR: Call a bloque no soportado: ProcedureFirstProduction"
+ "scl": "// ERROR: FB Call ProcedureFirstProduction sin instancia"
}
]
},
@@ -2355,6 +2467,9 @@
"uid": "22",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "21",
@@ -2367,12 +2482,12 @@
}
},
"outputs": {},
- "scl": "// RLO: \"mDelayPowerOnTmr\""
+ "scl": "// RLO: (NOT \"mDelayPowerOnTmr\")"
},
{
"instruction_uid": "23",
"uid": "23",
- "type": "Call_FB_scl",
+ "type": "Call_FB_error",
"block_name": "Procedure",
"block_type": "FB",
"instance_scope": "GlobalVariable",
@@ -2385,7 +2500,7 @@
}
},
"outputs": {},
- "scl": "IF \"mDelayPowerOnTmr\" THEN\n // ERROR: Call a bloque no soportado: Procedure\nEND_IF;"
+ "scl": "// ERROR: FB Call Procedure sin instancia"
}
]
},
@@ -2406,7 +2521,7 @@
}
},
"outputs": {},
- "scl": "Pneumatic Valve Ctrl();"
+ "scl": "Pneumatic_Valve_Ctrl();"
}
]
},
@@ -2441,6 +2556,7 @@
"uid": "22",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -2589,6 +2705,7 @@
"uid": "24",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -2608,6 +2725,7 @@
"uid": "25",
"type": "Se",
"template_values": {},
+ "negated_pins": {},
"inputs": {},
"outputs": {}
}
@@ -2623,6 +2741,7 @@
"uid": "26",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -2642,6 +2761,7 @@
"uid": "27",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -2660,6 +2780,7 @@
"template_values": {
"Card": "Cardinality"
},
+ "negated_pins": {},
"inputs": {
"in2": {
"type": "connection",
@@ -2682,6 +2803,7 @@
"uid": "29",
"type": "Se",
"template_values": {},
+ "negated_pins": {},
"inputs": {},
"outputs": {}
},
@@ -2690,6 +2812,7 @@
"uid": "30",
"type": "Coil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "25",
@@ -2718,6 +2841,7 @@
"uid": "23",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -2737,6 +2861,7 @@
"uid": "24",
"type": "RCoil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -2765,6 +2890,7 @@
"uid": "27",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -2784,6 +2910,7 @@
"uid": "28",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -2802,6 +2929,7 @@
"template_values": {
"Card": "Cardinality"
},
+ "negated_pins": {},
"inputs": {
"in2": {
"type": "connection",
@@ -2824,6 +2952,7 @@
"uid": "30",
"type": "Se",
"template_values": {},
+ "negated_pins": {},
"inputs": {},
"outputs": {}
},
@@ -2832,6 +2961,7 @@
"uid": "31",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "25",
@@ -2853,6 +2983,7 @@
"uid": "32",
"type": "Coil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "26",
@@ -2881,6 +3012,7 @@
"uid": "23",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -2900,6 +3032,7 @@
"uid": "24",
"type": "RCoil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -2928,6 +3061,7 @@
"uid": "26",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -2947,6 +3081,7 @@
"uid": "27",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -2965,6 +3100,7 @@
"template_values": {
"Card": "Cardinality"
},
+ "negated_pins": {},
"inputs": {
"in2": {
"type": "connection",
@@ -2987,6 +3123,7 @@
"uid": "29",
"type": "Se",
"template_values": {},
+ "negated_pins": {},
"inputs": {},
"outputs": {}
},
@@ -2995,6 +3132,7 @@
"uid": "30",
"type": "Coil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "25",
@@ -3023,6 +3161,7 @@
"uid": "23",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -3042,6 +3181,7 @@
"uid": "24",
"type": "RCoil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -3070,6 +3210,7 @@
"uid": "26",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -3089,6 +3230,7 @@
"uid": "27",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -3107,6 +3249,7 @@
"template_values": {
"Card": "Cardinality"
},
+ "negated_pins": {},
"inputs": {
"in2": {
"type": "connection",
@@ -3129,6 +3272,7 @@
"uid": "29",
"type": "Se",
"template_values": {},
+ "negated_pins": {},
"inputs": {},
"outputs": {}
},
@@ -3137,6 +3281,7 @@
"uid": "30",
"type": "Coil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "25",
@@ -3165,6 +3310,7 @@
"uid": "23",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -3184,6 +3330,7 @@
"uid": "24",
"type": "RCoil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -3212,6 +3359,7 @@
"uid": "23",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -3231,6 +3379,7 @@
"uid": "24",
"type": "RCoil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -3259,6 +3408,9 @@
"uid": "26",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "21",
@@ -3271,7 +3423,7 @@
}
},
"outputs": {},
- "scl": "// RLO: \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_Simulation\""
+ "scl": "// RLO: (NOT \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_Simulation\")"
},
{
"instruction_uid": "27",
@@ -3288,7 +3440,7 @@
}
},
"outputs": {},
- "scl": "IF \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_Simulation\" THEN\n BlenderCtrl_MFM Command();\nEND_IF;"
+ "scl": "IF (NOT \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_Simulation\") THEN\n BlenderCtrl_MFM_Command();\nEND_IF;"
}
]
},
@@ -3309,7 +3461,7 @@
}
},
"outputs": {},
- "scl": "CPU_DP Global Diag();"
+ "scl": "CPU_DP_Global_Diag();"
}
]
},
@@ -3330,7 +3482,7 @@
}
},
"outputs": {},
- "scl": "Profibus Network();"
+ "scl": "Profibus_Network();"
}
]
},
@@ -3365,6 +3517,7 @@
"uid": "25",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -3384,6 +3537,7 @@
"uid": "26",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "22",
@@ -3406,18 +3560,19 @@
"uid": "27",
"type": "NBox",
"template_values": {},
+ "negated_pins": {},
"inputs": {
- "in": {
- "type": "connection",
- "source_instruction_type": "Contact",
- "source_instruction_uid": "26",
- "source_pin": "out"
- },
"bit": {
"uid": "23",
"scope": "GlobalVariable",
"type": "variable",
"name": "\"M19011\""
+ },
+ "in": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "26",
+ "source_pin": "out"
}
},
"outputs": {}
@@ -3443,6 +3598,7 @@
"uid": "29",
"type": "Coil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "24",
@@ -3486,6 +3642,7 @@
"uid": "33",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -3505,6 +3662,9 @@
"uid": "34",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
"inputs": {
"operand": {
"uid": "22",
@@ -3520,13 +3680,14 @@
}
},
"outputs": {},
- "scl": "// RLO: \"HMI_Variables_Cmd\".\"Recipe\".\"Main_Page\" AND \"mFP_Recip_Main_Page\""
+ "scl": "// RLO: \"HMI_Variables_Cmd\".\"Recipe\".\"Main_Page\" AND (NOT \"mFP_Recip_Main_Page\")"
},
{
"instruction_uid": "35",
"uid": "35",
"type": "Coil_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "23",
@@ -3542,13 +3703,14 @@
}
},
"outputs": {},
- "scl": "\"mAux_FP_M700_1\" := \"HMI_Variables_Cmd\".\"Recipe\".\"Main_Page\" AND \"mFP_Recip_Main_Page\";"
+ "scl": "\"mAux_FP_M700_1\" := \"HMI_Variables_Cmd\".\"Recipe\".\"Main_Page\" AND (NOT \"mFP_Recip_Main_Page\");"
},
{
"instruction_uid": "36",
"uid": "36",
"type": "Coil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "24",
@@ -3564,6 +3726,7 @@
"uid": "37",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "25",
@@ -3580,6 +3743,7 @@
"uid": "38",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "26",
@@ -3602,6 +3766,7 @@
"uid": "39",
"type": "SdCoil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "27",
@@ -3623,6 +3788,7 @@
"uid": "40",
"type": "Contact",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "29",
@@ -3644,6 +3810,7 @@
"uid": "41",
"type": "RCoil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "30",
@@ -3665,6 +3832,7 @@
"uid": "42",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "31",
@@ -3681,6 +3849,7 @@
"uid": "43",
"type": "SCoil",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "32",
@@ -3709,6 +3878,7 @@
"uid": "42",
"type": "Contact_scl",
"template_values": {},
+ "negated_pins": {},
"inputs": {
"operand": {
"uid": "21",
@@ -3726,7 +3896,7 @@
{
"instruction_uid": "43",
"uid": "43",
- "type": "Call_FB_scl",
+ "type": "Call_FB_error",
"block_name": "RecipeManagement - Prod",
"block_type": "FB",
"instance_scope": "GlobalVariable",
@@ -3739,7 +3909,7 @@
}
},
"outputs": {},
- "scl": "IF \"AUX TRUE\" THEN\n // ERROR: Call a bloque no soportado: RecipeManagement - Prod\nEND_IF;"
+ "scl": "// ERROR: FB Call RecipeManagement___Prod sin instancia"
}
]
},
diff --git a/BlenderRun_ProdTime_simplified.json b/BlenderRun_ProdTime_simplified.json
new file mode 100644
index 0000000..01f75a0
--- /dev/null
+++ b/BlenderRun_ProdTime_simplified.json
@@ -0,0 +1,1317 @@
+{
+ "block_name": "BlenderRun_ProdTime",
+ "block_number": 2040,
+ "language": "LAD",
+ "block_comment": "",
+ "interface": {
+ "Temp": [
+ {
+ "name": "m1MinONS",
+ "datatype": "Bool"
+ },
+ {
+ "name": "m1HourONS",
+ "datatype": "Bool"
+ },
+ {
+ "name": "Buffer",
+ "datatype": "Bool"
+ },
+ {
+ "name": "mRunMin",
+ "datatype": "Bool"
+ },
+ {
+ "name": "mRunHr",
+ "datatype": "Bool"
+ },
+ {
+ "name": "I_DIRunning_sec",
+ "datatype": "DInt"
+ },
+ {
+ "name": "I_DIRunning_min",
+ "datatype": "DInt"
+ },
+ {
+ "name": "MOD60",
+ "datatype": "DInt"
+ }
+ ],
+ "Return": [
+ {
+ "name": "Ret_Val",
+ "datatype": "Void"
+ }
+ ]
+ },
+ "networks": [
+ {
+ "id": "9",
+ "title": "Seconds",
+ "comment": "",
+ "logic": [
+ {
+ "instruction_uid": "26",
+ "uid": "26",
+ "type": "Contact",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "21",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Procedure_Variables\".\"Blender_Run\".\"Running\""
+ },
+ "in": {
+ "type": "powerrail"
+ }
+ },
+ "outputs": {}
+ },
+ {
+ "instruction_uid": "27",
+ "uid": "27",
+ "type": "Contact",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "22",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"CLK_1.0S\""
+ },
+ "in": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "26",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {}
+ },
+ {
+ "instruction_uid": "28",
+ "uid": "28",
+ "type": "Add",
+ "template_values": {
+ "Card": "Cardinality",
+ "SrcType": "Type"
+ },
+ "inputs": {
+ "in2": {
+ "uid": "24",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 1
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "27",
+ "source_pin": "out"
+ },
+ "in1": {
+ "uid": "23",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gSLIM_Sec\""
+ }
+ },
+ "outputs": {
+ "out": [
+ {
+ "uid": "25",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gSLIM_Sec\""
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "id": "1A",
+ "title": "Reset Hours",
+ "comment": "",
+ "logic": [
+ {
+ "instruction_uid": "24",
+ "uid": "24",
+ "type": "Contact",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "21",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"SLIM_Variables\".\"ResetHour\""
+ },
+ "in": {
+ "type": "powerrail"
+ }
+ },
+ "outputs": {}
+ },
+ {
+ "instruction_uid": "25",
+ "uid": "25",
+ "type": "Move",
+ "template_values": {
+ "Card": "Cardinality"
+ },
+ "inputs": {
+ "in": {
+ "uid": "22",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 0
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "24",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {
+ "out1": [
+ {
+ "uid": "23",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gSLIM_Sec\""
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "id": "2B",
+ "title": "Seconds Counter",
+ "comment": "",
+ "logic": [
+ {
+ "instruction_uid": "26",
+ "uid": "26",
+ "type": "Contact",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "21",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"gBlenderBlending\""
+ },
+ "in": {
+ "type": "powerrail"
+ }
+ },
+ "outputs": {}
+ },
+ {
+ "instruction_uid": "27",
+ "uid": "27",
+ "type": "Contact",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "22",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"CLK_1.0S\""
+ },
+ "in": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "26",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {}
+ },
+ {
+ "instruction_uid": "28",
+ "uid": "28",
+ "type": "Add",
+ "template_values": {
+ "Card": "Cardinality",
+ "SrcType": "Type"
+ },
+ "inputs": {
+ "in2": {
+ "uid": "24",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 1
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "27",
+ "source_pin": "out"
+ },
+ "in1": {
+ "uid": "23",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gProdSec\""
+ }
+ },
+ "outputs": {
+ "out": [
+ {
+ "uid": "25",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gProdSec\""
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "id": "3C",
+ "title": "Minute",
+ "comment": "",
+ "logic": [
+ {
+ "instruction_uid": "24",
+ "uid": "24",
+ "type": "Eq",
+ "template_values": {
+ "SrcType": "Type"
+ },
+ "inputs": {
+ "pre": {
+ "type": "powerrail"
+ },
+ "in2": {
+ "uid": "22",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 60
+ },
+ "in1": {
+ "uid": "21",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gProdSec\""
+ }
+ },
+ "outputs": {}
+ },
+ {
+ "instruction_uid": "25",
+ "uid": "25",
+ "type": "Coil",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "23",
+ "scope": "LocalVariable",
+ "type": "variable",
+ "name": "\"m1MinONS\""
+ },
+ "in": {
+ "type": "connection",
+ "source_instruction_type": "Eq",
+ "source_instruction_uid": "24",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {}
+ }
+ ]
+ },
+ {
+ "id": "4D",
+ "title": "Minute Counter",
+ "comment": "",
+ "logic": [
+ {
+ "instruction_uid": "27",
+ "uid": "27",
+ "type": "Contact",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "21",
+ "scope": "LocalVariable",
+ "type": "variable",
+ "name": "\"m1MinONS\""
+ },
+ "in": {
+ "type": "powerrail"
+ }
+ },
+ "outputs": {}
+ },
+ {
+ "instruction_uid": "28",
+ "uid": "28",
+ "type": "Move",
+ "template_values": {
+ "Card": "Cardinality"
+ },
+ "inputs": {
+ "in": {
+ "uid": "22",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 0
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "27",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {
+ "out1": [
+ {
+ "uid": "23",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gProdSec\""
+ }
+ ]
+ }
+ },
+ {
+ "instruction_uid": "29",
+ "uid": "29",
+ "type": "Add",
+ "template_values": {
+ "Card": "Cardinality",
+ "SrcType": "Type"
+ },
+ "inputs": {
+ "in2": {
+ "uid": "25",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 1
+ },
+ "in1": {
+ "uid": "24",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gProdMin\""
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_uid": "27",
+ "source_instruction_type": "Contact",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {
+ "out": [
+ {
+ "uid": "26",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gProdMin\""
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "id": "5E",
+ "title": "Hour",
+ "comment": "",
+ "logic": [
+ {
+ "instruction_uid": "24",
+ "uid": "24",
+ "type": "Eq",
+ "template_values": {
+ "SrcType": "Type"
+ },
+ "inputs": {
+ "pre": {
+ "type": "powerrail"
+ },
+ "in2": {
+ "uid": "22",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 60
+ },
+ "in1": {
+ "uid": "21",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gProdMin\""
+ }
+ },
+ "outputs": {}
+ },
+ {
+ "instruction_uid": "25",
+ "uid": "25",
+ "type": "Coil",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "23",
+ "scope": "LocalVariable",
+ "type": "variable",
+ "name": "\"m1HourONS\""
+ },
+ "in": {
+ "type": "connection",
+ "source_instruction_type": "Eq",
+ "source_instruction_uid": "24",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {}
+ }
+ ]
+ },
+ {
+ "id": "6F",
+ "title": "Hour Counter",
+ "comment": "",
+ "logic": [
+ {
+ "instruction_uid": "30",
+ "uid": "30",
+ "type": "Contact",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "21",
+ "scope": "LocalVariable",
+ "type": "variable",
+ "name": "\"m1HourONS\""
+ },
+ "in": {
+ "type": "powerrail"
+ }
+ },
+ "outputs": {}
+ },
+ {
+ "instruction_uid": "31",
+ "uid": "31",
+ "type": "Move",
+ "template_values": {
+ "Card": "Cardinality"
+ },
+ "inputs": {
+ "in": {
+ "uid": "22",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 0
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "30",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {
+ "out1": [
+ {
+ "uid": "23",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gProdMin\""
+ }
+ ]
+ }
+ },
+ {
+ "instruction_uid": "32",
+ "uid": "32",
+ "type": "Add",
+ "template_values": {
+ "Card": "Cardinality",
+ "SrcType": "Type"
+ },
+ "inputs": {
+ "in2": {
+ "uid": "25",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 1
+ },
+ "in1": {
+ "uid": "24",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gProdHour\""
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_uid": "30",
+ "source_instruction_type": "Contact",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {
+ "out": [
+ {
+ "uid": "26",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gProdHour\""
+ }
+ ]
+ }
+ },
+ {
+ "instruction_uid": "33",
+ "uid": "33",
+ "type": "Add",
+ "template_values": {
+ "Card": "Cardinality",
+ "SrcType": "Type"
+ },
+ "inputs": {
+ "in2": {
+ "uid": "28",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 1
+ },
+ "in1": {
+ "uid": "27",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gBlendingMaintHour\""
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_uid": "30",
+ "source_instruction_type": "Contact",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {
+ "out": [
+ {
+ "uid": "29",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gBlendingMaintHour\""
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "id": "80",
+ "title": "Counter reset",
+ "comment": "",
+ "logic": [
+ {
+ "instruction_uid": "29",
+ "uid": "29",
+ "type": "Contact",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "21",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"gBlenderCIPMode\""
+ },
+ "in": {
+ "type": "powerrail"
+ }
+ },
+ "outputs": {}
+ },
+ {
+ "instruction_uid": "30",
+ "uid": "30",
+ "type": "Contact",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "22",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"gBlenderRinseMode\""
+ }
+ },
+ "outputs": {}
+ },
+ {
+ "instruction_uid": "31",
+ "uid": "31",
+ "type": "O",
+ "template_values": {
+ "Card": "Cardinality"
+ },
+ "inputs": {
+ "in2": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "30",
+ "source_pin": "out"
+ },
+ "in1": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "29",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {}
+ },
+ {
+ "instruction_uid": "32",
+ "uid": "32",
+ "type": "Move",
+ "template_values": {
+ "Card": "Cardinality"
+ },
+ "inputs": {
+ "in": {
+ "uid": "23",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 0
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_type": "O",
+ "source_instruction_uid": "31",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {
+ "out1": [
+ {
+ "uid": "24",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gProdSec\""
+ }
+ ]
+ }
+ },
+ {
+ "instruction_uid": "33",
+ "uid": "33",
+ "type": "Move",
+ "template_values": {
+ "Card": "Cardinality"
+ },
+ "inputs": {
+ "in": {
+ "uid": "25",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 0
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_uid": "31",
+ "source_instruction_type": "O",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {
+ "out1": [
+ {
+ "uid": "26",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gProdMin\""
+ }
+ ]
+ }
+ },
+ {
+ "instruction_uid": "34",
+ "uid": "34",
+ "type": "Move",
+ "template_values": {
+ "Card": "Cardinality"
+ },
+ "inputs": {
+ "in": {
+ "uid": "27",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 0
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_uid": "31",
+ "source_instruction_type": "O",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {
+ "out1": [
+ {
+ "uid": "28",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gProdHour\""
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "id": "91",
+ "title": "Running Seconds",
+ "comment": "",
+ "logic": [
+ {
+ "instruction_uid": "26",
+ "uid": "26",
+ "type": "Contact",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "21",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Procedure_Variables\".\"Blender_Run\".\"Running\""
+ },
+ "in": {
+ "type": "powerrail"
+ }
+ },
+ "outputs": {}
+ },
+ {
+ "instruction_uid": "27",
+ "uid": "27",
+ "type": "Contact",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "22",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"CLK_1.0S\""
+ },
+ "in": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "26",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {}
+ },
+ {
+ "instruction_uid": "28",
+ "uid": "28",
+ "type": "Add",
+ "template_values": {
+ "Card": "Cardinality",
+ "SrcType": "Type"
+ },
+ "inputs": {
+ "in2": {
+ "uid": "24",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 1
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "27",
+ "source_pin": "out"
+ },
+ "in1": {
+ "uid": "23",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gRunningSeconds\""
+ }
+ },
+ "outputs": {
+ "out": [
+ {
+ "uid": "25",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gRunningSeconds\""
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "id": "A2",
+ "title": "Running Minutes",
+ "comment": "",
+ "logic": [
+ {
+ "instruction_uid": "35",
+ "uid": "35",
+ "type": "Convert",
+ "template_values": {
+ "SrcType": "Type",
+ "DestType": "Type"
+ },
+ "inputs": {
+ "in": {
+ "uid": "21",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gRunningSeconds\""
+ },
+ "en": {
+ "type": "powerrail"
+ }
+ },
+ "outputs": {
+ "out": [
+ {
+ "uid": "22",
+ "scope": "LocalVariable",
+ "type": "variable",
+ "name": "\"I_DIRunning_sec\""
+ }
+ ]
+ }
+ },
+ {
+ "instruction_uid": "36",
+ "uid": "36",
+ "type": "Mod",
+ "template_values": {
+ "SrcType": "Type"
+ },
+ "inputs": {
+ "in2": {
+ "uid": "24",
+ "scope": "TypedConstant",
+ "type": "constant",
+ "datatype": "TypedConstant",
+ "value": "DINT#60"
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_type": "Convert",
+ "source_instruction_uid": "35",
+ "source_pin": "eno"
+ },
+ "in1": {
+ "uid": "23",
+ "scope": "LocalVariable",
+ "type": "variable",
+ "name": "\"I_DIRunning_sec\""
+ }
+ },
+ "outputs": {
+ "out": [
+ {
+ "uid": "25",
+ "scope": "LocalVariable",
+ "type": "variable",
+ "name": "\"MOD60\""
+ }
+ ]
+ },
+ "eno_logic": [
+ {
+ "target_pin": "pre",
+ "target_type": "instruction",
+ "target_uid": "37",
+ "target_name": "Eq"
+ }
+ ]
+ },
+ {
+ "instruction_uid": "37",
+ "uid": "37",
+ "type": "Eq",
+ "template_values": {
+ "SrcType": "Type"
+ },
+ "inputs": {
+ "pre": {
+ "type": "connection",
+ "source_instruction_type": "Mod",
+ "source_instruction_uid": "36",
+ "source_pin": "eno"
+ },
+ "in2": {
+ "uid": "27",
+ "scope": "TypedConstant",
+ "type": "constant",
+ "datatype": "TypedConstant",
+ "value": "DINT#0"
+ },
+ "in1": {
+ "uid": "26",
+ "scope": "LocalVariable",
+ "type": "variable",
+ "name": "\"MOD60\""
+ }
+ },
+ "outputs": {}
+ },
+ {
+ "instruction_uid": "38",
+ "uid": "38",
+ "type": "Contact",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "28",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Procedure_Variables\".\"Blender_Run\".\"Running\""
+ },
+ "in": {
+ "type": "connection",
+ "source_instruction_type": "Eq",
+ "source_instruction_uid": "37",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {}
+ },
+ {
+ "instruction_uid": "39",
+ "uid": "39",
+ "type": "Contact",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "29",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"CLK_1.0S\""
+ },
+ "in": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "38",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {}
+ },
+ {
+ "instruction_uid": "40",
+ "uid": "40",
+ "type": "Add",
+ "template_values": {
+ "Card": "Cardinality",
+ "SrcType": "Type"
+ },
+ "inputs": {
+ "in2": {
+ "uid": "31",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 1
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "39",
+ "source_pin": "out"
+ },
+ "in1": {
+ "uid": "30",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gRunningMinutes\""
+ }
+ },
+ "outputs": {
+ "out": [
+ {
+ "uid": "32",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gRunningMinutes\""
+ }
+ ]
+ }
+ },
+ {
+ "instruction_uid": "41",
+ "uid": "41",
+ "type": "PBox",
+ "template_values": {},
+ "inputs": {
+ "bit": {
+ "uid": "33",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"M19012\""
+ }
+ },
+ "outputs": {}
+ },
+ {
+ "instruction_uid": "42",
+ "uid": "42",
+ "type": "Coil",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "34",
+ "scope": "LocalVariable",
+ "type": "variable",
+ "name": "\"mRunMin\""
+ },
+ "in": {
+ "type": "connection",
+ "source_instruction_type": "PBox",
+ "source_instruction_uid": "41",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {}
+ }
+ ]
+ },
+ {
+ "id": "B3",
+ "title": "Running Hours for Maintenance",
+ "comment": "",
+ "logic": [
+ {
+ "instruction_uid": "32",
+ "uid": "32",
+ "type": "Contact",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "21",
+ "scope": "LocalVariable",
+ "type": "variable",
+ "name": "\"mRunMin\""
+ },
+ "in": {
+ "type": "powerrail"
+ }
+ },
+ "outputs": {}
+ },
+ {
+ "instruction_uid": "33",
+ "uid": "33",
+ "type": "Convert",
+ "template_values": {
+ "SrcType": "Type",
+ "DestType": "Type"
+ },
+ "inputs": {
+ "in": {
+ "uid": "22",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gRunningMinutes\""
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "32",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {
+ "out": [
+ {
+ "uid": "23",
+ "scope": "LocalVariable",
+ "type": "variable",
+ "name": "\"I_DIRunning_min\""
+ }
+ ]
+ }
+ },
+ {
+ "instruction_uid": "34",
+ "uid": "34",
+ "type": "Mod",
+ "template_values": {
+ "SrcType": "Type"
+ },
+ "inputs": {
+ "in2": {
+ "uid": "25",
+ "scope": "TypedConstant",
+ "type": "constant",
+ "datatype": "TypedConstant",
+ "value": "DINT#60"
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_type": "Convert",
+ "source_instruction_uid": "33",
+ "source_pin": "eno"
+ },
+ "in1": {
+ "uid": "24",
+ "scope": "LocalVariable",
+ "type": "variable",
+ "name": "\"I_DIRunning_min\""
+ }
+ },
+ "outputs": {
+ "out": [
+ {
+ "uid": "26",
+ "scope": "LocalVariable",
+ "type": "variable",
+ "name": "\"MOD60\""
+ }
+ ]
+ },
+ "eno_logic": [
+ {
+ "target_pin": "pre",
+ "target_type": "instruction",
+ "target_uid": "35",
+ "target_name": "Eq"
+ }
+ ]
+ },
+ {
+ "instruction_uid": "35",
+ "uid": "35",
+ "type": "Eq",
+ "template_values": {
+ "SrcType": "Type"
+ },
+ "inputs": {
+ "pre": {
+ "type": "connection",
+ "source_instruction_type": "Mod",
+ "source_instruction_uid": "34",
+ "source_pin": "eno"
+ },
+ "in2": {
+ "uid": "28",
+ "scope": "TypedConstant",
+ "type": "constant",
+ "datatype": "TypedConstant",
+ "value": "DINT#0"
+ },
+ "in1": {
+ "uid": "27",
+ "scope": "LocalVariable",
+ "type": "variable",
+ "name": "\"MOD60\""
+ }
+ },
+ "outputs": {}
+ },
+ {
+ "instruction_uid": "36",
+ "uid": "36",
+ "type": "Add",
+ "template_values": {
+ "Card": "Cardinality",
+ "SrcType": "Type"
+ },
+ "inputs": {
+ "in2": {
+ "uid": "30",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 1
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_type": "Eq",
+ "source_instruction_uid": "35",
+ "source_pin": "out"
+ },
+ "in1": {
+ "uid": "29",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gRunningMaintHour\""
+ }
+ },
+ "outputs": {
+ "out": [
+ {
+ "uid": "31",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gRunningMaintHour\""
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "id": "C4",
+ "title": "Running Hours for Maintenance",
+ "comment": "",
+ "logic": [
+ {
+ "instruction_uid": "23",
+ "uid": "23",
+ "type": "Move",
+ "template_values": {
+ "Card": "Cardinality"
+ },
+ "inputs": {
+ "in": {
+ "uid": "21",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gRunningMaintHour\""
+ },
+ "en": {
+ "type": "powerrail"
+ }
+ },
+ "outputs": {
+ "out1": [
+ {
+ "uid": "22",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"HMI_Variables_Status\".\"System\".\"BlendingMaintHour\""
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/BlenderRun_ProdTime_simplified_processed.json b/BlenderRun_ProdTime_simplified_processed.json
new file mode 100644
index 0000000..93ec292
--- /dev/null
+++ b/BlenderRun_ProdTime_simplified_processed.json
@@ -0,0 +1,1367 @@
+{
+ "block_name": "BlenderRun_ProdTime",
+ "block_number": 2040,
+ "language": "LAD",
+ "block_comment": "",
+ "interface": {
+ "Temp": [
+ {
+ "name": "m1MinONS",
+ "datatype": "Bool"
+ },
+ {
+ "name": "m1HourONS",
+ "datatype": "Bool"
+ },
+ {
+ "name": "Buffer",
+ "datatype": "Bool"
+ },
+ {
+ "name": "mRunMin",
+ "datatype": "Bool"
+ },
+ {
+ "name": "mRunHr",
+ "datatype": "Bool"
+ },
+ {
+ "name": "I_DIRunning_sec",
+ "datatype": "DInt"
+ },
+ {
+ "name": "I_DIRunning_min",
+ "datatype": "DInt"
+ },
+ {
+ "name": "MOD60",
+ "datatype": "DInt"
+ }
+ ],
+ "Return": [
+ {
+ "name": "Ret_Val",
+ "datatype": "Void"
+ }
+ ]
+ },
+ "networks": [
+ {
+ "id": "9",
+ "title": "Seconds",
+ "comment": "",
+ "logic": [
+ {
+ "instruction_uid": "26",
+ "uid": "26",
+ "type": "Contact_scl",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "21",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Procedure_Variables\".\"Blender_Run\".\"Running\""
+ },
+ "in": {
+ "type": "powerrail"
+ }
+ },
+ "outputs": {},
+ "scl": "// RLO updated by Contact 26: \"Procedure_Variables\".\"Blender_Run\".\"Running\""
+ },
+ {
+ "instruction_uid": "27",
+ "uid": "27",
+ "type": "Contact_scl",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "22",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"CLK_1.0S\""
+ },
+ "in": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "26",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {},
+ "scl": "// RLO updated by Contact 27: \"Procedure_Variables\".\"Blender_Run\".\"Running\" AND \"CLK_1.0S\""
+ },
+ {
+ "instruction_uid": "28",
+ "uid": "28",
+ "type": "Add_scl",
+ "template_values": {
+ "Card": "Cardinality",
+ "SrcType": "Type"
+ },
+ "inputs": {
+ "in2": {
+ "uid": "24",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 1
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "27",
+ "source_pin": "out"
+ },
+ "in1": {
+ "uid": "23",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gSLIM_Sec\""
+ }
+ },
+ "outputs": {
+ "out": [
+ {
+ "uid": "25",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gSLIM_Sec\""
+ }
+ ]
+ },
+ "scl": "IF \"Procedure_Variables\".\"Blender_Run\".\"Running\" AND \"CLK_1.0S\" THEN\n \"Blender_Variables_Pers\".\"gSLIM_Sec\" := \"Blender_Variables_Pers\".\"gSLIM_Sec\" + 1;\nEND_IF;"
+ }
+ ]
+ },
+ {
+ "id": "1A",
+ "title": "Reset Hours",
+ "comment": "",
+ "logic": [
+ {
+ "instruction_uid": "24",
+ "uid": "24",
+ "type": "Contact_scl",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "21",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"SLIM_Variables\".\"ResetHour\""
+ },
+ "in": {
+ "type": "powerrail"
+ }
+ },
+ "outputs": {},
+ "scl": "// RLO updated by Contact 24: \"SLIM_Variables\".\"ResetHour\""
+ },
+ {
+ "instruction_uid": "25",
+ "uid": "25",
+ "type": "Move_scl",
+ "template_values": {
+ "Card": "Cardinality"
+ },
+ "inputs": {
+ "in": {
+ "uid": "22",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 0
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "24",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {
+ "out1": [
+ {
+ "uid": "23",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gSLIM_Sec\""
+ }
+ ]
+ },
+ "scl": "IF \"SLIM_Variables\".\"ResetHour\" THEN\n \"Blender_Variables_Pers\".\"gSLIM_Sec\" := 0;\nEND_IF;"
+ }
+ ]
+ },
+ {
+ "id": "2B",
+ "title": "Seconds Counter",
+ "comment": "",
+ "logic": [
+ {
+ "instruction_uid": "26",
+ "uid": "26",
+ "type": "Contact_scl",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "21",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"gBlenderBlending\""
+ },
+ "in": {
+ "type": "powerrail"
+ }
+ },
+ "outputs": {},
+ "scl": "// RLO updated by Contact 26: \"gBlenderBlending\""
+ },
+ {
+ "instruction_uid": "27",
+ "uid": "27",
+ "type": "Contact_scl",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "22",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"CLK_1.0S\""
+ },
+ "in": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "26",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {},
+ "scl": "// RLO updated by Contact 27: \"gBlenderBlending\" AND \"CLK_1.0S\""
+ },
+ {
+ "instruction_uid": "28",
+ "uid": "28",
+ "type": "Add_scl",
+ "template_values": {
+ "Card": "Cardinality",
+ "SrcType": "Type"
+ },
+ "inputs": {
+ "in2": {
+ "uid": "24",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 1
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "27",
+ "source_pin": "out"
+ },
+ "in1": {
+ "uid": "23",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gProdSec\""
+ }
+ },
+ "outputs": {
+ "out": [
+ {
+ "uid": "25",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gProdSec\""
+ }
+ ]
+ },
+ "scl": "IF \"gBlenderBlending\" AND \"CLK_1.0S\" THEN\n \"Blender_Variables_Pers\".\"gProdSec\" := \"Blender_Variables_Pers\".\"gProdSec\" + 1;\nEND_IF;"
+ }
+ ]
+ },
+ {
+ "id": "3C",
+ "title": "Minute",
+ "comment": "",
+ "logic": [
+ {
+ "instruction_uid": "24",
+ "uid": "24",
+ "type": "Eq_scl",
+ "template_values": {
+ "SrcType": "Type"
+ },
+ "inputs": {
+ "pre": {
+ "type": "powerrail"
+ },
+ "in2": {
+ "uid": "22",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 60
+ },
+ "in1": {
+ "uid": "21",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gProdSec\""
+ }
+ },
+ "outputs": {},
+ "scl": "// Comparison Eq 24: \"Blender_Variables_Pers\".\"gProdSec\" = 60"
+ },
+ {
+ "instruction_uid": "25",
+ "uid": "25",
+ "type": "Coil_scl",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "23",
+ "scope": "LocalVariable",
+ "type": "variable",
+ "name": "\"m1MinONS\""
+ },
+ "in": {
+ "type": "connection",
+ "source_instruction_type": "Eq",
+ "source_instruction_uid": "24",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {},
+ "scl": "\"m1MinONS\" := \"Blender_Variables_Pers\".\"gProdSec\" = 60;"
+ }
+ ]
+ },
+ {
+ "id": "4D",
+ "title": "Minute Counter",
+ "comment": "",
+ "logic": [
+ {
+ "instruction_uid": "27",
+ "uid": "27",
+ "type": "Contact_scl",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "21",
+ "scope": "LocalVariable",
+ "type": "variable",
+ "name": "\"m1MinONS\""
+ },
+ "in": {
+ "type": "powerrail"
+ }
+ },
+ "outputs": {},
+ "scl": "IF \"m1MinONS\" THEN\n \"Blender_Variables_Pers\".\"gProdSec\" := 0;\n \"Blender_Variables_Pers\".\"gProdMin\" := \"Blender_Variables_Pers\".\"gProdMin\" + 1;\nEND_IF;"
+ },
+ {
+ "instruction_uid": "28",
+ "uid": "28",
+ "type": "Move_scl",
+ "template_values": {
+ "Card": "Cardinality"
+ },
+ "inputs": {
+ "in": {
+ "uid": "22",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 0
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "27",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {
+ "out1": [
+ {
+ "uid": "23",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gProdSec\""
+ }
+ ]
+ },
+ "scl": "// Logic included in grouped IF (by UID 27)",
+ "grouped": true
+ },
+ {
+ "instruction_uid": "29",
+ "uid": "29",
+ "type": "Add_scl",
+ "template_values": {
+ "Card": "Cardinality",
+ "SrcType": "Type"
+ },
+ "inputs": {
+ "in2": {
+ "uid": "25",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 1
+ },
+ "in1": {
+ "uid": "24",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gProdMin\""
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_uid": "27",
+ "source_instruction_type": "Contact",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {
+ "out": [
+ {
+ "uid": "26",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gProdMin\""
+ }
+ ]
+ },
+ "scl": "// Logic included in grouped IF (by UID 27)",
+ "grouped": true
+ }
+ ]
+ },
+ {
+ "id": "5E",
+ "title": "Hour",
+ "comment": "",
+ "logic": [
+ {
+ "instruction_uid": "24",
+ "uid": "24",
+ "type": "Eq_scl",
+ "template_values": {
+ "SrcType": "Type"
+ },
+ "inputs": {
+ "pre": {
+ "type": "powerrail"
+ },
+ "in2": {
+ "uid": "22",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 60
+ },
+ "in1": {
+ "uid": "21",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gProdMin\""
+ }
+ },
+ "outputs": {},
+ "scl": "// Comparison Eq 24: \"Blender_Variables_Pers\".\"gProdMin\" = 60"
+ },
+ {
+ "instruction_uid": "25",
+ "uid": "25",
+ "type": "Coil_scl",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "23",
+ "scope": "LocalVariable",
+ "type": "variable",
+ "name": "\"m1HourONS\""
+ },
+ "in": {
+ "type": "connection",
+ "source_instruction_type": "Eq",
+ "source_instruction_uid": "24",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {},
+ "scl": "\"m1HourONS\" := \"Blender_Variables_Pers\".\"gProdMin\" = 60;"
+ }
+ ]
+ },
+ {
+ "id": "6F",
+ "title": "Hour Counter",
+ "comment": "",
+ "logic": [
+ {
+ "instruction_uid": "30",
+ "uid": "30",
+ "type": "Contact_scl",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "21",
+ "scope": "LocalVariable",
+ "type": "variable",
+ "name": "\"m1HourONS\""
+ },
+ "in": {
+ "type": "powerrail"
+ }
+ },
+ "outputs": {},
+ "scl": "IF \"m1HourONS\" THEN\n \"Blender_Variables_Pers\".\"gProdMin\" := 0;\n \"Blender_Variables_Pers\".\"gProdHour\" := \"Blender_Variables_Pers\".\"gProdHour\" + 1;\n \"Blender_Variables_Pers\".\"gBlendingMaintHour\" := \"Blender_Variables_Pers\".\"gBlendingMaintHour\" + 1;\nEND_IF;"
+ },
+ {
+ "instruction_uid": "31",
+ "uid": "31",
+ "type": "Move_scl",
+ "template_values": {
+ "Card": "Cardinality"
+ },
+ "inputs": {
+ "in": {
+ "uid": "22",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 0
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "30",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {
+ "out1": [
+ {
+ "uid": "23",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gProdMin\""
+ }
+ ]
+ },
+ "scl": "// Logic included in grouped IF (by UID 30)",
+ "grouped": true
+ },
+ {
+ "instruction_uid": "32",
+ "uid": "32",
+ "type": "Add_scl",
+ "template_values": {
+ "Card": "Cardinality",
+ "SrcType": "Type"
+ },
+ "inputs": {
+ "in2": {
+ "uid": "25",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 1
+ },
+ "in1": {
+ "uid": "24",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gProdHour\""
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_uid": "30",
+ "source_instruction_type": "Contact",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {
+ "out": [
+ {
+ "uid": "26",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gProdHour\""
+ }
+ ]
+ },
+ "scl": "// Logic included in grouped IF (by UID 30)",
+ "grouped": true
+ },
+ {
+ "instruction_uid": "33",
+ "uid": "33",
+ "type": "Add_scl",
+ "template_values": {
+ "Card": "Cardinality",
+ "SrcType": "Type"
+ },
+ "inputs": {
+ "in2": {
+ "uid": "28",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 1
+ },
+ "in1": {
+ "uid": "27",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gBlendingMaintHour\""
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_uid": "30",
+ "source_instruction_type": "Contact",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {
+ "out": [
+ {
+ "uid": "29",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gBlendingMaintHour\""
+ }
+ ]
+ },
+ "scl": "// Logic included in grouped IF (by UID 30)",
+ "grouped": true
+ }
+ ]
+ },
+ {
+ "id": "80",
+ "title": "Counter reset",
+ "comment": "",
+ "logic": [
+ {
+ "instruction_uid": "29",
+ "uid": "29",
+ "type": "Contact_scl",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "21",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"gBlenderCIPMode\""
+ },
+ "in": {
+ "type": "powerrail"
+ }
+ },
+ "outputs": {},
+ "scl": "// RLO updated by Contact 29: \"gBlenderCIPMode\""
+ },
+ {
+ "instruction_uid": "30",
+ "uid": "30",
+ "type": "Contact_scl",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "22",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"gBlenderRinseMode\""
+ }
+ },
+ "outputs": {},
+ "scl": "// RLO updated by Contact 30: \"gBlenderRinseMode\""
+ },
+ {
+ "instruction_uid": "31",
+ "uid": "31",
+ "type": "O_scl",
+ "template_values": {
+ "Card": "Cardinality"
+ },
+ "inputs": {
+ "in2": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "30",
+ "source_pin": "out"
+ },
+ "in1": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "29",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {},
+ "scl": "IF \"gBlenderCIPMode\" OR \"gBlenderRinseMode\" THEN\n \"Blender_Variables_Pers\".\"gProdSec\" := 0;\n \"Blender_Variables_Pers\".\"gProdMin\" := 0;\n \"Blender_Variables_Pers\".\"gProdHour\" := 0;\nEND_IF;"
+ },
+ {
+ "instruction_uid": "32",
+ "uid": "32",
+ "type": "Move_scl",
+ "template_values": {
+ "Card": "Cardinality"
+ },
+ "inputs": {
+ "in": {
+ "uid": "23",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 0
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_type": "O",
+ "source_instruction_uid": "31",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {
+ "out1": [
+ {
+ "uid": "24",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gProdSec\""
+ }
+ ]
+ },
+ "scl": "// Logic included in grouped IF (by UID 31)",
+ "grouped": true
+ },
+ {
+ "instruction_uid": "33",
+ "uid": "33",
+ "type": "Move_scl",
+ "template_values": {
+ "Card": "Cardinality"
+ },
+ "inputs": {
+ "in": {
+ "uid": "25",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 0
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_uid": "31",
+ "source_instruction_type": "O",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {
+ "out1": [
+ {
+ "uid": "26",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gProdMin\""
+ }
+ ]
+ },
+ "scl": "// Logic included in grouped IF (by UID 31)",
+ "grouped": true
+ },
+ {
+ "instruction_uid": "34",
+ "uid": "34",
+ "type": "Move_scl",
+ "template_values": {
+ "Card": "Cardinality"
+ },
+ "inputs": {
+ "in": {
+ "uid": "27",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 0
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_uid": "31",
+ "source_instruction_type": "O",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {
+ "out1": [
+ {
+ "uid": "28",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gProdHour\""
+ }
+ ]
+ },
+ "scl": "// Logic included in grouped IF (by UID 31)",
+ "grouped": true
+ }
+ ]
+ },
+ {
+ "id": "91",
+ "title": "Running Seconds",
+ "comment": "",
+ "logic": [
+ {
+ "instruction_uid": "26",
+ "uid": "26",
+ "type": "Contact_scl",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "21",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Procedure_Variables\".\"Blender_Run\".\"Running\""
+ },
+ "in": {
+ "type": "powerrail"
+ }
+ },
+ "outputs": {},
+ "scl": "// RLO updated by Contact 26: \"Procedure_Variables\".\"Blender_Run\".\"Running\""
+ },
+ {
+ "instruction_uid": "27",
+ "uid": "27",
+ "type": "Contact_scl",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "22",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"CLK_1.0S\""
+ },
+ "in": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "26",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {},
+ "scl": "// RLO updated by Contact 27: \"Procedure_Variables\".\"Blender_Run\".\"Running\" AND \"CLK_1.0S\""
+ },
+ {
+ "instruction_uid": "28",
+ "uid": "28",
+ "type": "Add_scl",
+ "template_values": {
+ "Card": "Cardinality",
+ "SrcType": "Type"
+ },
+ "inputs": {
+ "in2": {
+ "uid": "24",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 1
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "27",
+ "source_pin": "out"
+ },
+ "in1": {
+ "uid": "23",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gRunningSeconds\""
+ }
+ },
+ "outputs": {
+ "out": [
+ {
+ "uid": "25",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gRunningSeconds\""
+ }
+ ]
+ },
+ "scl": "IF \"Procedure_Variables\".\"Blender_Run\".\"Running\" AND \"CLK_1.0S\" THEN\n \"Blender_Variables_Pers\".\"gRunningSeconds\" := \"Blender_Variables_Pers\".\"gRunningSeconds\" + 1;\nEND_IF;"
+ }
+ ]
+ },
+ {
+ "id": "A2",
+ "title": "Running Minutes",
+ "comment": "",
+ "logic": [
+ {
+ "instruction_uid": "35",
+ "uid": "35",
+ "type": "Convert_scl",
+ "template_values": {
+ "SrcType": "Type",
+ "DestType": "Type"
+ },
+ "inputs": {
+ "in": {
+ "uid": "21",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gRunningSeconds\""
+ },
+ "en": {
+ "type": "powerrail"
+ }
+ },
+ "outputs": {
+ "out": [
+ {
+ "uid": "22",
+ "scope": "LocalVariable",
+ "type": "variable",
+ "name": "\"I_DIRunning_sec\""
+ }
+ ]
+ },
+ "scl": "\"I_DIRunning_sec\" := \"Blender_Variables_Pers\".\"gRunningSeconds\";"
+ },
+ {
+ "instruction_uid": "36",
+ "uid": "36",
+ "type": "Mod_scl",
+ "template_values": {
+ "SrcType": "Type"
+ },
+ "inputs": {
+ "in2": {
+ "uid": "24",
+ "scope": "TypedConstant",
+ "type": "constant",
+ "datatype": "TypedConstant",
+ "value": "DINT#60"
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_type": "Convert",
+ "source_instruction_uid": "35",
+ "source_pin": "eno"
+ },
+ "in1": {
+ "uid": "23",
+ "scope": "LocalVariable",
+ "type": "variable",
+ "name": "\"I_DIRunning_sec\""
+ }
+ },
+ "outputs": {
+ "out": [
+ {
+ "uid": "25",
+ "scope": "LocalVariable",
+ "type": "variable",
+ "name": "\"MOD60\""
+ }
+ ]
+ },
+ "eno_logic": [
+ {
+ "target_pin": "pre",
+ "target_type": "instruction",
+ "target_uid": "37",
+ "target_name": "Eq"
+ }
+ ],
+ "scl": "\"MOD60\" := \"I_DIRunning_sec\" MOD DINT#60;"
+ },
+ {
+ "instruction_uid": "37",
+ "uid": "37",
+ "type": "Eq_scl",
+ "template_values": {
+ "SrcType": "Type"
+ },
+ "inputs": {
+ "pre": {
+ "type": "connection",
+ "source_instruction_type": "Mod",
+ "source_instruction_uid": "36",
+ "source_pin": "eno"
+ },
+ "in2": {
+ "uid": "27",
+ "scope": "TypedConstant",
+ "type": "constant",
+ "datatype": "TypedConstant",
+ "value": "DINT#0"
+ },
+ "in1": {
+ "uid": "26",
+ "scope": "LocalVariable",
+ "type": "variable",
+ "name": "\"MOD60\""
+ }
+ },
+ "outputs": {},
+ "scl": "// Comparison Eq 37: \"MOD60\" = DINT#0"
+ },
+ {
+ "instruction_uid": "38",
+ "uid": "38",
+ "type": "Contact_scl",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "28",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Procedure_Variables\".\"Blender_Run\".\"Running\""
+ },
+ "in": {
+ "type": "connection",
+ "source_instruction_type": "Eq",
+ "source_instruction_uid": "37",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {},
+ "scl": "// RLO updated by Contact 38: \"MOD60\" = DINT#0 AND \"Procedure_Variables\".\"Blender_Run\".\"Running\""
+ },
+ {
+ "instruction_uid": "39",
+ "uid": "39",
+ "type": "Contact_scl",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "29",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"CLK_1.0S\""
+ },
+ "in": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "38",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {},
+ "scl": "// RLO updated by Contact 39: (\"MOD60\" = DINT#0 AND \"Procedure_Variables\".\"Blender_Run\".\"Running\") AND \"CLK_1.0S\""
+ },
+ {
+ "instruction_uid": "40",
+ "uid": "40",
+ "type": "Add_scl",
+ "template_values": {
+ "Card": "Cardinality",
+ "SrcType": "Type"
+ },
+ "inputs": {
+ "in2": {
+ "uid": "31",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 1
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "39",
+ "source_pin": "out"
+ },
+ "in1": {
+ "uid": "30",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gRunningMinutes\""
+ }
+ },
+ "outputs": {
+ "out": [
+ {
+ "uid": "32",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gRunningMinutes\""
+ }
+ ]
+ },
+ "scl": "IF (\"MOD60\" = DINT#0 AND \"Procedure_Variables\".\"Blender_Run\".\"Running\") AND \"CLK_1.0S\" THEN\n \"Blender_Variables_Pers\".\"gRunningMinutes\" := \"Blender_Variables_Pers\".\"gRunningMinutes\" + 1;\nEND_IF;"
+ },
+ {
+ "instruction_uid": "41",
+ "uid": "41",
+ "type": "PBox_scl",
+ "template_values": {},
+ "inputs": {
+ "bit": {
+ "uid": "33",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"M19012\""
+ }
+ },
+ "outputs": {},
+ "scl": "\"M19012\" := ((\"MOD60\" = DINT#0 AND \"Procedure_Variables\".\"Blender_Run\".\"Running\") AND \"CLK_1.0S\"); // Update edge memory bit"
+ },
+ {
+ "instruction_uid": "42",
+ "uid": "42",
+ "type": "Coil_scl",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "34",
+ "scope": "LocalVariable",
+ "type": "variable",
+ "name": "\"mRunMin\""
+ },
+ "in": {
+ "type": "connection",
+ "source_instruction_type": "PBox",
+ "source_instruction_uid": "41",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {},
+ "scl": "\"mRunMin\" := ((\"MOD60\" = DINT#0 AND \"Procedure_Variables\".\"Blender_Run\".\"Running\") AND \"CLK_1.0S\") AND NOT \"M19012\";"
+ }
+ ]
+ },
+ {
+ "id": "B3",
+ "title": "Running Hours for Maintenance",
+ "comment": "",
+ "logic": [
+ {
+ "instruction_uid": "32",
+ "uid": "32",
+ "type": "Contact_scl",
+ "template_values": {},
+ "inputs": {
+ "operand": {
+ "uid": "21",
+ "scope": "LocalVariable",
+ "type": "variable",
+ "name": "\"mRunMin\""
+ },
+ "in": {
+ "type": "powerrail"
+ }
+ },
+ "outputs": {},
+ "scl": "// RLO updated by Contact 32: \"mRunMin\""
+ },
+ {
+ "instruction_uid": "33",
+ "uid": "33",
+ "type": "Convert_scl",
+ "template_values": {
+ "SrcType": "Type",
+ "DestType": "Type"
+ },
+ "inputs": {
+ "in": {
+ "uid": "22",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gRunningMinutes\""
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "32",
+ "source_pin": "out"
+ }
+ },
+ "outputs": {
+ "out": [
+ {
+ "uid": "23",
+ "scope": "LocalVariable",
+ "type": "variable",
+ "name": "\"I_DIRunning_min\""
+ }
+ ]
+ },
+ "scl": "IF \"mRunMin\" THEN\n \"I_DIRunning_min\" := \"Blender_Variables_Pers\".\"gRunningMinutes\";\nEND_IF;"
+ },
+ {
+ "instruction_uid": "34",
+ "uid": "34",
+ "type": "Mod_scl",
+ "template_values": {
+ "SrcType": "Type"
+ },
+ "inputs": {
+ "in2": {
+ "uid": "25",
+ "scope": "TypedConstant",
+ "type": "constant",
+ "datatype": "TypedConstant",
+ "value": "DINT#60"
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_type": "Convert",
+ "source_instruction_uid": "33",
+ "source_pin": "eno"
+ },
+ "in1": {
+ "uid": "24",
+ "scope": "LocalVariable",
+ "type": "variable",
+ "name": "\"I_DIRunning_min\""
+ }
+ },
+ "outputs": {
+ "out": [
+ {
+ "uid": "26",
+ "scope": "LocalVariable",
+ "type": "variable",
+ "name": "\"MOD60\""
+ }
+ ]
+ },
+ "eno_logic": [
+ {
+ "target_pin": "pre",
+ "target_type": "instruction",
+ "target_uid": "35",
+ "target_name": "Eq"
+ }
+ ],
+ "scl": "IF \"mRunMin\" THEN\n \"MOD60\" := \"I_DIRunning_min\" MOD DINT#60;\nEND_IF;"
+ },
+ {
+ "instruction_uid": "35",
+ "uid": "35",
+ "type": "Eq_scl",
+ "template_values": {
+ "SrcType": "Type"
+ },
+ "inputs": {
+ "pre": {
+ "type": "connection",
+ "source_instruction_type": "Mod",
+ "source_instruction_uid": "34",
+ "source_pin": "eno"
+ },
+ "in2": {
+ "uid": "28",
+ "scope": "TypedConstant",
+ "type": "constant",
+ "datatype": "TypedConstant",
+ "value": "DINT#0"
+ },
+ "in1": {
+ "uid": "27",
+ "scope": "LocalVariable",
+ "type": "variable",
+ "name": "\"MOD60\""
+ }
+ },
+ "outputs": {},
+ "scl": "// Comparison Eq 35: \"MOD60\" = DINT#0"
+ },
+ {
+ "instruction_uid": "36",
+ "uid": "36",
+ "type": "Add_scl",
+ "template_values": {
+ "Card": "Cardinality",
+ "SrcType": "Type"
+ },
+ "inputs": {
+ "in2": {
+ "uid": "30",
+ "scope": "LiteralConstant",
+ "type": "constant",
+ "datatype": "Int",
+ "value": 1
+ },
+ "en": {
+ "type": "connection",
+ "source_instruction_type": "Eq",
+ "source_instruction_uid": "35",
+ "source_pin": "out"
+ },
+ "in1": {
+ "uid": "29",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gRunningMaintHour\""
+ }
+ },
+ "outputs": {
+ "out": [
+ {
+ "uid": "31",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gRunningMaintHour\""
+ }
+ ]
+ },
+ "scl": "IF \"MOD60\" = DINT#0 THEN\n \"Blender_Variables_Pers\".\"gRunningMaintHour\" := \"Blender_Variables_Pers\".\"gRunningMaintHour\" + 1;\nEND_IF;"
+ }
+ ]
+ },
+ {
+ "id": "C4",
+ "title": "Running Hours for Maintenance",
+ "comment": "",
+ "logic": [
+ {
+ "instruction_uid": "23",
+ "uid": "23",
+ "type": "Move_scl",
+ "template_values": {
+ "Card": "Cardinality"
+ },
+ "inputs": {
+ "in": {
+ "uid": "21",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Blender_Variables_Pers\".\"gRunningMaintHour\""
+ },
+ "en": {
+ "type": "powerrail"
+ }
+ },
+ "outputs": {
+ "out1": [
+ {
+ "uid": "22",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"HMI_Variables_Status\".\"System\".\"BlendingMaintHour\""
+ }
+ ]
+ },
+ "scl": "\"HMI_Variables_Status\".\"System\".\"BlendingMaintHour\" := \"Blender_Variables_Pers\".\"gRunningMaintHour\";"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/BlenderRun_ProdTime_simplified_processed.scl b/BlenderRun_ProdTime_simplified_processed.scl
new file mode 100644
index 0000000..7af1511
--- /dev/null
+++ b/BlenderRun_ProdTime_simplified_processed.scl
@@ -0,0 +1,120 @@
+// Block Name (Original): BlenderRun_ProdTime
+// Block Number: 2040
+// Original Language: LAD
+
+FUNCTION_BLOCK "BlenderRun_ProdTime"
+{ S7_Optimized_Access := 'TRUE' }
+VERSION : 0.1
+
+VAR_INPUT
+END_VAR
+
+VAR_OUTPUT
+END_VAR
+
+VAR_IN_OUT
+END_VAR
+
+VAR_TEMP
+ m1MinONS : Bool;
+ m1HourONS : Bool;
+ Buffer : Bool;
+ mRunMin : Bool;
+ mRunHr : Bool;
+ I_DIRunning_sec : DInt;
+ I_DIRunning_min : DInt;
+ MOD60 : DInt;
+END_VAR
+
+BEGIN
+
+ // Network 1: Seconds
+
+ IF "Procedure_Variables"."Blender_Run"."Running" AND "CLK_1.0S" THEN
+ "Blender_Variables_Pers"."gSLIM_Sec" := "Blender_Variables_Pers"."gSLIM_Sec" + 1;
+ END_IF;
+
+ // Network 2: Reset Hours
+
+ IF "SLIM_Variables"."ResetHour" THEN
+ "Blender_Variables_Pers"."gSLIM_Sec" := 0;
+ END_IF;
+
+ // Network 3: Seconds Counter
+
+ IF "gBlenderBlending" AND "CLK_1.0S" THEN
+ "Blender_Variables_Pers"."gProdSec" := "Blender_Variables_Pers"."gProdSec" + 1;
+ END_IF;
+
+ // Network 4: Minute
+
+ "m1MinONS" := "Blender_Variables_Pers"."gProdSec" = 60;
+
+ // Network 5: Minute Counter
+
+ IF "m1MinONS" THEN
+ "Blender_Variables_Pers"."gProdSec" := 0;
+ "Blender_Variables_Pers"."gProdMin" := "Blender_Variables_Pers"."gProdMin" + 1;
+ END_IF;
+ // Logic included in grouped IF (by UID 27)
+ // Logic included in grouped IF (by UID 27)
+
+ // Network 6: Hour
+
+ "m1HourONS" := "Blender_Variables_Pers"."gProdMin" = 60;
+
+ // Network 7: Hour Counter
+
+ IF "m1HourONS" THEN
+ "Blender_Variables_Pers"."gProdMin" := 0;
+ "Blender_Variables_Pers"."gProdHour" := "Blender_Variables_Pers"."gProdHour" + 1;
+ "Blender_Variables_Pers"."gBlendingMaintHour" := "Blender_Variables_Pers"."gBlendingMaintHour" + 1;
+ END_IF;
+ // Logic included in grouped IF (by UID 30)
+ // Logic included in grouped IF (by UID 30)
+ // Logic included in grouped IF (by UID 30)
+
+ // Network 8: Counter reset
+
+ IF "gBlenderCIPMode" OR "gBlenderRinseMode" THEN
+ "Blender_Variables_Pers"."gProdSec" := 0;
+ "Blender_Variables_Pers"."gProdMin" := 0;
+ "Blender_Variables_Pers"."gProdHour" := 0;
+ END_IF;
+ // Logic included in grouped IF (by UID 31)
+ // Logic included in grouped IF (by UID 31)
+ // Logic included in grouped IF (by UID 31)
+
+ // Network 9: Running Seconds
+
+ IF "Procedure_Variables"."Blender_Run"."Running" AND "CLK_1.0S" THEN
+ "Blender_Variables_Pers"."gRunningSeconds" := "Blender_Variables_Pers"."gRunningSeconds" + 1;
+ END_IF;
+
+ // Network 10: Running Minutes
+
+ "I_DIRunning_sec" := "Blender_Variables_Pers"."gRunningSeconds";
+ "MOD60" := "I_DIRunning_sec" MOD DINT#60;
+ 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;
+ "M19012" := (("MOD60" = DINT#0 AND "Procedure_Variables"."Blender_Run"."Running") AND "CLK_1.0S"); // Update edge memory bit
+ "mRunMin" := (("MOD60" = DINT#0 AND "Procedure_Variables"."Blender_Run"."Running") AND "CLK_1.0S") AND NOT "M19012";
+
+ // Network 11: Running Hours for Maintenance
+
+ IF "mRunMin" THEN
+ "I_DIRunning_min" := "Blender_Variables_Pers"."gRunningMinutes";
+ END_IF;
+ IF "mRunMin" THEN
+ "MOD60" := "I_DIRunning_min" MOD DINT#60;
+ END_IF;
+ IF "MOD60" = DINT#0 THEN
+ "Blender_Variables_Pers"."gRunningMaintHour" := "Blender_Variables_Pers"."gRunningMaintHour" + 1;
+ END_IF;
+
+ // Network 12: Running Hours for Maintenance
+
+ "HMI_Variables_Status"."System"."BlendingMaintHour" := "Blender_Variables_Pers"."gRunningMaintHour";
+
+END_FUNCTION_BLOCK
diff --git a/TestLAD.xml b/TestLAD.xml
new file mode 100644
index 0000000..b9a9111
--- /dev/null
+++ b/TestLAD.xml
@@ -0,0 +1,486 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Optimized
+ TestLAD
+
+ 2
+ LAD
+ false
+
+
+
+
+
+
+ it-IT
+
+
+
+
+
+ de-DE
+
+
+
+
+
+ en-US
+
+
+
+
+
+ es-ES
+
+
+
+
+
+ fr-FR
+
+
+
+
+
+ zh-CN
+
+
+
+
+
+ ja-JP
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ LAD
+
+
+
+
+
+
+ it-IT
+
+
+
+
+
+ de-DE
+
+
+
+
+
+ en-US
+
+
+
+
+
+ es-ES
+
+
+
+
+
+ fr-FR
+
+
+
+
+
+ zh-CN
+
+
+
+
+
+ ja-JP
+
+
+
+
+
+
+
+
+
+ it-IT
+ Clock Bit
+
+
+
+
+ de-DE
+
+
+
+
+
+ en-US
+
+
+
+
+
+ es-ES
+
+
+
+
+
+ fr-FR
+
+
+
+
+
+ zh-CN
+
+
+
+
+
+ ja-JP
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ LAD
+
+
+
+
+
+
+ it-IT
+
+
+
+
+
+ de-DE
+
+
+
+
+
+ en-US
+
+
+
+
+
+ es-ES
+
+
+
+
+
+ fr-FR
+
+
+
+
+
+ zh-CN
+
+
+
+
+
+ ja-JP
+
+
+
+
+
+
+
+
+
+ it-IT
+ Clock Bit
+
+
+
+
+ de-DE
+
+
+
+
+
+ en-US
+
+
+
+
+
+ es-ES
+
+
+
+
+
+ fr-FR
+
+
+
+
+
+ zh-CN
+
+
+
+
+
+ ja-JP
+
+
+
+
+
+
+
+
+
+
+ LAD
+
+
+
+
+
+
+ it-IT
+
+
+
+
+
+ de-DE
+
+
+
+
+
+ en-US
+
+
+
+
+
+ es-ES
+
+
+
+
+
+ fr-FR
+
+
+
+
+
+ zh-CN
+
+
+
+
+
+ ja-JP
+
+
+
+
+
+
+
+
+
+ it-IT
+
+
+
+
+
+ de-DE
+
+
+
+
+
+ en-US
+
+
+
+
+
+ es-ES
+
+
+
+
+
+ fr-FR
+
+
+
+
+
+ zh-CN
+
+
+
+
+
+ ja-JP
+
+
+
+
+
+
+
+
+
+
+
+ it-IT
+
+
+
+
+
+ de-DE
+
+
+
+
+
+ en-US
+
+
+
+
+
+ es-ES
+
+
+
+
+
+ fr-FR
+
+
+
+
+
+ zh-CN
+
+
+
+
+
+ ja-JP
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TestLAD_simplified.json b/TestLAD_simplified.json
new file mode 100644
index 0000000..56f91e2
--- /dev/null
+++ b/TestLAD_simplified.json
@@ -0,0 +1,121 @@
+{
+ "block_name": "TestLAD",
+ "block_number": 2,
+ "language": "LAD",
+ "block_comment": "",
+ "interface": {
+ "Return": [
+ {
+ "name": "Ret_Val",
+ "datatype": "Void"
+ }
+ ]
+ },
+ "networks": [
+ {
+ "id": "9",
+ "title": "Clock Bit",
+ "comment": "",
+ "logic": [
+ {
+ "instruction_uid": "23",
+ "uid": "23",
+ "type": "Contact",
+ "template_values": {},
+ "negated_pins": {},
+ "inputs": {
+ "in": {
+ "type": "powerrail"
+ },
+ "operand": {
+ "uid": "21",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Clock_10Hz\""
+ }
+ },
+ "outputs": {}
+ },
+ {
+ "instruction_uid": "24",
+ "uid": "24",
+ "type": "Coil",
+ "template_values": {},
+ "negated_pins": {},
+ "inputs": {
+ "in": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "23",
+ "source_pin": "out"
+ },
+ "operand": {
+ "uid": "22",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Clock_5Hz\""
+ }
+ },
+ "outputs": {}
+ }
+ ]
+ },
+ {
+ "id": "1A",
+ "title": "Clock Bit",
+ "comment": "",
+ "logic": [
+ {
+ "instruction_uid": "23",
+ "uid": "23",
+ "type": "Contact",
+ "template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
+ "inputs": {
+ "in": {
+ "type": "powerrail"
+ },
+ "operand": {
+ "uid": "21",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Clock_10Hz\""
+ }
+ },
+ "outputs": {}
+ },
+ {
+ "instruction_uid": "24",
+ "uid": "24",
+ "type": "Coil",
+ "template_values": {},
+ "negated_pins": {},
+ "inputs": {
+ "in": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "23",
+ "source_pin": "out"
+ },
+ "operand": {
+ "uid": "22",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Clock_5Hz\""
+ }
+ },
+ "outputs": {}
+ }
+ ]
+ },
+ {
+ "id": "2B",
+ "title": "",
+ "comment": "",
+ "logic": [],
+ "error": "FlgNet not found"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/TestLAD_simplified_processed.json b/TestLAD_simplified_processed.json
new file mode 100644
index 0000000..20b13e6
--- /dev/null
+++ b/TestLAD_simplified_processed.json
@@ -0,0 +1,125 @@
+{
+ "block_name": "TestLAD",
+ "block_number": 2,
+ "language": "LAD",
+ "block_comment": "",
+ "interface": {
+ "Return": [
+ {
+ "name": "Ret_Val",
+ "datatype": "Void"
+ }
+ ]
+ },
+ "networks": [
+ {
+ "id": "9",
+ "title": "Clock Bit",
+ "comment": "",
+ "logic": [
+ {
+ "instruction_uid": "23",
+ "uid": "23",
+ "type": "Contact_scl",
+ "template_values": {},
+ "negated_pins": {},
+ "inputs": {
+ "in": {
+ "type": "powerrail"
+ },
+ "operand": {
+ "uid": "21",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Clock_10Hz\""
+ }
+ },
+ "outputs": {},
+ "scl": "// RLO: \"Clock_10Hz\""
+ },
+ {
+ "instruction_uid": "24",
+ "uid": "24",
+ "type": "Coil_scl",
+ "template_values": {},
+ "negated_pins": {},
+ "inputs": {
+ "in": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "23",
+ "source_pin": "out"
+ },
+ "operand": {
+ "uid": "22",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Clock_5Hz\""
+ }
+ },
+ "outputs": {},
+ "scl": "\"Clock_5Hz\" := \"Clock_10Hz\";"
+ }
+ ]
+ },
+ {
+ "id": "1A",
+ "title": "Clock Bit",
+ "comment": "",
+ "logic": [
+ {
+ "instruction_uid": "23",
+ "uid": "23",
+ "type": "Contact_scl",
+ "template_values": {},
+ "negated_pins": {
+ "operand": true
+ },
+ "inputs": {
+ "in": {
+ "type": "powerrail"
+ },
+ "operand": {
+ "uid": "21",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Clock_10Hz\""
+ }
+ },
+ "outputs": {},
+ "scl": "// RLO: (NOT \"Clock_10Hz\")"
+ },
+ {
+ "instruction_uid": "24",
+ "uid": "24",
+ "type": "Coil_scl",
+ "template_values": {},
+ "negated_pins": {},
+ "inputs": {
+ "in": {
+ "type": "connection",
+ "source_instruction_type": "Contact",
+ "source_instruction_uid": "23",
+ "source_pin": "out"
+ },
+ "operand": {
+ "uid": "22",
+ "scope": "GlobalVariable",
+ "type": "variable",
+ "name": "\"Clock_5Hz\""
+ }
+ },
+ "outputs": {},
+ "scl": "\"Clock_5Hz\" := (NOT \"Clock_10Hz\");"
+ }
+ ]
+ },
+ {
+ "id": "2B",
+ "title": "",
+ "comment": "",
+ "logic": [],
+ "error": "FlgNet not found"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/TestLAD_simplified_processed.scl b/TestLAD_simplified_processed.scl
new file mode 100644
index 0000000..6113687
--- /dev/null
+++ b/TestLAD_simplified_processed.scl
@@ -0,0 +1,35 @@
+// Block Name (Original): TestLAD
+// Block Number: 2
+// Original Language: LAD
+
+FUNCTION_BLOCK "TestLAD"
+{ S7_Optimized_Access := 'TRUE' }
+VERSION : 0.1
+
+VAR_INPUT
+END_VAR
+
+VAR_OUTPUT
+END_VAR
+
+VAR_IN_OUT
+END_VAR
+
+VAR_TEMP
+END_VAR
+
+BEGIN
+
+ // Network 1: Clock Bit
+
+ // RLO: "Clock_10Hz"
+ "Clock_5Hz" := "Clock_10Hz";
+
+ // Network 2: Clock Bit
+
+ // RLO: (NOT "Clock_10Hz")
+ "Clock_5Hz" := (NOT "Clock_10Hz");
+
+ // Network 3:
+
+END_FUNCTION_BLOCK
diff --git a/TestLAD_simplified_processed.scl.txt b/TestLAD_simplified_processed.scl.txt
new file mode 100644
index 0000000..93e785e
--- /dev/null
+++ b/TestLAD_simplified_processed.scl.txt
@@ -0,0 +1,33 @@
+// Block Name (Original): TestLAD
+// Block Number: 2
+// Original Language: LAD
+
+FUNCTION_BLOCK "TestLAD"
+{ S7_Optimized_Access := 'TRUE' }
+VERSION : 0.1
+
+VAR_INPUT
+END_VAR
+
+VAR_OUTPUT
+END_VAR
+
+VAR_IN_OUT
+END_VAR
+
+VAR_TEMP
+END_VAR
+
+BEGIN
+
+ // Network 1: Clock Bit
+
+ "Clock_5Hz" := "Clock_10Hz";
+
+ // Network 2: Clock Bit
+
+ "Clock_5Hz" := "Clock_10Hz";
+
+ // Network 3:
+
+END_FUNCTION_BLOCK
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..db5b447
--- /dev/null
+++ b/readme.md
@@ -0,0 +1,160 @@
+# LAD-to-SCL Conversion Pipeline: Documentación de Referencia
+
+## 1. Visión General
+
+Este documento describe un pipeline de scripts de Python diseñado para convertir bloques de función o funciones (FC/FB) escritos en Ladder Logic (LAD) desde archivos XML de TIA Portal Openness a un código SCL (Structured Control Language) semánticamente equivalente.
+
+El proceso se divide en tres etapas principales, cada una manejada por un script específico:
+
+1. **XML a JSON Enriquecido (`x1_to_json.py`):** Parsea el XML de Openness, extrae la estructura lógica y las conexiones explícitas, e **infiere conexiones implícitas** (especialmente las habilitaciones EN) para crear un archivo JSON detallado.
+2. **Procesamiento Semántico (`process.py`):** Lee el JSON enriquecido y, de forma iterativa, traduce cada instrucción LAD a su equivalente SCL, manejando dependencias, propagando el estado lógico (RLO), y agrupando lógica paralela. El SCL generado se almacena *dentro* del propio JSON.
+3. **Generación de SCL Final (`generate_scl.py`):** Lee el JSON completamente procesado y ensambla el código SCL final en un archivo `.scl` formateado, incluyendo declaraciones de variables y el cuerpo del programa.
+
+## 2. Etapas del Pipeline
+
+### Etapa 1: XML a JSON Enriquecido (`x1_to_json.py`)
+
+* **Propósito:** Transformar la compleja y a veces ambigua estructura XML de Openness en un formato JSON estructurado y más fácil de procesar, añadiendo información clave que está implícita en el LAD visual pero no siempre explícita en el XML.
+* **Entrada:** Archivo `.xml` exportado desde TIA Portal Openness para un FC o FB.
+* **Salida:** Archivo `_simplified.json`.
+* **Proceso Clave:**
+ 1. **Parseo XML:** Utiliza `lxml` para leer el archivo XML.
+ 2. **Extracción de Metadatos:** Obtiene nombre del bloque, número, lenguaje original, comentario del bloque.
+ 3. **Extracción de Interfaz:** Parsea las secciones `Input`, `Output`, `InOut`, `Temp`, `Constant`, `Return` para obtener la declaración de variables.
+ 4. **Parseo de Redes (`CompileUnit`):** Itera sobre cada red lógica.
+ * **`parse_network`:**
+ * **Parseo de Componentes:**
+ * `Access`: Identifica variables globales/locales, constantes literales y tipadas (`parse_access`).
+ * `Part`: Identifica instrucciones estándar LAD como `Contact`, `Coil`, `Move`, `Add`, etc. **Importante:** Detecta pines negados (``) y los almacena en `negated_pins` (`parse_part`).
+ * `Call`: Identifica llamadas a otros FCs o FBs, extrayendo el nombre del bloque llamado, tipo (FC/FB) e información de instancia DB si aplica (`parse_call`).
+ * Crea `access_map` y `parts_and_calls_map` para referencia rápida.
+ * **Parseo de Conexiones (`Wire`):**
+ * Construye `wire_connections`: Un mapa `(dest_uid, dest_pin) -> [(src_uid, src_pin), ...]`.
+ * Construye `source_connections`: Un mapa `(src_uid, src_pin) -> [(dest_uid, dest_pin), ...]`.
+ * Construye `eno_outputs`: Un mapa `src_uid -> [(dest_uid, dest_pin), ...]` para conexiones que *salen* de un pin `eno`.
+ * **Construcción Lógica Inicial:** Crea una lista de diccionarios (`all_logic_steps`), uno por cada `Part` o `Call`, rellenando `inputs` y `outputs` **solo con las conexiones explícitas** encontradas en los `Wire`.
+ * **Inferencia de Conexión `EN` (¡Paso Crucial!):**
+ * Itera sobre los bloques funcionales (`Move`, `Add`, `Call`, etc.) que *no* tienen una entrada `en` explícita definida después del paso anterior.
+ * Utiliza una **heurística** (buscar hacia atrás en la lista ordenada por UID) para encontrar la fuente de RLO más probable que precede a este bloque (la salida `out` de un bloque lógico como `Contact`/`O`/`Eq` o la salida `eno` de un bloque funcional anterior).
+ * Si se encuentra una fuente inferida, **añade la conexión `en`** al diccionario `inputs` del bloque funcional actual. Esto enriquece el JSON con la dependencia lógica implícita.
+ * **Adición de Lógica ENO Interesante:** Identifica las conexiones que salen de un pin `eno` y *no* van directamente al pin `en` de la siguiente instrucción, almacenándolas en el campo `eno_logic`.
+ * **Ordenamiento:** Ordena las instrucciones en la lista `logic` final (generalmente por UID).
+ 5. **Escritura JSON:** Guarda la estructura de datos completa en el archivo `_simplified.json`.
+
+### Etapa 2: Procesamiento Semántico (`process.py`)
+
+* **Propósito:** Traducir la lógica LAD (representada en el JSON enriquecido) a código SCL embebido, resolviendo dependencias entre instrucciones y aplicando optimizaciones de agrupación.
+* **Entrada:** Archivo `_simplified.json` (generado por la Etapa 1).
+* **Salida:** Archivo `_simplified_scl_processed.json`.
+* **Proceso Clave:**
+ 1. **Carga de JSON y Preparación:** Lee el JSON de entrada y reconstruye mapas de acceso por red. Inicializa el `scl_map` global (o por red).
+ 2. **Bucle Iterativo:** Repite los siguientes pasos hasta que no se realicen cambios en un pase completo o se alcance un límite máximo de pases.
+ * **Fase 1: Procesadores Base:**
+ * Itera sobre cada instrucción en cada red.
+ * Si la instrucción no ha sido procesada (`_scl` o `_error`) ni agrupada (`grouped`), busca el procesador adecuado (`process_xxx`) basado en su `type`.
+ * **`process_xxx` (Ejecución):**
+ * Llama a `get_scl_representation` para obtener el SCL de sus pines de entrada, buscándolos en `scl_map` o directamente en `access_map`.
+ * Si alguna dependencia no está resuelta (devuelve `None`), el procesador retorna `False`.
+ * Si las dependencias están resueltas:
+ * **Generadores RLO (`Contact`, `O`, `Eq`, `PBox`):** Calculan la expresión booleana SCL resultante y la almacenan en `scl_map` bajo la clave `(network_id, instr_uid, 'out')`. También almacenan el estado `EN` en `scl_map` para `eno` si aplica. Guardan un comentario en `instruction['scl']`.
+ * **Bloques Funcionales (`Move`, `Add`, `Convert`, `Mod`, `Call`):**
+ * Obtienen la condición `EN` (explícita o inferida por el JSON enriquecido).
+ * Generan el código SCL *core* (la asignación o cálculo).
+ * Generan el SCL final, **siempre incluyendo `IF en_scl THEN ... END_IF;`** si `en_scl` no es exactamente `"TRUE"`.
+ * Almacenan el SCL final en `instruction['scl']`.
+ * Almacenan el nombre de la variable de salida (o temporal) en `scl_map` para `out`/`out1`.
+ * Almacenan el `en_scl` en `scl_map` para `eno`.
+ * **Bobinas (`Coil`):** Obtienen el RLO de entrada (`in`), obtienen el operando destino, generan la asignación `destino := rlo;` y la guardan en `instruction['scl']`.
+ * Marcan la instrucción como procesada añadiendo `_scl` a `instruction['type']`.
+ * Retornan `True`.
+ * Se registra si hubo algún cambio en esta fase (`made_change_in_base_pass`).
+ * **Fase 2: Agrupación de IFs (`process_group_ifs`):**
+ * Itera sobre las instrucciones *ya procesadas* (`_scl`) que son generadoras de condición (`Contact`, `O`, `Eq`, etc.).
+ * Obtiene la `condition_scl` de `scl_map`.
+ * Busca todos los bloques funcionales (`Move_scl`, `Add_scl`, etc.) cuyo pin `EN` esté conectado a la salida de esta instrucción generadora.
+ * Verifica si el SCL de estos consumidores *ya* contiene un `IF condition_scl THEN...`.
+ * Si encuentra **más de uno** con la misma condición `IF`:
+ * Extrae el código *core* (lo que está dentro del `IF...END_IF;`) de cada consumidor.
+ * Construye un **único bloque `IF condition_scl THEN ... END_IF;`** que contiene todos los cores extraídos.
+ * **Sobrescribe** el campo `scl` de la instrucción *generadora de condición* con este nuevo bloque `IF` agrupado.
+ * Marca cada instrucción consumidora con `grouped = True` y cambia su `scl` a un comentario (`GROUPED_COMMENT`) para evitar que `generate_scl.py` lo use.
+ * Se registra si hubo algún cambio en esta fase (`made_change_in_group_pass`).
+ * **Condición de Salida:** El bucle termina si `made_change_in_base_pass` y `made_change_in_group_pass` son ambos `False`.
+ 3. **Escritura JSON:** Guarda el JSON modificado (con SCL embebido y marcas de agrupación) en el archivo `_simplified_scl_processed.json`.
+
+### Etapa 3: Generación de SCL Final (`generate_scl.py`)
+
+* **Propósito:** Ensamblar un archivo `.scl` completo y formateado a partir del JSON procesado.
+* **Entrada:** Archivo `_simplified_scl_processed.json` (generado por la Etapa 2).
+* **Salida:** Archivo `.scl`.
+* **Proceso Clave:**
+ 1. **Carga de JSON:** Lee el archivo JSON procesado.
+ 2. **Generación de Cabecera:** Escribe el encabezado del bloque (`FUNCTION_BLOCK name`, `VERSION`, etc.).
+ 3. **Generación de Declaraciones VAR:**
+ * Escribe las secciones `VAR_INPUT`, `VAR_OUTPUT`, `VAR_IN_OUT`, `VAR_TEMP`, `VAR_STAT`.
+ * Rellena cada sección con las variables definidas en la `interface` del JSON.
+ * **Detecta y declara** variables temporales (`_temp_...`) y estáticas (`stat_...`) encontradas en el SCL generado (requiere inferencia de tipo básica o usar `Variant`).
+ 4. **Generación del Cuerpo (`BEGIN`/`END_FUNCTION_BLOCK`):**
+ * Itera sobre las `networks` en el JSON.
+ * Añade comentarios de red.
+ * Itera sobre la `logic` de cada red.
+ * Para cada `instruction`:
+ * **Verifica el flag `grouped`:** Si `instruction.get('grouped', False)` es `True`, **ignora** esta instrucción (su lógica ya está en otro lugar).
+ * Si no está agrupada, obtiene el valor del campo `scl`.
+ * **Limpia comentarios internos:** Opcionalmente, elimina comentarios como `// RLO:` o `// Cond:` que fueron útiles para depurar `process.py` pero no son necesarios en el SCL final (excepto quizás los de PBox/flancos).
+ * Indenta y añade las líneas del SCL al output.
+ * Añade líneas en blanco entre redes si contienen código.
+ 5. **Escritura de Archivo:** Escribe el string SCL completo al archivo `.scl`.
+
+## 3. Cómo Extender para Nuevas Instrucciones LAD/FBD
+
+Añadir soporte para un nuevo tipo de instrucción (p.ej., un temporizador `TON`, un comparador `GT`, o una función matemática `SQRT`) requiere modificar los scripts `x1_to_json.py` y `process.py`.
+
+**Pasos:**
+
+1. **Analizar el XML:** Exporta un bloque simple que use la nueva instrucción y examina el XML de Openness. Identifica:
+ * Si se representa como `` o ``.
+ * Sus pines de entrada y salida (`NameCon`/`IdentCon` en los `Wire`).
+ * Cualquier atributo o `TemplateValue` relevante.
+ * Si tiene pines negados (``).
+
+2. **Modificar `x1_to_json.py` (`parse_network`):**
+ * **Parseo:** Asegúrate de que `parse_part` o `parse_call` (o una nueva función si es muy diferente) capture correctamente la nueva instrucción y sus atributos específicos. Añade su `type` al `parts_and_calls_map`.
+ * **Clasificación:** Decide si la nueva instrucción es un `functional_block_type` (tiene EN/ENO implícito/explícito) o un `rlo_generator` (modifica el flujo lógico principal). Actualiza estas listas si es necesario.
+ * **Inferencia EN:** Si es un bloque funcional, revisa si la lógica de inferencia EN necesita ajustes para manejar este nuevo tipo correctamente (aunque si tiene un `EN` explícito en el XML, la inferencia no debería ser necesaria).
+ * **Salidas:** Asegúrate de que sus pines de salida relevantes (`out`, `Q`, etc.) sean considerados por otros bloques y por la lógica `eno_outputs` si tiene `ENO`.
+
+3. **Modificar `process.py`:**
+ * **Crear Procesador:** Escribe una nueva función `process_nombre_instruccion(instruction, network_id, scl_map, access_map, ...)`.
+ * **Lógica SCL:** Implementa la traducción:
+ * Obtén las representaciones SCL de las entradas necesarias usando `get_scl_representation`.
+ * Verifica que todas las dependencias estén resueltas.
+ * Genera el SCL core equivalente.
+ * Maneja la habilitación `EN`: Obtén `en_scl`. Si `en_scl` no es `"TRUE"`, envuelve el SCL core en `IF en_scl THEN ... END_IF;`.
+ * Almacena el SCL final en `instruction['scl']`.
+ * Actualiza `instruction['type']` con el sufijo `_scl`.
+ * **Actualiza `scl_map`:** Añade entradas para los pines de salida (`out`, `Q`, etc.) con su representación SCL (puede ser un nombre de variable temporal o el resultado de una expresión). Añade la entrada para `eno` si el bloque lo tiene (generalmente `scl_map[key_eno] = en_scl`).
+ * Retorna `True`.
+ * **Añadir a la Lista:** Inserta la nueva función `process_nombre_instruccion` en la lista `base_processors` en el orden de prioridad correcto (generalmente, generadores de valores/condiciones antes que consumidores).
+ * **Agrupación:** Considera si este nuevo bloque debería ser parte de la lógica de agrupación (¿es un bloque funcional que puede ser habilitado en paralelo?). Si es así, no necesita cambios especiales aquí si se usa el enfoque de `process_group_ifs`. Si se usa el enfoque integrado, el generador de condición necesitaría saber cómo obtener el SCL core de este nuevo tipo.
+
+4. **Modificar `generate_scl.py` (Menos Frecuente):**
+ * **Declaraciones:** Si la nueva instrucción introduce la necesidad de tipos específicos de variables temporales o estáticas, ajusta la lógica de detección y declaración en `generate_scl.py`.
+ * **Limpieza de Comentarios:** Si el nuevo procesador genera comentarios específicos que no quieres en el SCL final, ajusta el filtro en `generate_scl.py`.
+
+5. **Probar:** Ejecuta el pipeline completo con un XML que contenga la nueva instrucción y verifica los JSON intermedios y el SCL final.
+
+## 4. Futuras Mejoras y Consideraciones
+
+* **Manejo de Tipos de Datos:** Implementar un seguimiento y conversión de tipos más robusto. Inferir tipos para variables temporales. Usar funciones de conversión SCL explícitas (`INT_TO_DINT`, etc.).
+* **Lógica de Flancos Completa:** Implementar correctamente la lógica de variables estáticas para `P_TRIG`/`N_TRIG` (o generar instancias de FB `FP`/`FN`).
+* **Soporte para FBs:** Manejar correctamente las llamadas a FBs con sus DBs de instancia y parámetros complejos.
+* **Optimización SCL:** Además de agrupar IFs, implementar otras optimizaciones (eliminación de código muerto, simplificación de expresiones).
+* **Estructuras LAD Complejas:** Mejorar la inferencia de EN para manejar bifurcaciones y uniones más complejas, o idealmente, rediseñar `x1_to_json.py` para un análisis topológico completo. Manejar saltos (`JMP`).
+* **Manejo de Errores:** Mejorar el reporte de errores y la resiliencia ante XMLs inesperados.
+* **Interfaz Gráfica/Configuración:** Crear una interfaz más amigable o archivos de configuración para gestionar el proceso.
+* **Soporte para otros lenguajes (FBD/SCL):** Extender el parser para manejar otros lenguajes de origen.
+
+## 5. Conclusión
+
+Este pipeline proporciona una base sólida para la conversión automática de LAD a SCL. Siguiendo los pasos de extensión, se puede añadir soporte para más instrucciones y mejorar la calidad y completitud de la conversión. La clave es el enfoque iterativo y la separación de responsabilidades entre el parseo/enriquecimiento del JSON y el procesamiento semántico/generación de SCL.
\ No newline at end of file
diff --git a/x1_to_json.py b/x1_to_json.py
index fa13257..94ccf15 100644
--- a/x1_to_json.py
+++ b/x1_to_json.py
@@ -147,29 +147,36 @@ def parse_access(access_element):
def parse_part(part_element):
- if part_element is None:
- return None
- uid = part_element.get("UId")
- name = part_element.get("Name")
- if not uid or not name:
- print(
- f"Error: Part sin UID o Name: {etree.tostring(part_element, encoding='unicode')}"
- )
- return None
+ """
+ Parsea un elemento Part (instrucción) y extrae UID, nombre,
+ valores de plantilla y pines negados.
+ """
+ if part_element is None: return None
+ uid = part_element.get('UId'); name = part_element.get('Name')
+ if not uid or not name: 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")
- if tv_name and tv_type:
- template_values[tv_name] = tv_type
- except Exception as e:
- print(f"Advertencia: Error extrayendo TemplateValues Part UID={uid}: {e}")
+ 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 Part UID={uid}: {e}")
+
+ # --- INICIO NUEVA LÓGICA PARA NEGACIÓN ---
+ negated_pins = {} # Diccionario para pines negados: {pin_name: True}
+ try:
+ for negated_elem in part_element.xpath("./*[local-name()='Negated']"):
+ negated_pin_name = negated_elem.get('Name')
+ if negated_pin_name:
+ negated_pins[negated_pin_name] = True
+ # print(f"DEBUG: Pin negado detectado: {name} UID {uid}, Pin: {negated_pin_name}") # Debug
+ except Exception as e: print(f"Advertencia: Error extrayendo Negated Pins Part UID={uid}: {e}")
return {
- "uid": uid,
- "type": name,
- "template_values": template_values,
- } # Cambiado Name a type
+ 'uid': uid,
+ 'type': name, # Usar 'type' para consistencia
+ 'template_values': template_values,
+ 'negated_pins': negated_pins # Añadir diccionario de pines negados
+ }
# --- NUEVA FUNCIÓN parse_call ---
diff --git a/x2_process.py b/x2_process.py
index f76418c..f8119bf 100644
--- a/x2_process.py
+++ b/x2_process.py
@@ -14,7 +14,7 @@ data = {}
# --- Helper Functions ---
-# (get_scl_representation, generate_temp_var_name, get_target_scl_name - sin cambios)
+# (get_scl_representation, format_variable_name, generate_temp_var_name, get_target_scl_name - sin cambios)
def get_scl_representation(source_info, network_id, scl_map, access_map):
if not source_info:
return None
@@ -47,7 +47,12 @@ def get_scl_representation(source_info, network_id, scl_map, access_map):
return "TRUE"
elif source_type == "variable":
name = source_info.get("name")
- return name if name else f"_ERR_VAR_NO_NAME_{source_info.get('uid')}_"
+ # Asegurar que los nombres de variables se formatean correctamente aquí también
+ return (
+ format_variable_name(name)
+ if name
+ else f"_ERR_VAR_NO_NAME_{source_info.get('uid')}_"
+ )
elif source_type == "constant":
dtype = str(source_info.get("datatype", "")).upper()
value = source_info.get("value")
@@ -73,11 +78,16 @@ def get_scl_representation(source_info, network_id, scl_map, access_map):
s_val = str(value)
return s_val if "." in s_val or "e" in s_val.lower() else s_val + ".0"
elif dtype == "STRING":
- return f"'{str(value)}'"
+ # Escapar comillas simples dentro del string si es necesario
+ str_val = str(value).replace("'", "''")
+ return f"'{str_val}'"
elif dtype == "TYPEDCONSTANT":
+ # Podría necesitar formateo específico basado en el tipo real
return str(value)
else:
- return f"'{str(value)}'"
+ # Otros tipos (TIME, DATE, etc.) - devolver como string por ahora
+ str_val = str(value).replace("'", "''")
+ return f"'{str_val}'"
except Exception as e:
print(f"Advertencia: Error formateando constante {source_info}: {e}")
return f"_ERR_CONST_FORMAT_{source_info.get('uid')}_"
@@ -99,34 +109,40 @@ def get_scl_representation(source_info, network_id, scl_map, access_map):
def format_variable_name(name):
- """Limpia el nombre de la variable quitando comillas y espacios."""
+ """Limpia el nombre de la variable para SCL."""
if not name:
return "_INVALID_NAME_"
- # Quita comillas dobles iniciales/finales
- name = name.strip('"')
- # Reemplaza comillas dobles internas y puntos por guión bajo
- # ¡Cuidado! Reemplazar '.' puede ser problemático para accesos a DBs/UDTs
- # Quizás solo reemplazar si está dentro de comillas? Más complejo.
- # Por ahora, mantenemos el reemplazo simple, asumiendo nombres de bloque limpios.
- name = name.replace('"."', "_").replace(
- ".", "_"
- ) # <-- REVISAR SI ESTO ES SEGURO PARA TODOS LOS NOMBRES
- # Quita comillas restantes (si las hubiera)
- name = name.replace('"', "")
- # Asegurarse de que no empiece con número
+
+ # Si ya está entre comillas dobles, asumimos que es un nombre complejo (ej. "DB"."Variable")
+ # y lo devolvemos tal cual para SCL.
+ if name.startswith('"') and name.endswith('"'):
+ # Podríamos añadir validación extra aquí si fuera necesario
+ return name
+
+ # Si no tiene comillas, es un nombre simple (ej. Tag_1, #tempVar)
+ # Reemplazar caracteres no válidos (excepto '_') por '_'
+ # Permitir '#' al inicio para variables temporales
+ prefix = ""
+ if name.startswith("#"):
+ prefix = "#"
+ name = name[1:]
+
+ # Permitir letras, números y guiones bajos. Reemplazar el resto.
+ # Asegurarse de que no empiece con número (después del # si existe)
if name and name[0].isdigit():
name = "_" + name
- # Devolver entre comillas si el nombre original las tenía o contiene caracteres no estándar
- # (Simplificación: por ahora no añadimos comillas automáticas aquí)
- return name
+ # Reemplazar caracteres no válidos
+ name = re.sub(r"[^a-zA-Z0-9_]", "_", name)
+
+ return prefix + name
def generate_temp_var_name(network_id, instr_uid, pin_name):
net_id_clean = str(network_id).replace("-", "_")
instr_uid_clean = str(instr_uid).replace("-", "_")
pin_name_clean = str(pin_name).replace("-", "_").lower()
- prefix = "_" if str(net_id_clean)[0].isdigit() else ""
- return f"{prefix}temp_{net_id_clean}_{instr_uid_clean}_{pin_name_clean}"
+ # Usar # para variables temporales SCL estándar
+ return f"#_temp_{net_id_clean}_{instr_uid_clean}_{pin_name_clean}"
def get_target_scl_name(instruction, output_pin_name, network_id, default_to_temp=True):
@@ -141,7 +157,9 @@ def get_target_scl_name(instruction, output_pin_name, network_id, default_to_tem
dest_access = output_pin_data[0]
if dest_access.get("type") == "variable":
target_scl = dest_access.get("name")
- if not target_scl:
+ if target_scl:
+ target_scl = format_variable_name(target_scl) # Formatear nombre
+ else:
print(
f"Error: Var destino {instr_uid}.{output_pin_name} sin nombre (UID: {dest_access.get('uid')}). {'Usando temp.' if default_to_temp else 'Ignorando.'}"
)
@@ -170,19 +188,37 @@ def get_target_scl_name(instruction, output_pin_name, network_id, default_to_tem
)
elif default_to_temp:
target_scl = generate_temp_var_name(network_id, instr_uid, output_pin_name)
+
+ # Si target_scl sigue siendo None y no se debe usar temp, devolver None
+ if target_scl is None and not default_to_temp:
+ return None
+
+ # Si target_scl es None pero sí se permite temp, generar uno ahora
+ if target_scl is None and default_to_temp:
+ target_scl = generate_temp_var_name(network_id, instr_uid, output_pin_name)
+
return target_scl
-# --- Procesadores de Instrucciones (SIMPLIFICADOS - Siempre generan IF si EN no es TRUE) ---
-
-
+# --- Procesadores de Instrucciones ---
+# (process_contact, process_eq, process_coil, process_convert, process_mod,
+# process_add, process_move, process_pbox, process_o, process_call - sin cambios significativos,
+# solo asegurar que usan format_variable_name donde sea necesario para operandos/destinos)
+# ... (código de los procesadores aquí, asumiendo que ya usan format_variable_name) ...
def process_contact(instruction, network_id, scl_map, access_map):
- # (Sin cambios respecto a la versión funcional anterior, solo actualiza scl_map)
+ """Traduce Contact (normal o negado) a una expresión booleana SCL."""
instr_uid = instruction["instruction_uid"]
instr_type = instruction["type"]
if instr_type.endswith(SCL_SUFFIX) or "_error" in instr_type:
return False
- is_negated = False # TODO
+
+ # --- INICIO LEER NEGACIÓN ---
+ # Verificar si el pin 'operand' está marcado como negado en el JSON
+ is_negated = instruction.get("negated_pins", {}).get("operand", False)
+ # --- FIN LEER NEGACIÓN ---
+
+ # print(f"DEBUG: Intentando procesar CONTACT{' (N)' if is_negated else ''} - UID: {instr_uid} en Red: {network_id}")
+
in_input = instruction["inputs"].get("in")
in_rlo_scl = (
"TRUE"
@@ -192,12 +228,19 @@ def process_contact(instruction, network_id, scl_map, access_map):
operand_scl = get_scl_representation(
instruction["inputs"].get("operand"), network_id, scl_map, access_map
)
+
if in_rlo_scl is None or operand_scl is None:
return False
+
+ # Usar is_negated para aplicar NOT
term = f"NOT {operand_scl}" if is_negated else operand_scl
if not (term.startswith('"') and term.endswith('"')):
- if " " in term and not (term.startswith("(") and term.endswith(")")):
+ # Añadir paréntesis si es NOT o si contiene espacios/operadores
+ if is_negated or (
+ " " in term and not (term.startswith("(") and term.endswith(")"))
+ ):
term = f"({term})"
+
new_rlo_scl = (
term
if in_rlo_scl == "TRUE"
@@ -208,32 +251,51 @@ def process_contact(instruction, network_id, scl_map, access_map):
else f"{in_rlo_scl} AND {term}"
)
)
+
map_key = (network_id, instr_uid, "out")
scl_map[map_key] = new_rlo_scl
- instruction["scl"] = f"// RLO: {new_rlo_scl}" # SCL es solo comentario aquí
+ instruction["scl"] = f"// RLO: {new_rlo_scl}"
instruction["type"] = instr_type + SCL_SUFFIX
return True
def process_eq(instruction, network_id, scl_map, access_map):
- # (Sin cambios respecto a la versión funcional anterior, solo actualiza scl_map)
instr_uid = instruction["instruction_uid"]
instr_type = instruction["type"]
if instr_type.endswith(SCL_SUFFIX) or "_error" in instr_type:
return False
- in1_scl = get_scl_representation(
- instruction["inputs"].get("in1"), network_id, scl_map, access_map
- )
- in2_scl = get_scl_representation(
- instruction["inputs"].get("in2"), network_id, scl_map, access_map
- )
+
+ in1_info = instruction["inputs"].get("in1")
+ in2_info = instruction["inputs"].get("in2")
+ in1_scl = get_scl_representation(in1_info, network_id, scl_map, access_map)
+ in2_scl = get_scl_representation(in2_info, network_id, scl_map, access_map)
+
if in1_scl is None or in2_scl is None:
- return False
- op1 = f"({in1_scl})" if " " in in1_scl else in1_scl
- op2 = f"({in2_scl})" if " " in in2_scl else in2_scl
+ return False # Dependencias no listas
+
+ # Formatear operandos si son variables
+ op1 = (
+ format_variable_name(in1_scl)
+ if in1_info and in1_info.get("type") == "variable"
+ else in1_scl
+ )
+ op2 = (
+ format_variable_name(in2_scl)
+ if in2_info and in2_info.get("type") == "variable"
+ else in2_scl
+ )
+
+ # Añadir paréntesis si los operandos contienen espacios (poco probable después de formatear)
+ op1 = f"({op1})" if " " in op1 and not op1.startswith("(") else op1
+ op2 = f"({op2})" if " " in op2 and not op2.startswith("(") else op2
+
comparison_scl = f"{op1} = {op2}"
+
+ # Guardar el resultado booleano de la comparación en el mapa SCL para la salida 'out'
map_key_out = (network_id, instr_uid, "out")
scl_map[map_key_out] = comparison_scl
+
+ # Procesar la entrada 'pre' (RLO anterior) para determinar ENO
pre_input = instruction["inputs"].get("pre")
pre_scl = (
"TRUE"
@@ -241,39 +303,61 @@ def process_eq(instruction, network_id, scl_map, access_map):
else get_scl_representation(pre_input, network_id, scl_map, access_map)
)
if pre_scl is None:
- return False
+ return False # Dependencia 'pre' no lista
+
+ # Guardar el estado de 'pre' como ENO
map_key_eno = (network_id, instr_uid, "eno")
scl_map[map_key_eno] = pre_scl
- instruction["scl"] = f"// Cond: {comparison_scl}"
+
+ # El SCL generado es solo un comentario indicando la condición,
+ # ya que la lógica se propaga a través de scl_map['out']
+ instruction["scl"] = f"// Comparison Eq {instr_uid}: {comparison_scl}"
instruction["type"] = instr_type + SCL_SUFFIX
return True
def process_coil(instruction, network_id, scl_map, access_map):
- # (Sin cambios respecto a la versión funcional anterior)
instr_uid = instruction["instruction_uid"]
instr_type = instruction["type"]
if instr_type.endswith(SCL_SUFFIX) or "_error" in instr_type:
return False
+
in_rlo_scl = get_scl_representation(
instruction["inputs"].get("in"), network_id, scl_map, access_map
)
operand_info = instruction["inputs"].get("operand")
operand_scl = get_scl_representation(operand_info, network_id, scl_map, access_map)
+
if in_rlo_scl is None or operand_scl is None:
- return False
+ return False # Dependencias no listas
+
+ # Validar y formatear operando
if not (operand_info and operand_info.get("type") == "variable"):
- print(f"Error: Operando COIL {instr_uid} no es var")
- instruction["scl"] = f"// ERROR: Coil {instr_uid} operando no es variable"
+ print(f"Error: Operando COIL {instr_uid} no es variable o falta información.")
+ instruction["scl"] = (
+ f"// ERROR: Coil {instr_uid} operando no es variable o falta info"
+ )
instruction["type"] = instr_type + "_error"
- return True
+ return True # Marcar como procesado (con error)
+
+ operand_scl_formatted = format_variable_name(operand_scl)
+
+ # Simplificar RLO si es posible
if in_rlo_scl == "(TRUE)":
in_rlo_scl = "TRUE"
elif in_rlo_scl == "(FALSE)":
in_rlo_scl = "FALSE"
- scl_final = f"{operand_scl} := {in_rlo_scl};"
+
+ # Generar la asignación SCL
+ scl_final = f"{operand_scl_formatted} := {in_rlo_scl};"
instruction["scl"] = scl_final
instruction["type"] = instr_type + SCL_SUFFIX
+
+ # Las bobinas no suelen tener salida ENO explícita en este contexto,
+ # pero podríamos propagar el RLO de entrada si fuera necesario para alguna lógica posterior.
+ # map_key_eno = (network_id, instr_uid, "eno")
+ # scl_map[map_key_eno] = in_rlo_scl
+
return True
@@ -284,15 +368,13 @@ def process_convert(instruction, network_id, scl_map, access_map):
return False
en_input = instruction["inputs"].get("en")
- # Ahora EN debe existir si es necesario, no asumimos TRUE si falta
en_scl = (
get_scl_representation(en_input, network_id, scl_map, access_map)
if en_input
else "TRUE"
- ) # Asumir TRUE solo si no hay 'en' key
- in_scl = get_scl_representation(
- instruction["inputs"].get("in"), network_id, scl_map, access_map
)
+ in_info = instruction["inputs"].get("in")
+ in_scl = get_scl_representation(in_info, network_id, scl_map, access_map)
if en_scl is None or in_scl is None:
return False # Esperar si dependencias no listas
@@ -301,12 +383,35 @@ def process_convert(instruction, network_id, scl_map, access_map):
instruction, "out", network_id, default_to_temp=True
)
if target_scl is None:
- print(f"Error: Sin destino CONVERT {instr_uid}")
+ print(f"Error: Sin destino claro para CONVERT {instr_uid}")
+ instruction["scl"] = f"// ERROR: Convert {instr_uid} sin destino"
instruction["type"] += "_error"
- return True
+ return True # Procesado con error
- conversion_expr = in_scl # TODO: Logica de conversion explicita
+ # Formatear entrada si es variable
+ in_scl_formatted = (
+ format_variable_name(in_scl)
+ if in_info and in_info.get("type") == "variable"
+ else in_scl
+ )
+
+ # Determinar el tipo de destino (simplificado, necesitaría info del XML original)
+ # Asumimos que el tipo está en TemplateValues o inferirlo del nombre/contexto
+ target_type = instruction.get("template_values", {}).get(
+ "destType", "VARIANT"
+ ) # Ejemplo, ajustar según XML real
+ conversion_func = f"{target_type}_TO_" # Necesita el tipo de origen también
+ # Esta parte es compleja sin saber los tipos exactos. Usaremos una conversión genérica o MOVE.
+ # Para una conversión real, necesitaríamos algo como:
+ # conversion_expr = f"CONVERT(IN := {in_scl_formatted}, OUT => {target_scl})" # Sintaxis inventada
+ # O usar funciones específicas: INT_TO_REAL, etc.
+
+ # Simplificación: Usar asignación directa (MOVE implícito) o función genérica si existe
+ # Asumiremos asignación directa por ahora.
+ conversion_expr = in_scl_formatted
scl_core = f"{target_scl} := {conversion_expr};"
+
+ # Añadir IF EN si es necesario
scl_final = (
f"IF {en_scl} THEN\n {scl_core}\nEND_IF;" if en_scl != "TRUE" else scl_core
)
@@ -314,9 +419,9 @@ def process_convert(instruction, network_id, scl_map, access_map):
instruction["scl"] = scl_final
instruction["type"] = instr_type + SCL_SUFFIX
map_key_out = (network_id, instr_uid, "out")
- scl_map[map_key_out] = target_scl
+ scl_map[map_key_out] = target_scl # El valor de salida es el contenido del destino
map_key_eno = (network_id, instr_uid, "eno")
- scl_map[map_key_eno] = en_scl
+ scl_map[map_key_eno] = en_scl # ENO sigue a EN
return True
@@ -332,12 +437,10 @@ def process_mod(instruction, network_id, scl_map, access_map):
if en_input
else "TRUE"
)
- in1_scl = get_scl_representation(
- instruction["inputs"].get("in1"), network_id, scl_map, access_map
- )
- in2_scl = get_scl_representation(
- instruction["inputs"].get("in2"), network_id, scl_map, access_map
- )
+ in1_info = instruction["inputs"].get("in1")
+ in2_info = instruction["inputs"].get("in2")
+ in1_scl = get_scl_representation(in1_info, network_id, scl_map, access_map)
+ in2_scl = get_scl_representation(in2_info, network_id, scl_map, access_map)
if en_scl is None or in1_scl is None or in2_scl is None:
return False
@@ -347,11 +450,26 @@ def process_mod(instruction, network_id, scl_map, access_map):
)
if target_scl is None:
print(f"Error: Sin destino MOD {instr_uid}")
+ instruction["scl"] = f"// ERROR: Mod {instr_uid} sin destino"
instruction["type"] += "_error"
return True
- op1 = f"({in1_scl})" if " " in in1_scl else in1_scl
- op2 = f"({in2_scl})" if " " in in2_scl else in2_scl
+ # Formatear operandos si son variables
+ op1 = (
+ format_variable_name(in1_scl)
+ if in1_info and in1_info.get("type") == "variable"
+ else in1_scl
+ )
+ op2 = (
+ format_variable_name(in2_scl)
+ if in2_info and in2_info.get("type") == "variable"
+ else in2_scl
+ )
+
+ # Añadir paréntesis si es necesario (poco probable tras formatear)
+ op1 = f"({op1})" if " " in op1 and not op1.startswith("(") else op1
+ op2 = f"({op2})" if " " in op2 and not op2.startswith("(") else op2
+
scl_core = f"{target_scl} := {op1} MOD {op2};"
scl_final = (
f"IF {en_scl} THEN\n {scl_core}\nEND_IF;" if en_scl != "TRUE" else scl_core
@@ -378,12 +496,10 @@ def process_add(instruction, network_id, scl_map, access_map):
if en_input
else "TRUE"
)
- in1_scl = get_scl_representation(
- instruction["inputs"].get("in1"), network_id, scl_map, access_map
- )
- in2_scl = get_scl_representation(
- instruction["inputs"].get("in2"), network_id, scl_map, access_map
- )
+ in1_info = instruction["inputs"].get("in1")
+ in2_info = instruction["inputs"].get("in2")
+ in1_scl = get_scl_representation(in1_info, network_id, scl_map, access_map)
+ in2_scl = get_scl_representation(in2_info, network_id, scl_map, access_map)
if en_scl is None or in1_scl is None or in2_scl is None:
return False
@@ -393,11 +509,26 @@ def process_add(instruction, network_id, scl_map, access_map):
)
if target_scl is None:
print(f"Error: Sin destino ADD {instr_uid}")
+ instruction["scl"] = f"// ERROR: Add {instr_uid} sin destino"
instruction["type"] += "_error"
return True
- op1 = f"({in1_scl})" if " " in in1_scl else in1_scl
- op2 = f"({in2_scl})" if " " in in2_scl else in2_scl
+ # Formatear operandos si son variables
+ op1 = (
+ format_variable_name(in1_scl)
+ if in1_info and in1_info.get("type") == "variable"
+ else in1_scl
+ )
+ op2 = (
+ format_variable_name(in2_scl)
+ if in2_info and in2_info.get("type") == "variable"
+ else in2_scl
+ )
+
+ # Añadir paréntesis si es necesario
+ op1 = f"({op1})" if " " in op1 and not op1.startswith("(") else op1
+ op2 = f"({op2})" if " " in op2 and not op2.startswith("(") else op2
+
scl_core = f"{target_scl} := {op1} + {op2};"
scl_final = (
f"IF {en_scl} THEN\n {scl_core}\nEND_IF;" if en_scl != "TRUE" else scl_core
@@ -424,45 +555,84 @@ def process_move(instruction, network_id, scl_map, access_map):
if en_input
else "TRUE"
)
- in_scl = get_scl_representation(
- instruction["inputs"].get("in"), network_id, scl_map, access_map
- )
+ in_info = instruction["inputs"].get("in")
+ in_scl = get_scl_representation(in_info, network_id, scl_map, access_map)
if en_scl is None or in_scl is None:
return False
+ # Intentar obtener el destino de 'out1' (o 'out' si es el estándar)
target_scl = get_target_scl_name(
instruction, "out1", network_id, default_to_temp=False
- ) # No usar temp por defecto
+ )
if target_scl is None:
- print(f"Advertencia: MOVE {instr_uid} sin destino claro.")
- return False # No procesar
+ target_scl = get_target_scl_name(
+ instruction, "out", network_id, default_to_temp=False
+ )
- scl_core = f"{target_scl} := {in_scl};"
+ if target_scl is None:
+ # Si no hay destino explícito, podríamos usar una temp si la lógica lo requiere,
+ # pero MOVE generalmente necesita un destino claro. Marcar como advertencia/error.
+ print(
+ f"Advertencia/Error: MOVE {instr_uid} sin destino claro en 'out' o 'out1'. Se requiere destino explícito."
+ )
+ # Decidir si generar error o simplemente no hacer nada. No hacer nada es más seguro.
+ # instruction["scl"] = f"// ERROR: MOVE {instr_uid} sin destino"
+ # instruction["type"] += "_error"
+ # return True
+ return False # No procesar si no hay destino claro
+
+ # Formatear entrada si es variable
+ in_scl_formatted = (
+ format_variable_name(in_scl)
+ if in_info and in_info.get("type") == "variable"
+ else in_scl
+ )
+
+ scl_core = f"{target_scl} := {in_scl_formatted};"
scl_final = (
f"IF {en_scl} THEN\n {scl_core}\nEND_IF;" if en_scl != "TRUE" else scl_core
)
instruction["scl"] = scl_final
instruction["type"] = instr_type + SCL_SUFFIX
+
+ # Propagar el valor movido a través de scl_map si se usa 'out' o 'out1' como fuente
+ map_key_out = (network_id, instr_uid, "out") # Asumir 'out' como estándar
+ scl_map[map_key_out] = target_scl # El valor es lo que está en el destino
+ map_key_out1 = (network_id, instr_uid, "out1") # Si existe out1
+ scl_map[map_key_out1] = target_scl
+
+ map_key_eno = (network_id, instr_uid, "eno")
+ scl_map[map_key_eno] = en_scl
return True
def process_pbox(instruction, network_id, scl_map, access_map, network_logic_list):
- # (Sin cambios respecto a la versión funcional anterior)
instr_uid = instruction["instruction_uid"]
instr_type = instruction["type"]
if instr_type.endswith(SCL_SUFFIX) or "_error" in instr_type:
return False
+
mem_bit_input = instruction["inputs"].get("bit")
mem_bit_scl = get_scl_representation(mem_bit_input, network_id, scl_map, access_map)
+
if mem_bit_scl is None:
- return False
+ return False # Dependencia no lista
+
+ # Validar y formatear el bit de memoria
if not (mem_bit_input and mem_bit_input.get("type") == "variable"):
- print(f"Error: PBOX {instr_uid} bit no es var")
- instruction["scl"] = f"// ERROR: PBox {instr_uid} bit no es var"
+ print(f"Error: PBOX {instr_uid} 'bit' no es variable o falta información.")
+ instruction["scl"] = (
+ f"// ERROR: PBox {instr_uid} 'bit' no es variable o falta info"
+ )
instruction["type"] += "_error"
- return True
+ return True # Procesado con error
+
+ mem_bit_scl_formatted = format_variable_name(mem_bit_scl)
+
+ # --- Lógica para inferir CLK (similar a la versión anterior) ---
+ # Determinar si es P_TRIG (conectado a una bobina)
is_likely_p_trig = False
consuming_coil_uid = None
for potential_consumer in network_logic_list:
@@ -471,140 +641,269 @@ def process_pbox(instruction, network_id, scl_map, access_map, network_logic_lis
isinstance(coil_input_signal, dict)
and coil_input_signal.get("type") == "connection"
and coil_input_signal.get("source_instruction_uid") == instr_uid
- and coil_input_signal.get("source_pin") == "out"
+ and coil_input_signal.get("source_pin")
+ == "out" # PBox output alimenta la bobina
):
- if (
+ consumer_type_original = (
potential_consumer.get("type", "")
.replace("_scl", "")
.replace("_error", "")
- == "Coil"
- ):
+ )
+ if consumer_type_original == "Coil":
is_likely_p_trig = True
- break
- rlo_scl = None
+ consuming_coil_uid = potential_consumer.get("instruction_uid")
+ break # Encontrado consumidor de bobina
+
+ rlo_scl = None # Este será el CLK inferido
if is_likely_p_trig:
+ # Buscar hacia atrás la fuente del RLO que alimenta este PBox
clk_source_found = False
current_instr_index = -1
for i, instr in enumerate(network_logic_list):
if instr["instruction_uid"] == instr_uid:
current_instr_index = i
break
+
if current_instr_index != -1:
- for i in range(current_instr_index - 1, -1, -1):
- prev_instr = network_logic_list[i]
- prev_instr_uid = prev_instr["instruction_uid"]
- prev_instr_type = (
- prev_instr.get("type", "")
- .replace(SCL_SUFFIX, "")
- .replace("_error", "")
+ # Buscar la entrada 'in' del PBox si existe explícitamente
+ pbox_in_signal = instruction.get("inputs", {}).get("in")
+ if pbox_in_signal:
+ rlo_scl = get_scl_representation(
+ pbox_in_signal, network_id, scl_map, access_map
)
- if prev_instr_type in [
- "Contact",
- "Eq",
- "O",
- "PBox",
- "And",
- "Xor",
- "Ne",
- "Gt",
- "Lt",
- "Ge",
- "Le",
- ]:
- map_key_prev_out = (network_id, prev_instr_uid, "out")
- potential_clk_scl = scl_map.get(map_key_prev_out)
- if potential_clk_scl is not None:
- rlo_scl = potential_clk_scl
- clk_source_found = True
- break
- elif prev_instr_type in ["Move", "Add", "Convert", "Mod"]:
- map_key_prev_eno = (network_id, prev_instr_uid, "eno")
- potential_clk_scl = scl_map.get(map_key_prev_eno)
- if potential_clk_scl is not None:
- rlo_scl = potential_clk_scl
- clk_source_found = True
+ if rlo_scl is not None:
+ clk_source_found = True
+ # print(f"DEBUG: PBox {instr_uid} CLK encontrado por pin 'in': {rlo_scl}")
+
+ # Si no hay pin 'in' explícito, buscar hacia atrás (lógica LAD clásica)
+ if not clk_source_found:
+ # print(f"DEBUG: PBox {instr_uid} buscando CLK hacia atrás...")
+ for i in range(current_instr_index - 1, -1, -1):
+ prev_instr = network_logic_list[i]
+ prev_instr_uid = prev_instr["instruction_uid"]
+ prev_instr_type_original = (
+ prev_instr.get("type", "")
+ .replace(SCL_SUFFIX, "")
+ .replace("_error", "")
+ )
+
+ # ¿Es una instrucción que genera RLO booleano?
+ if prev_instr_type_original in [
+ "Contact",
+ "Eq",
+ "O",
+ "PBox",
+ "And",
+ "Xor",
+ "Ne",
+ "Gt",
+ "Lt",
+ "Ge",
+ "Le",
+ ]:
+ map_key_prev_out = (network_id, prev_instr_uid, "out")
+ potential_clk_scl = scl_map.get(map_key_prev_out)
+ if potential_clk_scl is not None:
+ rlo_scl = potential_clk_scl
+ clk_source_found = True
+ # print(f"DEBUG: PBox {instr_uid} CLK encontrado de {prev_instr_type_original} {prev_instr_uid} (out): {rlo_scl}")
+ break
+ # ¿Es un bloque funcional cuya salida ENO podría ser el RLO?
+ elif prev_instr_type_original in [
+ "Move",
+ "Add",
+ "Convert",
+ "Mod",
+ "Call",
+ ]: # Añadir otros bloques funcionales
+ map_key_prev_eno = (network_id, prev_instr_uid, "eno")
+ potential_clk_scl = scl_map.get(map_key_prev_eno)
+ if potential_clk_scl is not None:
+ rlo_scl = potential_clk_scl
+ clk_source_found = True
+ # print(f"DEBUG: PBox {instr_uid} CLK encontrado de {prev_instr_type_original} {prev_instr_uid} (eno): {rlo_scl}")
+ break
+ # Si encontramos una bobina, el RLO se detiene ahí
+ elif prev_instr_type_original == "Coil":
+ # print(f"DEBUG: PBox {instr_uid} búsqueda CLK detenida por Coil {prev_instr_uid}")
break
+
if not clk_source_found:
- print(f"Error: No se pudo inferir CLK PBOX {instr_uid}")
- instruction["scl"] = f"// ERROR: PBox {instr_uid} sin CLK"
+ print(f"Error: No se pudo inferir CLK para P_TRIG PBOX {instr_uid}")
+ instruction["scl"] = f"// ERROR: PBox {instr_uid} (P_TRIG) sin CLK inferido"
instruction["type"] += "_error"
- return True
+ return True # Procesado con error
+
if rlo_scl is None:
- return False
+ # print(f"DEBUG: PBox {instr_uid} CLK encontrado pero valor es None, esperando...")
+ return False # Dependencia (CLK) no resuelta aún
+
+ # --- Generar SCL ---
scl_comment = ""
+ result_scl = "" # El valor que PBox pone en scl_map['out']
+
if is_likely_p_trig:
- clk_signal_formatted = f"({rlo_scl})" if " " in rlo_scl else rlo_scl
- result_scl = f"P_TRIG_FUNC(CLK := {clk_signal_formatted}, M := {mem_bit_scl})"
- scl_comment = f"// Edge PBox {instr_uid} -> {result_scl}"
- else:
- print(f"Advertencia: PBox {instr_uid} no como P_TRIG. Pasando bit.")
- result_scl = mem_bit_scl
- scl_comment = f"// PBox {instr_uid} - Passing bit: {result_scl}"
+ # Formatear CLK si es variable (poco probable, suele ser resultado lógico)
+ # clk_signal_formatted = format_variable_name(rlo_scl) if ... else rlo_scl
+ clk_signal_formatted = (
+ rlo_scl # Asumir que ya está bien formateado o es una expresión
+ )
+
+ # Añadir paréntesis si CLK es complejo
+ if (
+ " " in clk_signal_formatted
+ or "AND" in clk_signal_formatted
+ or "OR" in clk_signal_formatted
+ ) and not (
+ clk_signal_formatted.startswith("(") and clk_signal_formatted.endswith(")")
+ ):
+ clk_signal_formatted = f"({clk_signal_formatted})"
+
+ # Generar llamada a función de flanco (asumimos P_TRIG)
+ # Necesitamos un nombre para la instancia del flanco, usualmente una variable STAT
+ # Podríamos generarla automáticamente o requerirla en el XML.
+ # Generación automática:
+ stat_var_name = f"stat_{network_id}_{instr_uid}_ptrig"
+ stat_var_name_scl = format_variable_name(f'"{stat_var_name}"') # Poner comillas
+
+ # La generación SCL real depende de si usamos una función o lógica explícita.
+ # Usando función estándar (requiere declarar la instancia 'stat_var_name_scl' como P_TRIG en VAR_STAT):
+ # result_scl = f"{stat_var_name_scl}(CLK := {clk_signal_formatted})" # La función devuelve Q
+ # scl_comment = f"// P_TRIG {instr_uid}: {result_scl}"
+ # instruction["scl"] = f"{stat_var_name_scl}(CLK := {clk_signal_formatted}); // Generates edge pulse" # La llamada en sí
+ # result_scl = f"{stat_var_name_scl}.Q" # La salida es el pin Q de la instancia
+
+ # Usando lógica explícita (más portable si no se declaran instancias):
+ result_scl = f"{clk_signal_formatted} AND NOT {mem_bit_scl_formatted}"
+ scl_comment = f"// P_TRIG Logic {instr_uid}: {result_scl}"
+ # La actualización del bit de memoria se hace aparte
+ instruction["scl"] = (
+ f"{mem_bit_scl_formatted} := {clk_signal_formatted}; // Update edge memory bit"
+ )
+
+ else: # Si no es P_TRIG (ej. N_TRIG o simplemente pasando el bit)
+ # Aquí asumimos que es N_TRIG si tiene TemplateValue "Negated" o similar
+ is_negated_pbox = (
+ instruction.get("template_values", {}).get("Negated") == "true"
+ )
+ if is_negated_pbox:
+ # Lógica N_TRIG explícita
+ clk_signal_formatted = rlo_scl # Asumimos que CLK se infiere igual
+ if clk_signal_formatted is None:
+ return False # Esperar CLK
+
+ if (
+ " " in clk_signal_formatted
+ or "AND" in clk_signal_formatted
+ or "OR" in clk_signal_formatted
+ ) and not (
+ clk_signal_formatted.startswith("(")
+ and clk_signal_formatted.endswith(")")
+ ):
+ clk_signal_formatted = f"({clk_signal_formatted})"
+
+ result_scl = f"NOT {clk_signal_formatted} AND {mem_bit_scl_formatted}"
+ scl_comment = f"// N_TRIG Logic {instr_uid}: {result_scl}"
+ instruction["scl"] = (
+ f"{mem_bit_scl_formatted} := {clk_signal_formatted}; // Update edge memory bit"
+ )
+ else:
+ # Comportamiento por defecto: pasar el bit de memoria (raro para PBox)
+ print(
+ f"Advertencia: PBox {instr_uid} no parece ser P_TRIG ni N_TRIG. Pasando bit de memoria."
+ )
+ result_scl = mem_bit_scl_formatted
+ scl_comment = f"// PBox {instr_uid} - Passing memory bit: {result_scl}"
+ instruction["scl"] = f"// {scl_comment}" # Solo comentario
+
+ # Actualizar el mapa SCL con el resultado booleano del flanco/paso
map_key_out = (network_id, instr_uid, "out")
scl_map[map_key_out] = result_scl
- instruction["scl"] = scl_comment
+
+ # ENO sigue al CLK (si existe) o es TRUE por defecto? Asumimos que sigue al CLK si es P/N_TRIG
+ map_key_eno = (network_id, instr_uid, "eno")
+ scl_map[map_key_eno] = rlo_scl if rlo_scl is not None else "TRUE"
+
instruction["type"] = instr_type + SCL_SUFFIX
return True
def process_o(instruction, network_id, scl_map, access_map):
- # (Sin cambios respecto a la versión funcional anterior)
instr_uid = instruction["instruction_uid"]
instr_type = instruction["type"]
if instr_type.endswith(SCL_SUFFIX) or "_error" in instr_type:
return False
- input_pins = [pin for pin in instruction["inputs"] if pin.startswith("in")]
+
+ # Buscar todas las entradas 'in', 'in1', 'in2', ...
+ input_pins = sorted([pin for pin in instruction["inputs"] if pin.startswith("in")])
+
if not input_pins:
- print(f"Error: O {instr_uid} sin pines inX")
- instruction["scl"] = f"// ERROR: O {instr_uid} sin pines in"
+ print(f"Error: O {instr_uid} sin pines de entrada (inX).")
+ instruction["scl"] = f"// ERROR: O {instr_uid} sin pines inX"
instruction["type"] += "_error"
- return True
+ return True # Procesado con error
+
scl_parts = []
all_resolved = True
- for pin in sorted(input_pins):
+ for pin in input_pins:
in_scl = get_scl_representation(
instruction["inputs"][pin], network_id, scl_map, access_map
)
if in_scl is None:
all_resolved = False
- break
- term = (
- f"({in_scl})"
- if (" " in in_scl or "AND" in in_scl)
- and not (in_scl.startswith("(") and in_scl.endswith(")"))
- else in_scl
- )
+ # print(f"DEBUG: O {instr_uid} esperando pin {pin}")
+ break # Salir del bucle for si una entrada no está lista
+
+ # Formatear término (añadir paréntesis si es necesario)
+ term = in_scl
+ if (" " in term or "AND" in term) and not (
+ term.startswith("(") and term.endswith(")")
+ ):
+ term = f"({term})"
scl_parts.append(term)
+
if not all_resolved:
- return False
- result_scl = (
- " OR ".join(scl_parts)
- if len(scl_parts) > 1
- else (scl_parts[0] if scl_parts else "FALSE")
- )
+ return False # Esperar a que todas las entradas estén resueltas
+
+ # Construir la expresión OR
+ result_scl = "FALSE" # Valor por defecto si no hay entradas válidas (raro)
+ if scl_parts:
+ result_scl = " OR ".join(scl_parts)
+ # Simplificar si solo hay un término
+ if len(scl_parts) == 1:
+ result_scl = scl_parts[0]
+ # Quitar paréntesis redundantes si solo hay un término y está entre paréntesis
+ if result_scl.startswith("(") and result_scl.endswith(")"):
+ # Comprobar si los paréntesis son necesarios (contienen operadores de menor precedencia)
+ # Simplificación: quitar siempre si solo hay un término. Podría ser incorrecto en casos complejos.
+ # result_scl = result_scl[1:-1] # Comentado por seguridad
+ pass
+
+ # Actualizar mapa SCL y la instrucción
map_key_out = (network_id, instr_uid, "out")
scl_map[map_key_out] = result_scl
- instruction["scl"] = f"// Logic O {instr_uid}: {result_scl}"
+ instruction["scl"] = (
+ f"// Logic O {instr_uid}: {result_scl}" # Comentario informativo
+ )
instruction["type"] = instr_type + SCL_SUFFIX
+
+ # La instrucción 'O' no tiene ENO propio, propaga el resultado por 'out'
return True
def process_call(instruction, network_id, scl_map, access_map):
- """Traduce una llamada a FC/FB a SCL."""
instr_uid = instruction["instruction_uid"]
- instr_type = instruction["type"] # Será 'Call'
- if instruction.get("type", "").endswith(SCL_SUFFIX) or "_error" in instruction.get(
- "type", ""
- ):
- return False # Usar get con default
+ instr_type = instruction.get("type", "") # Usar get con default
+ if instr_type.endswith(SCL_SUFFIX) or "_error" in instr_type:
+ return False
- block_name_scl = format_variable_name(
- instruction.get("block_name", "UnknownCall")
- ) # Limpiar nombre
- block_type = instruction.get("block_type")
- instance_db = instruction.get("instance_db") # Será None para FCs
+ block_name = instruction.get("block_name", f"UnknownCall_{instr_uid}")
+ block_type = instruction.get("block_type") # FC, FB
+ instance_db = instruction.get("instance_db") # Nombre del DB de instancia (para FB)
- # print(f"DEBUG: Intentando procesar CALL - UID: {instr_uid} Block: {block_name_scl}")
+ # Formatear nombres
+ block_name_scl = format_variable_name(block_name)
+ instance_db_scl = format_variable_name(instance_db) if instance_db else None
# --- Manejo de EN ---
en_input = instruction["inputs"].get("en")
@@ -613,63 +912,109 @@ def process_call(instruction, network_id, scl_map, access_map):
if en_input
else "TRUE"
)
-
if en_scl is None:
- # print(f"DEBUG: Dependencia EN no resuelta para CALL UID: {instr_uid}")
- return False
- # --- Fin Manejo de EN ---
+ return False # Dependencia EN no resuelta
+
+ # --- Procesar Parámetros de Entrada/Salida ---
+ # Necesitamos iterar sobre los pines definidos en la interfaz del bloque llamado.
+ # Esta información no está directamente en la instrucción 'Call' del JSON simplificado.
+ # ¡Limitación! Sin la interfaz del bloque llamado, solo podemos manejar EN/ENO
+ # y asumir una llamada sin parámetros o con parámetros conectados implícitamente.
+
+ # Solución temporal: Buscar conexiones en 'inputs' y 'outputs' que NO sean 'en'/'eno'
+ # y construir la llamada basándose en eso. Esto es muy heurístico.
+ scl_call_params = []
+ processed_inputs = {"en"} # Marcar 'en' como ya procesado
+ for pin_name, source_info in instruction.get("inputs", {}).items():
+ if pin_name not in processed_inputs:
+ param_scl = get_scl_representation(
+ source_info, network_id, scl_map, access_map
+ )
+ if param_scl is None:
+ # print(f"DEBUG: Call {instr_uid} esperando parámetro de entrada {pin_name}")
+ return False # Dependencia de parámetro no resuelta
+ # Formatear si es variable
+ param_scl_formatted = (
+ format_variable_name(param_scl)
+ if source_info.get("type") == "variable"
+ else param_scl
+ )
+ scl_call_params.append(
+ f"{format_variable_name(pin_name)} := {param_scl_formatted}"
+ )
+ processed_inputs.add(pin_name)
+
+ # Procesar parámetros de salida (asignaciones después de la llamada o pasados como VAR_IN_OUT/VAR_OUTPUT)
+ # Esto es aún más complejo. SCL normalmente asigna salidas después o usa punteros/referencias.
+ # Simplificación: Asumir que las salidas se manejan por asignación posterior si es necesario,
+ # o que son VAR_OUTPUT y se acceden como instancia.salida.
+ # Por ahora, no generamos asignaciones explícitas para las salidas aquí.
# --- Construcción de la Llamada SCL ---
- scl_call_params = []
- # TODO: Procesar otros parámetros de entrada/salida si existieran
- # para FC/FB con parámetros, se necesitaría iterar sobre instruction['inputs']
- # y instruction['outputs'] buscando conexiones a pines específicos de la llamada.
+ scl_call_body = ""
+ param_string = ", ".join(scl_call_params)
- scl_final_call = ""
- if block_type == "FB" and instance_db:
+ if block_type == "FB":
+ if not instance_db_scl:
+ print(
+ f"Error: Llamada a FB '{block_name_scl}' (UID {instr_uid}) sin DB de instancia especificado."
+ )
+ instruction["scl"] = f"// ERROR: FB Call {block_name_scl} sin instancia"
+ instruction["type"] = "Call_FB_error"
+ return True # Procesado con error
# Llamada a FB con DB de instancia
- scl_final_call = (
- f"{instance_db}();" # Simplificado, añadir parámetros si los hay
- )
+ scl_call_body = f"{instance_db_scl}({param_string});"
elif block_type == "FC":
# Llamada a FC
- scl_final_call = (
- f"{block_name_scl}();" # Simplificado, añadir parámetros si los hay
- )
+ scl_call_body = f"{block_name_scl}({param_string});"
else:
print(
f"Advertencia: Tipo de bloque no soportado para Call UID {instr_uid}: {block_type}"
)
- scl_final_call = f"// ERROR: Call a bloque no soportado: {block_name_scl}"
- instruction["type"] += "_error" # Marcar como error parcial
+ scl_call_body = f"// ERROR: Call a bloque tipo '{block_type}' no soportado: {block_name_scl}"
+ instruction["type"] = f"Call_{block_type}_error" # Marcar como error parcial
# --- Aplicar Condición EN ---
scl_final = ""
if en_scl != "TRUE":
# Indentar la llamada dentro del IF
- indented_call = "\n".join([f" {line}" for line in scl_final_call.splitlines()])
+ indented_call = "\n".join([f" {line}" for line in scl_call_body.splitlines()])
scl_final = f"IF {en_scl} THEN\n{indented_call}\nEND_IF;"
else:
- scl_final = scl_final_call
+ scl_final = scl_call_body
# --- Actualizar JSON y Mapa SCL ---
instruction["scl"] = scl_final
- # Cambiar el tipo para marcar como procesado
- instruction["type"] = f"Call_{block_type}_scl" # Ej: Call_FC_scl
+ instruction["type"] = (
+ f"Call_{block_type}_scl"
+ if "_error" not in instruction["type"]
+ else instruction["type"]
+ )
- # Actualizar scl_map con el estado ENO (igual a EN para llamadas simples)
+ # Actualizar scl_map con el estado ENO (igual a EN para llamadas simples sin manejo explícito de ENO)
map_key_eno = (network_id, instr_uid, "eno")
scl_map[map_key_eno] = en_scl
- # print(f"INFO: Call UID: {instr_uid} procesado. SCL: {scl_final.splitlines()[0]}...")
+ # Propagar valores de salida (si pudiéramos determinarlos)
+ # Ejemplo: Si supiéramos que hay una salida 'Out1' de tipo INT
+ # map_key_out1 = (network_id, instr_uid, "Out1")
+ # if block_type == "FB" and instance_db_scl:
+ # scl_map[map_key_out1] = f"{instance_db_scl}.Out1" # Acceso a salida de instancia
+ # else:
+ # # Para FCs, necesitaríamos una variable temporal o asignación explícita
+ # temp_out1 = generate_temp_var_name(network_id, instr_uid, "Out1")
+ # # Modificar scl_call_body para incluir la asignación: Out1 => temp_out1
+ # scl_map[map_key_out1] = temp_out1
+
return True
# --- NUEVO: Procesador de Agrupación (Refinado) ---
def process_group_ifs(instruction, network_id, scl_map, access_map):
"""
- Busca instrucciones que generan condiciones (Contact, O, Eq, PBox) ya procesadas
- y, si habilitan un grupo (>1) de bloques funcionales, construye el bloque IF agrupado.
+ Busca instrucciones que generan condiciones (Contact, O, Eq, PBox, etc.) ya procesadas
+ y, si habilitan un grupo (>1) de bloques funcionales (Move, Add, Call, etc.),
+ construye el bloque IF agrupado.
Modifica el campo 'scl' de la instrucción generadora de condición.
"""
instr_uid = instruction["instruction_uid"]
@@ -678,34 +1023,47 @@ def process_group_ifs(instruction, network_id, scl_map, access_map):
made_change = False
# Solo actuar sobre generadores de condición ya procesados (_scl)
- if not instr_type.endswith("_scl") or instr_type_original not in [
- "Contact",
- "O",
- "Eq",
- "Ne",
- "Gt",
- "Lt",
- "Ge",
- "Le",
- "PBox",
- ]:
+ # y que no sean ellos mismos errores o ya agrupados por otro IF
+ if (
+ not instr_type.endswith("_scl")
+ or "_error" in instr_type
+ or instruction.get("grouped", False)
+ or instr_type_original
+ not in [
+ "Contact",
+ "O",
+ "Eq",
+ "Ne",
+ "Gt",
+ "Lt",
+ "Ge",
+ "Le",
+ "PBox",
+ "And",
+ "Xor",
+ ]
+ ): # Añadir más si es necesario
return False
- # Evitar reagrupar si ya se hizo
- if instruction.get("scl", "").strip().startswith("IF"):
- # print(f"DEBUG Group: {instr_uid} ya tiene IF, saltando agrupación.")
+ # Evitar reagrupar si ya se hizo (comprobando si SCL ya es un IF complejo)
+ current_scl = instruction.get("scl", "")
+ if current_scl.strip().startswith("IF") and "END_IF;" in current_scl:
+ # print(f"DEBUG Group: {instr_uid} ya tiene IF complejo, saltando agrupación.")
+ return False
+ # Ignorar comentarios simples que empiezan por IF
+ if current_scl.strip().startswith("//") and "IF" in current_scl:
return False
- # Obtener la condición generada por esta instrucción (debería estar en scl_map)
+ # Obtener la condición generada por esta instrucción (debería estar en scl_map['out'])
map_key_out = (network_id, instr_uid, "out")
condition_scl = scl_map.get(map_key_out)
- # No agrupar para condiciones triviales o no encontradas
+ # No agrupar para condiciones triviales, no encontradas o ya agrupadas
if condition_scl is None or condition_scl in ["TRUE", "FALSE"]:
return False
# Encontrar todos los bloques funcionales habilitados DIRECTAMENTE por esta condición
- grouped_instructions_cores = [] # Lista de SCL 'core'
+ grouped_instructions_cores = [] # Lista de SCL 'core' de los consumidores
consumer_instr_list = [] # Lista de instrucciones consumidoras
network_logic = next(
(net["logic"] for net in data["networks"] if net["id"] == network_id), []
@@ -713,64 +1071,78 @@ def process_group_ifs(instruction, network_id, scl_map, access_map):
if not network_logic:
return False
+ # Identificar los tipos de instrucciones que queremos agrupar (bloques funcionales)
+ groupable_types = [
+ "Move",
+ "Add",
+ "Sub",
+ "Mul",
+ "Div",
+ "Mod",
+ "Convert",
+ "Call_FC",
+ "Call_FB",
+ ] # Añadir más si es necesario
+
for consumer_instr in network_logic:
consumer_uid = consumer_instr["instruction_uid"]
- # Saltar si ya está agrupado por otra condición
- if consumer_instr.get("grouped", False):
+ # Saltar si ya está agrupado por otra condición o es él mismo
+ if consumer_instr.get("grouped", False) or consumer_uid == instr_uid:
continue
consumer_en = consumer_instr.get("inputs", {}).get("en")
consumer_type = consumer_instr.get("type", "") # Tipo actual (_scl o no)
consumer_type_original = consumer_type.replace("_scl", "").replace("_error", "")
- # ¿Está conectado a nuestra salida 'out'?
+ # ¿Está la entrada 'en' del consumidor conectada a nuestra salida 'out'?
+ is_enabled_by_us = False
if (
isinstance(consumer_en, dict)
and consumer_en.get("type") == "connection"
and consumer_en.get("source_instruction_uid") == instr_uid
- and consumer_en.get("source_pin") == "out"
+ and consumer_en.get("source_pin")
+ == "out" # Condición viene de 'out' del generador
):
+ is_enabled_by_us = True
- # ¿Es un bloque funcional procesado?
- if consumer_type.endswith("_scl") and consumer_type_original in [
- "Move",
- "Add",
- "Sub",
- "Mul",
- "Div",
- "Mod",
- "Convert",
- ]:
+ # ¿Es un tipo de instrucción agrupable y ya procesado (tiene SCL)?
+ if (
+ is_enabled_by_us
+ and consumer_type.endswith("_scl")
+ and consumer_type_original in groupable_types
+ ):
+ consumer_scl = consumer_instr.get("scl", "")
+ # Extraer el SCL core (la parte DENTRO del IF o la línea única si no había IF)
+ core_scl = None
+ if consumer_scl.strip().startswith("IF"):
+ # Extraer todo entre THEN y END_IF;
+ match = re.search(
+ r"IF\s+.*\s+THEN\s*(.*?)\s*END_IF;",
+ consumer_scl,
+ re.DOTALL | re.IGNORECASE,
+ )
+ if match:
+ core_scl = match.group(1).strip()
+ elif consumer_scl and not consumer_scl.strip().startswith("//"):
+ # Si no es IF y no es solo comentario, es el core
+ core_scl = consumer_scl.strip()
- consumer_scl = consumer_instr.get("scl", "")
- # Extraer el SCL core (la parte DENTRO del IF o la línea única si no había IF)
- core_scl = None
- if consumer_scl.strip().startswith("IF"):
- match = re.search(r"THEN\s*(.+)\s*END_IF;", consumer_scl, re.DOTALL)
- if match:
- core_scl = match.group(1).strip()
- elif consumer_scl and not consumer_scl.strip().startswith(
- "//"
- ): # Si no es IF y no es solo comentario
- core_scl = consumer_scl.strip()
+ if core_scl:
+ grouped_instructions_cores.append(core_scl)
+ consumer_instr_list.append(consumer_instr) # Guardar referencia
+ # else: # Debug
+ # print(f"DEBUG Group: Consumidor {consumer_uid} ({consumer_type}) habilitado por {instr_uid} no tenía SCL core extraíble. SCL: '{consumer_scl}'")
- if core_scl:
- grouped_instructions_cores.append(core_scl)
- consumer_instr_list.append(
- consumer_instr
- ) # Guardar referencia a la instrucción
- # else: # Comentado para reducir ruido
- # print(f"DEBUG Group: Consumidor {consumer_uid} no tenía SCL core extraíble.")
-
- # Si encontramos más de un consumidor
+ # Si encontramos más de un consumidor agrupable
if len(grouped_instructions_cores) > 1:
print(
- f"INFO: Agrupando {len(grouped_instructions_cores)} instrucciones bajo condición de {instr_type_original} UID {instr_uid}"
+ f"INFO: Agrupando {len(grouped_instructions_cores)} instrucciones bajo condición de {instr_type_original} UID {instr_uid} (Cond: {condition_scl})"
)
+ # Construir el bloque IF agrupado
scl_grouped = [f"IF {condition_scl} THEN"]
for core_line in grouped_instructions_cores:
- # Añadir indentación adecuada si el core tiene múltiples líneas
+ # Añadir indentación adecuada (2 espacios)
indented_core = "\n".join(
[f" {line.strip()}" for line in core_line.splitlines()]
)
@@ -778,20 +1150,24 @@ def process_group_ifs(instruction, network_id, scl_map, access_map):
scl_grouped.append("END_IF;")
final_grouped_scl = "\n".join(scl_grouped)
- # Sobrescribir 'scl' de la instrucción generadora
+ # Sobrescribir 'scl' de la instrucción generadora de condición
instruction["scl"] = final_grouped_scl
- # Marcar los consumidores
+ # Marcar los consumidores como agrupados y limpiar su SCL original
for consumer_instr in consumer_instr_list:
consumer_instr["scl"] = f"{GROUPED_COMMENT} (by UID {instr_uid})"
- consumer_instr["grouped"] = True
+ consumer_instr["grouped"] = True # Marcar como agrupado
made_change = True
+ # else: # Debug
+ # if len(grouped_instructions_cores) == 1:
+ # print(f"DEBUG Group: Solo 1 consumidor ({consumer_instr_list[0]['instruction_uid']}) para {instr_uid}. No se agrupa.")
+ # elif len(grouped_instructions_cores) == 0 and condition_scl not in ['TRUE', 'FALSE']:
+ # # Solo mostrar si la condición no era trivial
+ # pass # print(f"DEBUG Group: Ningún consumidor agrupable encontrado para {instr_uid} (Cond: {condition_scl}).")
return made_change
# --- Bucle Principal de Procesamiento ---
-
-
def process_json_to_scl(json_filepath):
"""Lee el JSON, aplica los procesadores iterativamente y guarda el resultado."""
if not os.path.exists(json_filepath):
@@ -800,18 +1176,23 @@ def process_json_to_scl(json_filepath):
print(f"Cargando JSON desde: {json_filepath}")
try:
with open(json_filepath, "r", encoding="utf-8") as f:
- global data
+ global data # Modificar la variable global
data = json.load(f)
except Exception as e:
print(f"Error al cargar JSON: {e}")
+ traceback.print_exc()
return
+ # Crear mapas de acceso por red (para resolver UIDs de variables/constantes rápidamente)
network_access_maps = {}
# print("Creando mapas de acceso por red...") # Comentado para brevedad
for network in data.get("networks", []):
net_id = network["id"]
current_access_map = {}
+ # Extraer todos los 'Access' (variables/constantes) usados en esta red
+ # Esta información ya está dentro de inputs/outputs en el JSON simplificado
for instr in network.get("logic", []):
+ # Revisar Inputs
for _, source in instr.get("inputs", {}).items():
sources_to_check = (
source
@@ -822,25 +1203,33 @@ def process_json_to_scl(json_filepath):
if (
isinstance(src, dict)
and src.get("uid")
- and src.get("scope")
and src.get("type") in ["variable", "constant"]
):
- current_access_map[src["uid"]] = src
+ current_access_map[src["uid"]] = (
+ src # Guardar info del Access por UID
+ )
+ # Revisar Outputs
for _, dest_list in instr.get("outputs", {}).items():
if isinstance(dest_list, list):
for dest in dest_list:
if (
isinstance(dest, dict)
and dest.get("uid")
- and dest.get("scope")
and dest.get("type") in ["variable", "constant"]
):
- current_access_map[dest["uid"]] = dest
+ current_access_map[dest["uid"]] = (
+ dest # Guardar info del Access por UID
+ )
network_access_maps[net_id] = current_access_map
+ # Mapa global para almacenar el SCL generado para cada salida de instrucción (pin)
+ # Clave: (network_id, instruction_uid, pin_name) -> Valor: SCL string
scl_map = {}
- max_passes = 25
+
+ # --- Bucle Iterativo ---
+ max_passes = 30 # Aumentar por si hay dependencias largas o agrupaciones complejas
passes = 0
+ processing_complete = False
# Lista y mapa de procesadores base
base_processors = [
@@ -854,37 +1243,73 @@ def process_json_to_scl(json_filepath):
process_move,
process_call,
process_coil,
+ # Añadir aquí nuevos procesadores base para otros tipos de instrucciones
]
- processor_map = {
- func.__name__.split("_")[1].lower(): func for func in base_processors
- }
+ # Crear mapa por nombre de tipo original (en minúsculas)
+ processor_map = {}
+ for func in base_processors:
+ # Extraer tipo del nombre de la función (p.ej., 'process_contact' -> 'contact')
+ match = re.match(r"process_(\w+)", func.__name__)
+ if match:
+ type_name = match.group(1).lower()
+ # Manejar casos especiales como 'call' que puede ser FC o FB
+ if type_name == "call":
+ processor_map["call_fc"] = func
+ processor_map["call_fb"] = func
+ processor_map["call"] = func # Genérico por si acaso
+ else:
+ processor_map[type_name] = func
print("\n--- Iniciando Bucle de Procesamiento Iterativo ---")
- while passes < max_passes:
+ while passes < max_passes and not processing_complete:
passes += 1
made_change_in_base_pass = False
made_change_in_group_pass = False
print(f"\n--- Pase {passes} ---")
+ num_processed_this_pass = 0
+ num_grouped_this_pass = 0
# --- FASE 1: Procesadores Base ---
- # print(f"DEBUG: Iniciando Fase 1 (Procesadores Base) - Pase {passes}") # Debug
for network in data.get("networks", []):
network_id = network["id"]
access_map = network_access_maps.get(network_id, {})
- network_logic = network.get("logic", [])
- for instruction in network_logic:
- instr_type_original = instruction["type"]
+ network_logic = network.get(
+ "logic", []
+ ) # Obtener referencia a la lista de lógica
+
+ # Crear una copia de la lista de instrucciones para iterar,
+ # ya que modificaremos la original (al añadir _scl al tipo)
+ # logic_to_process = list(network_logic) # No necesario si solo modificamos in-place
+
+ for instruction in network_logic: # Iterar sobre la lista original
+ instr_uid = instruction.get("instruction_uid")
+ instr_type_original = instruction.get("type", "Unknown")
+
+ # Saltar si ya procesado, es un error, o está agrupado
if (
instr_type_original.endswith(SCL_SUFFIX)
or "_error" in instr_type_original
or instruction.get("grouped", False)
):
continue
- instr_type_lower_lookup = instr_type_original.lower()
- func_to_call = processor_map.get(instr_type_lower_lookup)
+
+ # Buscar el procesador adecuado
+ # Para 'Call', necesitamos distinguir FC/FB si es posible
+ lookup_key = instr_type_original.lower()
+ if instr_type_original == "Call":
+ block_type = instruction.get("block_type", "").upper()
+ if block_type == "FC":
+ lookup_key = "call_fc"
+ elif block_type == "FB":
+ lookup_key = "call_fb"
+ # else: se usará 'call' genérico si existe
+
+ func_to_call = processor_map.get(lookup_key)
+
if func_to_call:
try:
changed = False
+ # Pasar la lista de lógica completa solo si es necesario (PBox)
if func_to_call == process_pbox:
changed = func_to_call(
instruction,
@@ -897,65 +1322,140 @@ def process_json_to_scl(json_filepath):
changed = func_to_call(
instruction, network_id, scl_map, access_map
)
+
if changed:
made_change_in_base_pass = True
+ num_processed_this_pass += 1
+ # print(f"DEBUG: Procesado {instr_type_original} UID {instr_uid}") # Debug detallado
except Exception as e:
print(
- f"ERROR(Base) {func_to_call.__name__} UID {instruction.get('instruction_uid')}: {e}"
+ f"ERROR(Base) al procesar {instr_type_original} UID {instr_uid} con {func_to_call.__name__}: {e}"
)
traceback.print_exc()
- instruction["scl"] = f"// ERROR base: {e}"
- instruction["type"] += "_error"
- made_change_in_base_pass = True
+ # Marcar como error para no reintentar
+ instruction["scl"] = f"// ERROR en procesador base: {e}"
+ instruction["type"] = instr_type_original + "_error"
+ made_change_in_base_pass = True # Considerar error como cambio para evitar bucles infinitos
+ # else: # Debug para tipos no encontrados
+ # if lookup_key not in ['unknown', 'unknown_structure', 'error_parsing_symbol', 'error_parsing_constant', 'error_no_name']:
+ # print(f"DEBUG: No se encontró procesador base para el tipo '{instr_type_original}' (lookup: '{lookup_key}') UID {instr_uid}")
+ # pass
# --- FASE 2: Procesador de Agrupación ---
- # print(f"DEBUG: Iniciando Fase 2 (Agrupación IF) - Pase {passes}") # Debug
- for network in data.get("networks", []):
- network_id = network["id"]
- access_map = network_access_maps.get(network_id, {})
- network_logic = network.get("logic", [])
- for instruction in network_logic:
- if instruction["type"].endswith("_scl") and not instruction.get(
- "grouped", False
- ): # Solo en generadores procesados y no agrupados
- try:
- group_changed = process_group_ifs(
- instruction, network_id, scl_map, access_map
- )
- if group_changed:
- made_change_in_group_pass = True
- except Exception as e:
- print(
- f"ERROR(Group) process_group_ifs UID {instruction.get('instruction_uid')}: {e}"
- )
- traceback.print_exc()
+ # Ejecutar solo si hubo cambios en la fase base (o en el primer pase) para optimizar
+ if made_change_in_base_pass or passes == 1:
+ # print(f"DEBUG: Iniciando Fase 2 (Agrupación IF) - Pase {passes}") # Debug
+ for network in data.get("networks", []):
+ network_id = network["id"]
+ access_map = network_access_maps.get(network_id, {})
+ network_logic = network.get("logic", [])
+ # Iterar sobre generadores de condición ya procesados
+ for instruction in network_logic:
+ # Solo intentar agrupar si es un generador de condición procesado y no agrupado
+ if instruction["type"].endswith("_scl") and not instruction.get(
+ "grouped", False
+ ):
+ try:
+ group_changed = process_group_ifs(
+ instruction, network_id, scl_map, access_map
+ )
+ if group_changed:
+ made_change_in_group_pass = True
+ num_grouped_this_pass += 1
+ except Exception as e:
+ print(
+ f"ERROR(Group) al intentar agrupar desde UID {instruction.get('instruction_uid')}: {e}"
+ )
+ traceback.print_exc()
+ # No marcar la instrucción generadora como error, solo falló la agrupación
- # Decidir si continuar
+ # --- Comprobar si se completó el procesamiento ---
if not made_change_in_base_pass and not made_change_in_group_pass:
print(
- f"\n--- No se hicieron cambios en el pase {passes}. Proceso completado. ---"
+ f"\n--- No se hicieron más cambios en el pase {passes}. Proceso iterativo completado. ---"
+ )
+ processing_complete = True
+ else:
+ print(
+ f"--- Fin Pase {passes}: {num_processed_this_pass} procesados, {num_grouped_this_pass} agrupados. Continuando..."
)
- break
- # else: print(f"DEBUG: Cambios Pase {passes}: Base={made_change_in_base_pass}, Grupo={made_change_in_group_pass}. Continuando...") # Debug
- if passes == max_passes:
- print(f"\n--- Límite de {max_passes} pases alcanzado. ---")
+ if passes == max_passes and not processing_complete:
+ print(
+ f"\n--- ADVERTENCIA: Límite de {max_passes} pases alcanzado. Puede haber dependencias no resueltas. ---"
+ )
+
+ # --- FIN BUCLE ITERATIVO ---
+
+ # --- NUEVO: Verificación de Instrucciones No Procesadas ---
+ print("\n--- Verificación Final de Instrucciones No Procesadas ---")
+ unprocessed_count = 0
+ unprocessed_details = [] # Lista para guardar detalles
+
+ for network in data.get("networks", []):
+ network_id = network.get("id", "Unknown ID")
+ network_title = network.get("title", f"Network {network_id}")
+ for instruction in network.get("logic", []):
+ instr_uid = instruction.get("instruction_uid", "Unknown UID")
+ instr_type = instruction.get("type", "Unknown Type")
+ is_grouped = instruction.get("grouped", False)
+
+ # Comprobar si NO está procesada (sin _scl), NO es error, y NO está agrupada
+ if (
+ not instr_type.endswith(SCL_SUFFIX)
+ and "_error" not in instr_type
+ and not is_grouped
+ ):
+ unprocessed_count += 1
+ # Añadir detalle formateado a la lista
+ unprocessed_details.append(
+ f" - Red '{network_title}' (ID: {network_id}), "
+ f"Instrucción UID: {instr_uid}, Tipo Original: '{instr_type}'"
+ )
+
+ # Imprimir el resumen de no procesadas
+ if unprocessed_count > 0:
+ print(
+ f"ADVERTENCIA: Se encontraron {unprocessed_count} instrucciones que no pudieron ser procesadas a SCL:"
+ )
+ # Imprimir cada detalle de la lista
+ for detail in unprocessed_details:
+ print(detail)
+ print(
+ ">>> Estos tipos de instrucción podrían necesitar un procesador específico en 'x2_process.py'."
+ )
+ else:
+ print(
+ "INFO: Todas las instrucciones fueron procesadas a SCL, marcadas como error o agrupadas exitosamente."
+ )
+ # --- FIN Verificación ---
# --- Guardar JSON Final ---
- output_filename = json_filepath.replace(".json", "_processed.json")
+ output_filename = json_filepath.replace(
+ "_simplified.json", "_simplified_processed.json"
+ )
print(f"\nGuardando JSON procesado en: {output_filename}")
try:
with open(output_filename, "w", encoding="utf-8") as f:
json.dump(data, f, indent=4, ensure_ascii=False)
print("Guardado completado.")
except Exception as e:
- print(f"Error al guardar JSON: {e}")
+ print(f"Error Crítico al guardar JSON procesado: {e}")
+ traceback.print_exc()
# --- Ejecución ---
if __name__ == "__main__":
- xml_file = "BlenderCtrl__Main.xml" # CAMBIAR AL NUEVO ARCHIVO XML
- input_json_file = xml_file.replace(
- ".xml", "_simplified.json"
- ) # Nombre de salida dinámico
- process_json_to_scl(input_json_file)
+ # Asegúrate de que el nombre base del archivo XML sea correcto
+ xml_filename_base = "BlenderCtrl__Main" # Cambia esto si tu XML se llama diferente
+ input_json_file = f"{xml_filename_base}_simplified.json"
+
+ if not os.path.exists(input_json_file):
+ print(
+ f"Error Fatal: El archivo de entrada JSON simplificado no existe: '{input_json_file}'"
+ )
+ print(
+ "Asegúrate de haber ejecutado 'x1_to_json.py' primero sobre el archivo XML correcto."
+ )
+ else:
+ process_json_to_scl(input_json_file)