From a35f891eb7523aa534835e66159dae51f6fc2385 Mon Sep 17 00:00:00 2001 From: Miguel Date: Fri, 18 Apr 2025 17:21:26 +0200 Subject: [PATCH] Version funcionando --- BlenderCtrl_ProdModeInit.xml | 477 ++++++++++++++ BlenderRun_ProdTime.scl | 48 +- ...Run_ProdTime_simplified_scl_processed.json | 72 +- x2_process.py | 618 ++++++++---------- 4 files changed, 826 insertions(+), 389 deletions(-) create mode 100644 BlenderCtrl_ProdModeInit.xml diff --git a/BlenderCtrl_ProdModeInit.xml b/BlenderCtrl_ProdModeInit.xml new file mode 100644 index 0000000..2485d76 --- /dev/null +++ b/BlenderCtrl_ProdModeInit.xml @@ -0,0 +1,477 @@ + + + + + + false + TASK2 + +
+
+
+
+
+
+ +
+ + Standard + BlenderCtrl_ProdModeInit + + 2012 + 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 + PID Reset Integral + + + + + 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 + Ctrl Init Errors + + + + + de-DE + + + + + + en-US + + + + + + es-ES + + + + + + fr-FR + + + + + + zh-CN + + + + + + ja-JP + + + + + + + + + + + + + + Real + 0.0 + + + + + + + + + + + 1 + + + + + + + + + + + + + + + + + + LAD + + + + + + + it-IT + + + + + + de-DE + + + + + + en-US + + + + + + es-ES + + + + + + fr-FR + + + + + + zh-CN + + + + + + ja-JP + + + + + + + + + + it-IT + RunOut Counter + + + + + de-DE + + + + + + en-US + + + + + + es-ES + + + + + + fr-FR + + + + + + zh-CN + + + + + + ja-JP + + + + + + + + + + + + it-IT + Prode Mode Init + + + + + de-DE + + + + + + en-US + + + + + + es-ES + + + + + + fr-FR + + + + + + zh-CN + + + + + + ja-JP + + + + + + + + \ No newline at end of file diff --git a/BlenderRun_ProdTime.scl b/BlenderRun_ProdTime.scl index 2f933ed..518002a 100644 --- a/BlenderRun_ProdTime.scl +++ b/BlenderRun_ProdTime.scl @@ -30,49 +30,74 @@ BEGIN // Network 1: Seconds + // RLO: "Procedure_Variables"."Blender_Run"."Running" + // RLO: "Procedure_Variables"."Blender_Run"."Running" AND "CLK_1.0S" 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 + // RLO: "SLIM_Variables"."ResetHour" IF "SLIM_Variables"."ResetHour" THEN "Blender_Variables_Pers"."gSLIM_Sec" := 0; END_IF; // Network 3: Seconds Counter + // RLO: "gBlenderBlending" + // RLO: "gBlenderBlending" AND "CLK_1.0S" IF "gBlenderBlending" AND "CLK_1.0S" THEN "Blender_Variables_Pers"."gProdSec" := "Blender_Variables_Pers"."gProdSec" + 1; END_IF; // Network 4: Minute + // Cond: "Blender_Variables_Pers"."gProdSec" = 60 "m1MinONS" := "Blender_Variables_Pers"."gProdSec" = 60; // Network 5: Minute Counter - "Blender_Variables_Pers"."gProdSec" := 0; - "Blender_Variables_Pers"."gProdMin" := "Blender_Variables_Pers"."gProdMin" + 1; + 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 + // Cond: "Blender_Variables_Pers"."gProdMin" = 60 "m1HourONS" := "Blender_Variables_Pers"."gProdMin" = 60; // Network 7: Hour Counter - "Blender_Variables_Pers"."gProdMin" := 0; - "Blender_Variables_Pers"."gProdHour" := "Blender_Variables_Pers"."gProdHour" + 1; - "Blender_Variables_Pers"."gBlendingMaintHour" := "Blender_Variables_Pers"."gBlendingMaintHour" + 1; + 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 - "Blender_Variables_Pers"."gProdSec" := 0; - "Blender_Variables_Pers"."gProdMin" := 0; - "Blender_Variables_Pers"."gProdHour" := 0; + // RLO: "gBlenderCIPMode" + // RLO: "gBlenderRinseMode" + 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 + // RLO: "Procedure_Variables"."Blender_Run"."Running" + // RLO: "Procedure_Variables"."Blender_Run"."Running" AND "CLK_1.0S" IF "Procedure_Variables"."Blender_Run"."Running" AND "CLK_1.0S" THEN "Blender_Variables_Pers"."gRunningSeconds" := "Blender_Variables_Pers"."gRunningSeconds" + 1; END_IF; @@ -81,20 +106,25 @@ BEGIN "I_DIRunning_sec" := "Blender_Variables_Pers"."gRunningSeconds"; "MOD60" := "I_DIRunning_sec" MOD DINT#60; + // Cond: "MOD60" = DINT#0 + // RLO: "MOD60" = DINT#0 AND "Procedure_Variables"."Blender_Run"."Running" + // RLO: ("MOD60" = DINT#0 AND "Procedure_Variables"."Blender_Run"."Running") AND "CLK_1.0S" IF ("MOD60" = DINT#0 AND "Procedure_Variables"."Blender_Run"."Running") AND "CLK_1.0S" THEN "Blender_Variables_Pers"."gRunningMinutes" := "Blender_Variables_Pers"."gRunningMinutes" + 1; END_IF; - // Edge detection PBox 41 -> P_TRIG_FUNC(CLK := (("MOD60" = DINT#0 AND "Procedure_Variables"."Blender_Run"."Running") AND "CLK_1.0S"), M := "M19012") (CLK inferred) + // Edge PBox 41 -> P_TRIG_FUNC(CLK := (("MOD60" = DINT#0 AND "Procedure_Variables"."Blender_Run"."Running") AND "CLK_1.0S"), M := "M19012") "mRunMin" := P_TRIG_FUNC(CLK := (("MOD60" = DINT#0 AND "Procedure_Variables"."Blender_Run"."Running") AND "CLK_1.0S"), M := "M19012"); // Network 11: Running Hours for Maintenance + // RLO: "mRunMin" IF "mRunMin" THEN "I_DIRunning_min" := "Blender_Variables_Pers"."gRunningMinutes"; END_IF; IF "mRunMin" THEN "MOD60" := "I_DIRunning_min" MOD DINT#60; END_IF; + // Cond: "MOD60" = DINT#0 IF "MOD60" = DINT#0 THEN "Blender_Variables_Pers"."gRunningMaintHour" := "Blender_Variables_Pers"."gRunningMaintHour" + 1; END_IF; diff --git a/BlenderRun_ProdTime_simplified_scl_processed.json b/BlenderRun_ProdTime_simplified_scl_processed.json index 9b202c4..e1f3930 100644 --- a/BlenderRun_ProdTime_simplified_scl_processed.json +++ b/BlenderRun_ProdTime_simplified_scl_processed.json @@ -66,7 +66,7 @@ } }, "outputs": {}, - "scl": "// RLO updated by Contact 26: \"Procedure_Variables\".\"Blender_Run\".\"Running\"" + "scl": "// RLO: \"Procedure_Variables\".\"Blender_Run\".\"Running\"" }, { "instruction_uid": "27", @@ -86,7 +86,7 @@ } }, "outputs": {}, - "scl": "// RLO updated by Contact 27: \"Procedure_Variables\".\"Blender_Run\".\"Running\" AND \"CLK_1.0S\"" + "scl": "// RLO: \"Procedure_Variables\".\"Blender_Run\".\"Running\" AND \"CLK_1.0S\"" }, { "instruction_uid": "28", @@ -146,7 +146,7 @@ } }, "outputs": {}, - "scl": "// RLO updated by Contact 24: \"SLIM_Variables\".\"ResetHour\"" + "scl": "// RLO: \"SLIM_Variables\".\"ResetHour\"" }, { "instruction_uid": "25", @@ -200,7 +200,7 @@ } }, "outputs": {}, - "scl": "// RLO updated by Contact 26: \"gBlenderBlending\"" + "scl": "// RLO: \"gBlenderBlending\"" }, { "instruction_uid": "27", @@ -220,7 +220,7 @@ } }, "outputs": {}, - "scl": "// RLO updated by Contact 27: \"gBlenderBlending\" AND \"CLK_1.0S\"" + "scl": "// RLO: \"gBlenderBlending\" AND \"CLK_1.0S\"" }, { "instruction_uid": "28", @@ -287,7 +287,7 @@ } }, "outputs": {}, - "scl": "// Comparison Eq 24: \"Blender_Variables_Pers\".\"gProdSec\" = 60" + "scl": "// Cond: \"Blender_Variables_Pers\".\"gProdSec\" = 60" }, { "instruction_uid": "25", @@ -331,7 +331,7 @@ } }, "outputs": {}, - "scl": "// RLO updated by Contact 27: \"m1MinONS\"" + "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", @@ -361,8 +361,8 @@ } ] }, - "grouped": true, - "scl": "\"Blender_Variables_Pers\".\"gProdSec\" := 0;" + "scl": "// Logic included in grouped IF (by UID 27)", + "grouped": true }, { "instruction_uid": "29", @@ -398,8 +398,8 @@ } ] }, - "grouped": true, - "scl": "\"Blender_Variables_Pers\".\"gProdMin\" := \"Blender_Variables_Pers\".\"gProdMin\" + 1;" + "scl": "// Logic included in grouped IF (by UID 27)", + "grouped": true } ] }, @@ -430,7 +430,7 @@ } }, "outputs": {}, - "scl": "// Comparison Eq 24: \"Blender_Variables_Pers\".\"gProdMin\" = 60" + "scl": "// Cond: \"Blender_Variables_Pers\".\"gProdMin\" = 60" }, { "instruction_uid": "25", @@ -474,7 +474,7 @@ } }, "outputs": {}, - "scl": "// RLO updated by Contact 30: \"m1HourONS\"" + "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", @@ -504,8 +504,8 @@ } ] }, - "grouped": true, - "scl": "\"Blender_Variables_Pers\".\"gProdMin\" := 0;" + "scl": "// Logic included in grouped IF (by UID 30)", + "grouped": true }, { "instruction_uid": "32", @@ -541,8 +541,8 @@ } ] }, - "grouped": true, - "scl": "\"Blender_Variables_Pers\".\"gProdHour\" := \"Blender_Variables_Pers\".\"gProdHour\" + 1;" + "scl": "// Logic included in grouped IF (by UID 30)", + "grouped": true }, { "instruction_uid": "33", @@ -578,8 +578,8 @@ } ] }, - "grouped": true, - "scl": "\"Blender_Variables_Pers\".\"gBlendingMaintHour\" := \"Blender_Variables_Pers\".\"gBlendingMaintHour\" + 1;" + "scl": "// Logic included in grouped IF (by UID 30)", + "grouped": true } ] }, @@ -603,7 +603,7 @@ } }, "outputs": {}, - "scl": "// RLO updated by Contact 29: \"gBlenderCIPMode\"" + "scl": "// RLO: \"gBlenderCIPMode\"" }, { "instruction_uid": "30", @@ -617,7 +617,7 @@ } }, "outputs": {}, - "scl": "// RLO updated by Contact 30: \"gBlenderRinseMode\"" + "scl": "// RLO: \"gBlenderRinseMode\"" }, { "instruction_uid": "31", @@ -637,7 +637,7 @@ } }, "outputs": {}, - "scl": "// Logic O 31: \"gBlenderCIPMode\" OR \"gBlenderRinseMode\"" + "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", @@ -667,8 +667,8 @@ } ] }, - "grouped": true, - "scl": "\"Blender_Variables_Pers\".\"gProdSec\" := 0;" + "scl": "// Logic included in grouped IF (by UID 31)", + "grouped": true }, { "instruction_uid": "33", @@ -698,8 +698,8 @@ } ] }, - "grouped": true, - "scl": "\"Blender_Variables_Pers\".\"gProdMin\" := 0;" + "scl": "// Logic included in grouped IF (by UID 31)", + "grouped": true }, { "instruction_uid": "34", @@ -729,8 +729,8 @@ } ] }, - "grouped": true, - "scl": "\"Blender_Variables_Pers\".\"gProdHour\" := 0;" + "scl": "// Logic included in grouped IF (by UID 31)", + "grouped": true } ] }, @@ -754,7 +754,7 @@ } }, "outputs": {}, - "scl": "// RLO updated by Contact 26: \"Procedure_Variables\".\"Blender_Run\".\"Running\"" + "scl": "// RLO: \"Procedure_Variables\".\"Blender_Run\".\"Running\"" }, { "instruction_uid": "27", @@ -774,7 +774,7 @@ } }, "outputs": {}, - "scl": "// RLO updated by Contact 27: \"Procedure_Variables\".\"Blender_Run\".\"Running\" AND \"CLK_1.0S\"" + "scl": "// RLO: \"Procedure_Variables\".\"Blender_Run\".\"Running\" AND \"CLK_1.0S\"" }, { "instruction_uid": "28", @@ -914,7 +914,7 @@ } }, "outputs": {}, - "scl": "// Comparison Eq 37: \"MOD60\" = DINT#0" + "scl": "// Cond: \"MOD60\" = DINT#0" }, { "instruction_uid": "38", @@ -934,7 +934,7 @@ } }, "outputs": {}, - "scl": "// RLO updated by Contact 38: \"MOD60\" = DINT#0 AND \"Procedure_Variables\".\"Blender_Run\".\"Running\"" + "scl": "// RLO: \"MOD60\" = DINT#0 AND \"Procedure_Variables\".\"Blender_Run\".\"Running\"" }, { "instruction_uid": "39", @@ -954,7 +954,7 @@ } }, "outputs": {}, - "scl": "// RLO updated by Contact 39: (\"MOD60\" = DINT#0 AND \"Procedure_Variables\".\"Blender_Run\".\"Running\") AND \"CLK_1.0S\"" + "scl": "// RLO: (\"MOD60\" = DINT#0 AND \"Procedure_Variables\".\"Blender_Run\".\"Running\") AND \"CLK_1.0S\"" }, { "instruction_uid": "40", @@ -1004,7 +1004,7 @@ } }, "outputs": {}, - "scl": "// Edge detection PBox 41 -> P_TRIG_FUNC(CLK := ((\"MOD60\" = DINT#0 AND \"Procedure_Variables\".\"Blender_Run\".\"Running\") AND \"CLK_1.0S\"), M := \"M19012\") (CLK inferred)" + "scl": "// Edge PBox 41 -> P_TRIG_FUNC(CLK := ((\"MOD60\" = DINT#0 AND \"Procedure_Variables\".\"Blender_Run\".\"Running\") AND \"CLK_1.0S\"), M := \"M19012\")" }, { "instruction_uid": "42", @@ -1048,7 +1048,7 @@ } }, "outputs": {}, - "scl": "// RLO updated by Contact 32: \"mRunMin\"" + "scl": "// RLO: \"mRunMin\"" }, { "instruction_uid": "33", @@ -1148,7 +1148,7 @@ } }, "outputs": {}, - "scl": "// Comparison Eq 35: \"MOD60\" = DINT#0" + "scl": "// Cond: \"MOD60\" = DINT#0" }, { "instruction_uid": "36", diff --git a/x2_process.py b/x2_process.py index 429e7b0..01edaa9 100644 --- a/x2_process.py +++ b/x2_process.py @@ -94,7 +94,7 @@ def get_scl_representation(source_info, network_id, scl_map, access_map): ) return f"_ERR_UNKNOWN_SRC_{source_info.get('uid')}_" else: - print(f"Advertencia: Tipo de fuente desconocido o inválido: {source_info}") + print(f"Advertencia: Tipo de fuente desconocido: {source_info}") return f"_ERR_INVALID_SRC_TYPE_" @@ -120,7 +120,7 @@ def get_target_scl_name(instruction, output_pin_name, network_id, default_to_tem target_scl = dest_access.get("name") if not target_scl: print( - f"Error: Variable destino para {instr_uid}.{output_pin_name} sin nombre (UID: {dest_access.get('uid')}). {'Usando temp.' if default_to_temp else 'Ignorando.'}" + f"Error: Var destino {instr_uid}.{output_pin_name} sin nombre (UID: {dest_access.get('uid')}). {'Usando temp.' if default_to_temp else 'Ignorando.'}" ) target_scl = ( generate_temp_var_name(network_id, instr_uid, output_pin_name) @@ -129,7 +129,7 @@ def get_target_scl_name(instruction, output_pin_name, network_id, default_to_tem ) elif dest_access.get("type") == "constant": print( - f"Advertencia: Instr {instr_uid} intenta escribir en constante UID {dest_access.get('uid')}. {'Usando temp.' if default_to_temp else 'Ignorando.'}" + f"Advertencia: Instr {instr_uid} escribe en const UID {dest_access.get('uid')}. {'Usando temp.' if default_to_temp else 'Ignorando.'}" ) target_scl = ( generate_temp_var_name(network_id, instr_uid, output_pin_name) @@ -138,7 +138,7 @@ def get_target_scl_name(instruction, output_pin_name, network_id, default_to_tem ) else: print( - f"Advertencia: Destino de {instr_uid}.{output_pin_name} no es var/const: {dest_access.get('type')}. {'Usando temp.' if default_to_temp else 'Ignorando.'}" + f"Advertencia: Destino {instr_uid}.{output_pin_name} no es var/const: {dest_access.get('type')}. {'Usando temp.' if default_to_temp else 'Ignorando.'}" ) target_scl = ( generate_temp_var_name(network_id, instr_uid, output_pin_name) @@ -150,262 +150,16 @@ def get_target_scl_name(instruction, output_pin_name, network_id, default_to_tem return target_scl -# --- Procesadores de Instrucciones (MODIFICADOS para Agrupación) --- +# --- Procesadores de Instrucciones (SIMPLIFICADOS - Siempre generan IF si EN no es TRUE) --- -def check_if_grouped(instruction, network_id): - """Verifica si la entrada EN de esta instrucción viene de una fuente - que alimenta a más de un bloque funcional en la misma red.""" - en_input = instruction.get("inputs", {}).get("en") - if not isinstance(en_input, dict) or en_input.get("type") != "connection": - return False, None # No está conectado a otra instrucción o no tiene EN - - source_uid = en_input.get("source_instruction_uid") - source_pin = en_input.get("source_pin") - if not source_uid or not source_pin: - return False, None # Información de fuente inválida - - consumer_count = 0 - network_logic = next( - (net["logic"] for net in data.get("networks", []) if net["id"] == network_id), - [], - ) - - for instr in network_logic: - other_en = instr.get("inputs", {}).get("en") - if ( - isinstance(other_en, dict) - and other_en.get("type") == "connection" - and other_en.get("source_instruction_uid") == source_uid - and other_en.get("source_pin") == source_pin - ): - # Contar solo bloques funcionales como consumidores - instr_type_orig = ( - instr.get("type", "").replace(SCL_SUFFIX, "").replace("_error", "") - ) - if instr_type_orig in [ - "Move", - "Add", - "Sub", - "Mul", - "Div", - "Mod", - "Convert", - ]: # Ampliar si es necesario - consumer_count += 1 - - is_grouped = consumer_count > 1 - # print(f"DEBUG: Check group for {instruction['instruction_uid']}: source={source_uid}.{source_pin}, consumers={consumer_count}, is_grouped={is_grouped}") - return is_grouped, (source_uid, source_pin) - - -def process_move(instruction, network_id, scl_map, access_map): - instr_uid = instruction["instruction_uid"] - instr_type = instruction["type"] - if instr_type.endswith(SCL_SUFFIX) or "_error" in instr_type: - return False - - en_input = instruction["inputs"].get("en") - en_scl = ( - "TRUE" - if en_input is None - else get_scl_representation(en_input, network_id, scl_map, access_map) - ) - in_scl = get_scl_representation( - instruction["inputs"].get("in"), network_id, scl_map, access_map - ) - - if en_scl is None or in_scl is None: - return False - - target_scl = get_target_scl_name( - instruction, "out1", network_id, default_to_temp=False - ) - if target_scl is None: - print(f"Advertencia: MOVE UID: {instr_uid} no tiene destino claro.") - return False - - scl_core = f"{target_scl} := {in_scl};" - - # --- Lógica de Agrupación --- - is_grouped, _ = check_if_grouped(instruction, network_id) - if is_grouped: - scl_final = scl_core # Solo el core si es parte de grupo - instruction["grouped"] = True # Marcar como agrupado - elif en_scl != "TRUE": - scl_final = f"IF {en_scl} THEN\n {scl_core}\nEND_IF;" - else: - scl_final = scl_core - # --- Fin Lógica de Agrupación --- - - instruction["scl"] = scl_final - instruction["type"] = instr_type + SCL_SUFFIX - return True - - -def process_add(instruction, network_id, scl_map, access_map): - instr_uid = instruction["instruction_uid"] - instr_type = instruction["type"] - if instr_type.endswith(SCL_SUFFIX) or "_error" in instr_type: - return False - - en_input = instruction["inputs"].get("en") - en_scl = ( - "TRUE" - if en_input is None - else get_scl_representation(en_input, network_id, scl_map, access_map) - ) - 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 - ) - - if en_scl is None or in1_scl is None or in2_scl is None: - return False - - target_scl = get_target_scl_name( - instruction, "out", network_id, default_to_temp=True - ) - if target_scl is None: - print(f"Error Interno: No se pudo det. destino ADD {instr_uid}") - 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 - scl_core = f"{target_scl} := {op1} + {op2};" - - is_grouped, _ = check_if_grouped(instruction, network_id) - if is_grouped: - scl_final = scl_core - instruction["grouped"] = True - elif en_scl != "TRUE": - scl_final = f"IF {en_scl} THEN\n {scl_core}\nEND_IF;" - else: - scl_final = scl_core - - 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 - map_key_eno = (network_id, instr_uid, "eno") - scl_map[map_key_eno] = en_scl - return True - - -# --- (Aplica lógica similar de 'check_if_grouped' a process_convert, process_mod, etc.) --- -# Ejemplo para process_convert: -def process_convert(instruction, network_id, scl_map, access_map): - instr_uid = instruction["instruction_uid"] - instr_type = instruction["type"] - if instr_type.endswith(SCL_SUFFIX) or "_error" in instr_type: - return False - - en_input = instruction["inputs"].get("en") - en_scl = ( - "TRUE" - if en_input is None - else get_scl_representation(en_input, network_id, scl_map, access_map) - ) - in_scl = get_scl_representation( - instruction["inputs"].get("in"), network_id, scl_map, access_map - ) - - if en_scl is None or in_scl is None: - return False - - target_scl = get_target_scl_name( - instruction, "out", network_id, default_to_temp=True - ) - if target_scl is None: - print(f"Error Interno: No se pudo det. destino CONVERT {instr_uid}") - instruction["type"] += "_error" - return True - - conversion_expr = in_scl - scl_core = f"{target_scl} := {conversion_expr};" - - is_grouped, _ = check_if_grouped(instruction, network_id) - if is_grouped: - scl_final = scl_core - instruction["grouped"] = True - elif en_scl != "TRUE": - scl_final = f"IF {en_scl} THEN\n {scl_core}\nEND_IF;" - else: - scl_final = scl_core - - 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 - map_key_eno = (network_id, instr_uid, "eno") - scl_map[map_key_eno] = en_scl - return True - - -# Ejemplo para process_mod: -def process_mod(instruction, network_id, scl_map, access_map): - instr_uid = instruction["instruction_uid"] - instr_type = instruction["type"] - if instr_type.endswith(SCL_SUFFIX) or "_error" in instr_type: - return False - - en_input = instruction["inputs"].get("en") - en_scl = ( - "TRUE" - if en_input is None - else get_scl_representation(en_input, network_id, scl_map, access_map) - ) - 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 - ) - - if en_scl is None or in1_scl is None or in2_scl is None: - return False - - target_scl = get_target_scl_name( - instruction, "out", network_id, default_to_temp=True - ) - if target_scl is None: - print(f"Error Interno: No se pudo det. destino MOD {instr_uid}") - 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 - scl_core = f"{target_scl} := {op1} MOD {op2};" - - is_grouped, _ = check_if_grouped(instruction, network_id) - if is_grouped: - scl_final = scl_core - instruction["grouped"] = True - elif en_scl != "TRUE": - scl_final = f"IF {en_scl} THEN\n {scl_core}\nEND_IF;" - else: - scl_final = scl_core - - 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 - map_key_eno = (network_id, instr_uid, "eno") - scl_map[map_key_eno] = en_scl - return True - - -# --- (process_contact, process_eq, process_coil, process_o, process_pbox - sin cambios respecto a la versión anterior) --- -# ... (Asegúrate de tener las versiones funcionales de estos aquí) ... def process_contact(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 - is_negated = False + is_negated = False # TODO in_input = instruction["inputs"].get("in") in_rlo_scl = ( "TRUE" @@ -421,25 +175,25 @@ def process_contact(instruction, network_id, scl_map, access_map): if not (term.startswith('"') and term.endswith('"')): if " " in term and not (term.startswith("(") and term.endswith(")")): term = f"({term})" - new_rlo_scl = "" - if in_rlo_scl == "TRUE": - new_rlo_scl = term - else: - if ("AND" in in_rlo_scl or "OR" in in_rlo_scl) and not ( - in_rlo_scl.startswith("(") and in_rlo_scl.endswith(")") - ): - in_rlo_processed = f"({in_rlo_scl})" - else: - in_rlo_processed = in_rlo_scl - new_rlo_scl = f"{in_rlo_processed} AND {term}" + new_rlo_scl = ( + term + if in_rlo_scl == "TRUE" + else ( + f"({in_rlo_scl}) AND {term}" + if ("AND" in in_rlo_scl or "OR" in in_rlo_scl) + and not (in_rlo_scl.startswith("(") and in_rlo_scl.endswith(")")) + 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 updated by Contact {instr_uid}: {new_rlo_scl}" + instruction["scl"] = f"// RLO: {new_rlo_scl}" # SCL es solo comentario aquí 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: @@ -467,12 +221,13 @@ def process_eq(instruction, network_id, scl_map, access_map): return False map_key_eno = (network_id, instr_uid, "eno") scl_map[map_key_eno] = pre_scl - instruction["scl"] = f"// Comparison Eq {instr_uid}: {comparison_scl}" + instruction["scl"] = f"// Cond: {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: @@ -499,7 +254,179 @@ def process_coil(instruction, network_id, scl_map, access_map): return True +def process_convert(instruction, network_id, scl_map, access_map): + instr_uid = instruction["instruction_uid"] + instr_type = instruction["type"] + if instr_type.endswith(SCL_SUFFIX) or "_error" in instr_type: + 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 + ) + + if en_scl is None or in_scl is None: + return False # Esperar si dependencias no listas + + target_scl = get_target_scl_name( + instruction, "out", network_id, default_to_temp=True + ) + if target_scl is None: + print(f"Error: Sin destino CONVERT {instr_uid}") + instruction["type"] += "_error" + return True + + conversion_expr = in_scl # TODO: Logica de conversion explicita + scl_core = f"{target_scl} := {conversion_expr};" + 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 + map_key_out = (network_id, instr_uid, "out") + scl_map[map_key_out] = target_scl + map_key_eno = (network_id, instr_uid, "eno") + scl_map[map_key_eno] = en_scl + return True + + +def process_mod(instruction, network_id, scl_map, access_map): + instr_uid = instruction["instruction_uid"] + instr_type = instruction["type"] + if instr_type.endswith(SCL_SUFFIX) or "_error" in instr_type: + return False + + en_input = instruction["inputs"].get("en") + en_scl = ( + get_scl_representation(en_input, 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 + ) + + if en_scl is None or in1_scl is None or in2_scl is None: + return False + + target_scl = get_target_scl_name( + instruction, "out", network_id, default_to_temp=True + ) + if target_scl is None: + print(f"Error: Sin destino MOD {instr_uid}") + 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 + 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 + ) + + 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 + map_key_eno = (network_id, instr_uid, "eno") + scl_map[map_key_eno] = en_scl + return True + + +def process_add(instruction, network_id, scl_map, access_map): + instr_uid = instruction["instruction_uid"] + instr_type = instruction["type"] + if instr_type.endswith(SCL_SUFFIX) or "_error" in instr_type: + return False + + en_input = instruction["inputs"].get("en") + en_scl = ( + get_scl_representation(en_input, 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 + ) + + if en_scl is None or in1_scl is None or in2_scl is None: + return False + + target_scl = get_target_scl_name( + instruction, "out", network_id, default_to_temp=True + ) + if target_scl is None: + print(f"Error: Sin destino ADD {instr_uid}") + 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 + 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 + ) + + 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 + map_key_eno = (network_id, instr_uid, "eno") + scl_map[map_key_eno] = en_scl + return True + + +def process_move(instruction, network_id, scl_map, access_map): + instr_uid = instruction["instruction_uid"] + instr_type = instruction["type"] + if instr_type.endswith(SCL_SUFFIX) or "_error" in instr_type: + return False + + en_input = instruction["inputs"].get("en") + en_scl = ( + get_scl_representation(en_input, 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 + ) + + if en_scl is None or in_scl is None: + return False + + 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 + + scl_core = f"{target_scl} := {in_scl};" + 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 + 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: @@ -575,7 +502,7 @@ def process_pbox(instruction, network_id, scl_map, access_map, network_logic_lis clk_source_found = True break if not clk_source_found: - print(f"Error: No se pudo inferir CLK para PBOX {instr_uid}") + print(f"Error: No se pudo inferir CLK PBOX {instr_uid}") instruction["scl"] = f"// ERROR: PBox {instr_uid} sin CLK" instruction["type"] += "_error" return True @@ -585,9 +512,7 @@ def process_pbox(instruction, network_id, scl_map, access_map, network_logic_lis 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 detection PBox {instr_uid} -> {result_scl} (CLK inferred)" - ) + 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 @@ -600,6 +525,7 @@ def process_pbox(instruction, network_id, scl_map, access_map, network_logic_lis 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: @@ -640,11 +566,11 @@ def process_o(instruction, network_id, scl_map, access_map): return True -# --- NUEVO: Procesador de Agrupación --- +# --- 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) - y, si habilitan un grupo de bloques funcionales, construye el bloque IF agrupado. + 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. Modifica el campo 'scl' de la instrucción generadora de condición. """ instr_uid = instruction["instruction_uid"] @@ -652,7 +578,7 @@ def process_group_ifs(instruction, network_id, scl_map, access_map): instr_type_original = instr_type.replace("_scl", "").replace("_error", "") made_change = False - # Solo actuar sobre generadores de condición ya procesados + # Solo actuar sobre generadores de condición ya procesados (_scl) if not instr_type.endswith("_scl") or instr_type_original not in [ "Contact", "O", @@ -664,22 +590,24 @@ def process_group_ifs(instruction, network_id, scl_map, access_map): "Le", "PBox", ]: - return False # No es un generador de condición procesado relevante - - # Si ya contiene un IF agrupado (de un pase anterior o error), no hacer nada - if instruction.get("scl", "").strip().startswith("IF"): return False - # Obtener la condición generada por esta instrucción + # 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.") + return False + + # Obtener la condición generada por esta instrucción (debería estar en scl_map) map_key_out = (network_id, instr_uid, "out") condition_scl = scl_map.get(map_key_out) - if condition_scl is None or condition_scl == "TRUE" or condition_scl == "FALSE": - return False # No agrupar para condiciones triviales + # No agrupar para condiciones triviales o no encontradas + 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_core_scl = [] - consumer_uids_processed_in_group = set() # Para marcar consumidores agrupados + grouped_instructions_cores = [] # Lista de SCL 'core' + consumer_instr_list = [] # Lista de instrucciones consumidoras network_logic = next( (net["logic"] for net in data["networks"] if net["id"] == network_id), [] ) @@ -688,15 +616,15 @@ def process_group_ifs(instruction, network_id, scl_map, access_map): for consumer_instr in network_logic: consumer_uid = consumer_instr["instruction_uid"] - # Saltar si el consumidor ya fue marcado como agrupado por otra condición + # Saltar si ya está agrupado por otra condición if consumer_instr.get("grouped", False): continue consumer_en = consumer_instr.get("inputs", {}).get("en") - consumer_type = consumer_instr.get("type", "") + consumer_type = consumer_instr.get("type", "") # Tipo actual (_scl o no) consumer_type_original = consumer_type.replace("_scl", "").replace("_error", "") - # Verificar si está conectado a nuestra salida 'out' + # ¿Está conectado a nuestra salida 'out'? if ( isinstance(consumer_en, dict) and consumer_en.get("type") == "connection" @@ -704,42 +632,59 @@ def process_group_ifs(instruction, network_id, scl_map, access_map): and consumer_en.get("source_pin") == "out" ): - # Verificar si es un bloque funcional procesado y si su SCL es solo el 'core' - if ( - consumer_type.endswith("_scl") - and consumer_type_original - in ["Move", "Add", "Sub", "Mul", "Div", "Mod", "Convert"] - and consumer_instr.get("scl") - and not consumer_instr["scl"].strip().startswith("IF") - ): # Asegurarse de que NO tenga IF + # ¿Es un bloque funcional procesado? + if consumer_type.endswith("_scl") and consumer_type_original in [ + "Move", + "Add", + "Sub", + "Mul", + "Div", + "Mod", + "Convert", + ]: - core_scl = consumer_instr["scl"].strip() - grouped_instructions_core_scl.append(core_scl) - consumer_uids_processed_in_group.add(consumer_uid) + 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() - # Si encontramos más de un consumidor agrupado - if len(grouped_instructions_core_scl) > 1: + 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 + if len(grouped_instructions_cores) > 1: print( - f"INFO: Agrupando {len(grouped_instructions_core_scl)} instrucciones para 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}" ) - # Construir el bloque IF agrupado scl_grouped = [f"IF {condition_scl} THEN"] - for core_line in grouped_instructions_core_scl: - scl_grouped.append(f" {core_line}") # Añadir indentación + for core_line in grouped_instructions_cores: + # Añadir indentación adecuada si el core tiene múltiples líneas + indented_core = "\n".join( + [f" {line.strip()}" for line in core_line.splitlines()] + ) + scl_grouped.append(indented_core) scl_grouped.append("END_IF;") final_grouped_scl = "\n".join(scl_grouped) - # Sobrescribir el campo 'scl' de la instrucción generadora de condición + # Sobrescribir 'scl' de la instrucción generadora instruction["scl"] = final_grouped_scl - # Marcar los consumidores para que generate_scl los ignore - for consumer_uid_to_mark in consumer_uids_processed_in_group: - for instr_to_mark in network_logic: - if instr_to_mark["instruction_uid"] == consumer_uid_to_mark: - # Añadir comentario y flag - instr_to_mark["scl"] = f"{GROUPED_COMMENT} (by UID {instr_uid})" - instr_to_mark["grouped"] = True - break + # Marcar los consumidores + for consumer_instr in consumer_instr_list: + consumer_instr["scl"] = f"{GROUPED_COMMENT} (by UID {instr_uid})" + consumer_instr["grouped"] = True made_change = True return made_change @@ -751,21 +696,19 @@ def process_group_ifs(instruction, network_id, scl_map, access_map): 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): - print(f"Error: Archivo JSON no encontrado en {json_filepath}") + print(f"Error: JSON no encontrado: {json_filepath}") return - print(f"Cargando JSON desde: {json_filepath}") try: with open(json_filepath, "r", encoding="utf-8") as f: global data data = json.load(f) except Exception as e: - print(f"Error al cargar o parsear JSON: {e}") + print(f"Error al cargar JSON: {e}") return - # Reconstruir access_map dinámicamente network_access_maps = {} - # print("Creando mapas de acceso por red...") + # print("Creando mapas de acceso por red...") # Comentado para brevedad for network in data.get("networks", []): net_id = network["id"] current_access_map = {} @@ -800,7 +743,7 @@ def process_json_to_scl(json_filepath): max_passes = 25 passes = 0 - # Lista de procesadores base + procesador de agrupación + # Lista y mapa de procesadores base base_processors = [ process_convert, process_mod, @@ -824,12 +767,11 @@ def process_json_to_scl(json_filepath): print(f"\n--- Pase {passes} ---") # --- FASE 1: Procesadores Base --- - print(f"DEBUG: Iniciando Fase 1 (Procesadores Base) - Pase {passes}") + # 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"] if ( @@ -837,11 +779,9 @@ def process_json_to_scl(json_filepath): or "_error" in instr_type_original or instruction.get("grouped", False) ): - continue # Saltar ya procesados, erróneos o agrupados - + continue instr_type_lower_lookup = instr_type_original.lower() func_to_call = processor_map.get(instr_type_lower_lookup) - if func_to_call: try: changed = False @@ -857,59 +797,49 @@ def process_json_to_scl(json_filepath): changed = func_to_call( instruction, network_id, scl_map, access_map ) - if changed: - # print(f"DEBUG: Cambio BASE detectado por {func_to_call.__name__} en UID {instruction['instruction_uid']}") made_change_in_base_pass = True except Exception as e: print( - f"ERROR(Base) al ejecutar {func_to_call.__name__} en UID {instruction.get('instruction_uid')} Red {network_id}: {e}" + f"ERROR(Base) {func_to_call.__name__} UID {instruction.get('instruction_uid')}: {e}" ) traceback.print_exc() - instruction["scl"] = f"// ERROR during base processing: {e}" + instruction["scl"] = f"// ERROR base: {e}" instruction["type"] += "_error" - made_change_in_base_pass = True # Considerar error como cambio + made_change_in_base_pass = True # --- FASE 2: Procesador de Agrupación --- - print(f"DEBUG: Iniciando Fase 2 (Agrupación IF) - Pase {passes}") + # 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: - # Solo intentar agrupar en generadores de condición ya procesados 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: - # print(f"DEBUG: Cambio GROUP detectado por process_group_ifs en UID {instruction['instruction_uid']}") made_change_in_group_pass = True except Exception as e: print( - f"ERROR(Group) al ejecutar process_group_ifs en UID {instruction.get('instruction_uid')}: {e}" + f"ERROR(Group) process_group_ifs UID {instruction.get('instruction_uid')}: {e}" ) traceback.print_exc() - # No marcar la instrucción como error por fallo en agrupación - # Decidir si continuar: Hubo algún cambio en CUALQUIERA de las fases? + # Decidir si continuar 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. ---" ) break - else: - print( - f"DEBUG: Cambios en Pase {passes}: Base={made_change_in_base_pass}, Grupo={made_change_in_group_pass}. Continuando..." - ) + # 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. Puede haber dependencias circulares o lógica no procesada. ---" - ) + print(f"\n--- Límite de {max_passes} pases alcanzado. ---") # --- Guardar JSON Final --- output_filename = json_filepath.replace(".json", "_scl_processed.json") @@ -919,10 +849,10 @@ def process_json_to_scl(json_filepath): json.dump(data, f, indent=4, ensure_ascii=False) print("Guardado completado.") except Exception as e: - print(f"Error al guardar el JSON procesado: {e}") + print(f"Error al guardar JSON: {e}") # --- Ejecución --- if __name__ == "__main__": - input_json_file = "BlenderRun_ProdTime_simplified.json" + input_json_file = "BlenderRun_ProdTime_simplified.json" # Asegúrate que este es el generado por x1_to_json.py MODIFICADO process_json_to_scl(input_json_file)