Incluidos los Timers

This commit is contained in:
Miguel 2025-04-19 03:51:21 +02:00
parent 2d9fd4e80a
commit 6228d77d8d
5 changed files with 1564 additions and 382 deletions

View File

@ -64,7 +64,9 @@
"type": "powerrail"
}
},
"outputs": {}
"outputs": {
"out": []
}
},
{
"instruction_uid": "31",
@ -88,7 +90,9 @@
"source_pin": "out"
}
},
"outputs": {}
"outputs": {
"out": []
}
},
{
"instruction_uid": "32",
@ -112,7 +116,9 @@
"source_pin": "out"
}
},
"outputs": {}
"outputs": {
"out": []
}
},
{
"instruction_uid": "33",
@ -134,7 +140,9 @@
"source_pin": "out"
}
},
"outputs": {}
"outputs": {
"out": []
}
},
{
"instruction_uid": "34",
@ -158,7 +166,9 @@
"source_pin": "out"
}
},
"outputs": {}
"outputs": {
"out": []
}
},
{
"instruction_uid": "35",
@ -180,7 +190,9 @@
"source_pin": "out"
}
},
"outputs": {}
"outputs": {
"out": []
}
},
{
"instruction_uid": "36",
@ -202,7 +214,9 @@
"source_pin": "out"
}
},
"outputs": {}
"outputs": {
"out": []
}
},
{
"instruction_uid": "37",
@ -224,7 +238,9 @@
"source_pin": "out"
}
},
"outputs": {}
"outputs": {
"out": []
}
},
{
"instruction_uid": "38",
@ -235,20 +251,22 @@
},
"negated_pins": {},
"inputs": {
"in2": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "37",
"source_pin": "out"
},
"in1": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "34",
"source_pin": "out"
},
"in2": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "37",
"source_pin": "out"
}
},
"outputs": {}
"outputs": {
"out": []
}
},
{
"instruction_uid": "39",
@ -297,7 +315,9 @@
"type": "powerrail"
}
},
"outputs": {}
"outputs": {
"out": []
}
},
{
"instruction_uid": "26",
@ -312,6 +332,12 @@
"source_instruction_uid": "25",
"source_pin": "out"
},
"timer": {
"uid": "22",
"scope": "GlobalVariable",
"type": "variable",
"name": "\"mHVM302_Dly\""
},
"tv": {
"uid": "23",
"scope": "TypedConstant",
@ -326,7 +352,9 @@
"source_pin": "out"
}
},
"outputs": {}
"outputs": {
"q": []
}
},
{
"instruction_uid": "27",
@ -375,7 +403,9 @@
"type": "powerrail"
}
},
"outputs": {}
"outputs": {
"out": []
}
},
{
"instruction_uid": "25",
@ -390,6 +420,12 @@
"source_instruction_uid": "24",
"source_pin": "out"
},
"timer": {
"uid": "22",
"scope": "GlobalVariable",
"type": "variable",
"name": "\"mResetTotalizerTmr\""
},
"tv": {
"uid": "23",
"scope": "TypedConstant",
@ -431,7 +467,9 @@
"type": "powerrail"
}
},
"outputs": {}
"outputs": {
"out": []
}
},
{
"instruction_uid": "27",
@ -450,7 +488,9 @@
"type": "powerrail"
}
},
"outputs": {}
"outputs": {
"out": []
}
},
{
"instruction_uid": "28",
@ -461,20 +501,22 @@
},
"negated_pins": {},
"inputs": {
"in2": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "27",
"source_pin": "out"
},
"in1": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "26",
"source_pin": "out"
},
"in2": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "27",
"source_pin": "out"
}
},
"outputs": {}
"outputs": {
"out": []
}
},
{
"instruction_uid": "29",
@ -489,6 +531,12 @@
"source_instruction_uid": "28",
"source_pin": "out"
},
"timer": {
"uid": "23",
"scope": "GlobalVariable",
"type": "variable",
"name": "\"mResetFTN301TotTmr\""
},
"tv": {
"uid": "24",
"scope": "TypedConstant",
@ -503,7 +551,9 @@
"source_pin": "out"
}
},
"outputs": {}
"outputs": {
"q": []
}
},
{
"instruction_uid": "30",
@ -552,7 +602,9 @@
"type": "powerrail"
}
},
"outputs": {}
"outputs": {
"out": []
}
},
{
"instruction_uid": "28",
@ -571,7 +623,9 @@
"type": "powerrail"
}
},
"outputs": {}
"outputs": {
"out": []
}
},
{
"instruction_uid": "29",
@ -582,20 +636,22 @@
},
"negated_pins": {},
"inputs": {
"in2": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "28",
"source_pin": "out"
},
"in1": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "27",
"source_pin": "out"
},
"in2": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "28",
"source_pin": "out"
}
},
"outputs": {}
"outputs": {
"out": []
}
},
{
"instruction_uid": "30",
@ -610,6 +666,12 @@
"source_instruction_uid": "29",
"source_pin": "out"
},
"timer": {
"uid": "23",
"scope": "GlobalVariable",
"type": "variable",
"name": "\"mResetFTP302TotTmr\""
},
"tv": {
"uid": "24",
"scope": "TypedConstant",
@ -624,7 +686,9 @@
"source_pin": "out"
}
},
"outputs": {}
"outputs": {
"q": []
}
},
{
"instruction_uid": "31",
@ -646,7 +710,9 @@
"source_pin": "q"
}
},
"outputs": {}
"outputs": {
"out": []
}
},
{
"instruction_uid": "32",
@ -695,7 +761,9 @@
"type": "powerrail"
}
},
"outputs": {}
"outputs": {
"out": []
}
},
{
"instruction_uid": "27",
@ -714,7 +782,9 @@
"type": "powerrail"
}
},
"outputs": {}
"outputs": {
"out": []
}
},
{
"instruction_uid": "28",
@ -725,20 +795,22 @@
},
"negated_pins": {},
"inputs": {
"in2": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "27",
"source_pin": "out"
},
"in1": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "26",
"source_pin": "out"
},
"in2": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "27",
"source_pin": "out"
}
},
"outputs": {}
"outputs": {
"out": []
}
},
{
"instruction_uid": "29",
@ -753,6 +825,12 @@
"source_instruction_uid": "28",
"source_pin": "out"
},
"timer": {
"uid": "23",
"scope": "GlobalVariable",
"type": "variable",
"name": "\"mResetFTM303TotTmr\""
},
"tv": {
"uid": "24",
"scope": "TypedConstant",
@ -767,7 +845,9 @@
"source_pin": "out"
}
},
"outputs": {}
"outputs": {
"q": []
}
},
{
"instruction_uid": "30",
@ -816,7 +896,9 @@
"type": "powerrail"
}
},
"outputs": {}
"outputs": {
"out": []
}
},
{
"instruction_uid": "27",
@ -835,7 +917,9 @@
"type": "powerrail"
}
},
"outputs": {}
"outputs": {
"out": []
}
},
{
"instruction_uid": "28",
@ -846,20 +930,22 @@
},
"negated_pins": {},
"inputs": {
"in2": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "27",
"source_pin": "out"
},
"in1": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "26",
"source_pin": "out"
},
"in2": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "27",
"source_pin": "out"
}
},
"outputs": {}
"outputs": {
"out": []
}
},
{
"instruction_uid": "29",
@ -874,6 +960,12 @@
"source_instruction_uid": "28",
"source_pin": "out"
},
"timer": {
"uid": "23",
"scope": "GlobalVariable",
"type": "variable",
"name": "\"mResetProductTotTmr\""
},
"tv": {
"uid": "24",
"scope": "TypedConstant",
@ -888,7 +980,9 @@
"source_pin": "out"
}
},
"outputs": {}
"outputs": {
"q": []
}
},
{
"instruction_uid": "30",
@ -937,7 +1031,9 @@
"type": "powerrail"
}
},
"outputs": {}
"outputs": {
"out": []
}
},
{
"instruction_uid": "34",
@ -961,7 +1057,9 @@
"source_pin": "out"
}
},
"outputs": {}
"outputs": {
"out": []
}
},
{
"instruction_uid": "35",
@ -1024,7 +1122,9 @@
"type": "powerrail"
}
},
"outputs": {}
"outputs": {
"out": []
}
},
{
"instruction_uid": "38",
@ -1046,29 +1146,46 @@
"source_pin": "out"
}
},
"outputs": {}
"outputs": {
"out": []
}
},
{
"instruction_uid": "39",
"uid": "39",
"type": "SdCoil",
"type": "Se",
"template_values": {},
"negated_pins": {},
"inputs": {
"operand": {
"timer": {
"uid": "27",
"scope": "GlobalVariable",
"type": "variable",
"name": "\"T_Pulse_Recipe_Edit\""
},
"in": {
"s": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "38",
"source_pin": "out"
},
"tv": {
"uid": "28",
"scope": "TypedConstant",
"type": "constant",
"datatype": "TypedConstant",
"value": "S5T#500ms"
},
"en": {
"type": "connection",
"source_instruction_uid": "38",
"source_instruction_type": "Contact",
"source_pin": "out"
}
},
"outputs": {}
"outputs": {
"q": []
}
},
{
"instruction_uid": "40",
@ -1087,10 +1204,12 @@
"type": "connection",
"source_instruction_type": "SdCoil",
"source_instruction_uid": "39",
"source_pin": "out"
"source_pin": "q"
}
},
"outputs": {}
"outputs": {
"out": []
}
},
{
"instruction_uid": "41",
@ -1131,7 +1250,9 @@
"type": "powerrail"
}
},
"outputs": {}
"outputs": {
"out": []
}
},
{
"instruction_uid": "43",

View File

@ -64,7 +64,9 @@
"type": "powerrail"
}
},
"outputs": {},
"outputs": {
"out": []
},
"scl": "// RLO: \"gSyrupRoomEn\""
},
{
@ -89,7 +91,9 @@
"source_pin": "out"
}
},
"outputs": {},
"outputs": {
"out": []
},
"scl": "// RLO: \"gSyrupRoomEn\" AND (NOT \"gIN_HVP301_Aux\")"
},
{
@ -114,7 +118,9 @@
"source_pin": "out"
}
},
"outputs": {},
"outputs": {
"out": []
},
"scl": "// RLO: (\"gSyrupRoomEn\" AND (NOT \"gIN_HVP301_Aux\")) AND (NOT \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_FastChangeOverEnabled\")"
},
{
@ -137,7 +143,9 @@
"source_pin": "out"
}
},
"outputs": {},
"outputs": {
"out": []
},
"scl": "// RLO: (\"gSyrupRoomEn\" AND (NOT \"gIN_HVP301_Aux\")) AND (NOT \"HMI_Blender_Parameters\".\"Processor_Options\".\"Blender_OPT\".\"_FastChangeOverEnabled\") AND \"Procedure_Variables\".\"FTP302Line_Preparation\".\"Done\""
},
{
@ -162,7 +170,9 @@
"source_pin": "out"
}
},
"outputs": {},
"outputs": {
"out": []
},
"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\")"
},
{
@ -185,7 +195,9 @@
"source_pin": "out"
}
},
"outputs": {},
"outputs": {
"out": []
},
"scl": "// RLO: (\"gSyrupRoomEn\" AND (NOT \"gIN_HVP301_Aux\")) AND \"gBlenderCIPMode\""
},
{
@ -208,7 +220,9 @@
"source_pin": "out"
}
},
"outputs": {},
"outputs": {
"out": []
},
"scl": "// RLO: ((\"gSyrupRoomEn\" AND (NOT \"gIN_HVP301_Aux\")) AND \"gBlenderCIPMode\") AND \"gIN_CIP_CIPRunning\""
},
{
@ -231,7 +245,9 @@
"source_pin": "out"
}
},
"outputs": {},
"outputs": {
"out": []
},
"scl": "// RLO: (((\"gSyrupRoomEn\" AND (NOT \"gIN_HVP301_Aux\")) AND \"gBlenderCIPMode\") AND \"gIN_CIP_CIPRunning\") AND \"Procedure_Variables\".\"Blender_Run\".\"Running\""
},
{
@ -243,20 +259,22 @@
},
"negated_pins": {},
"inputs": {
"in2": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "37",
"source_pin": "out"
},
"in1": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "34",
"source_pin": "out"
},
"in2": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "37",
"source_pin": "out"
}
},
"outputs": {},
"outputs": {
"out": []
},
"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 ((((\"gSyrupRoomEn\" AND (NOT \"gIN_HVP301_Aux\")) AND \"gBlenderCIPMode\") AND \"gIN_CIP_CIPRunning\") AND \"Procedure_Variables\".\"Blender_Run\".\"Running\")"
},
{
@ -307,13 +325,15 @@
"type": "powerrail"
}
},
"outputs": {},
"outputs": {
"out": []
},
"scl": "// RLO: \"gIN_HVM302_Aux\""
},
{
"instruction_uid": "26",
"uid": "26",
"type": "Sd",
"type": "Sd_scl",
"template_values": {},
"negated_pins": {},
"inputs": {
@ -323,6 +343,12 @@
"source_instruction_uid": "25",
"source_pin": "out"
},
"timer": {
"uid": "22",
"scope": "GlobalVariable",
"type": "variable",
"name": "\"mHVM302_Dly\""
},
"tv": {
"uid": "23",
"scope": "TypedConstant",
@ -337,12 +363,15 @@
"source_pin": "out"
}
},
"outputs": {}
"outputs": {
"q": []
},
"scl": "\"mHVM302_Dly\"(IN := \"gIN_HVM302_Aux\", PT := S5T#1S); // TODO: Declarar \"mHVM302_Dly\" : TON; en VAR_STAT o VAR"
},
{
"instruction_uid": "27",
"uid": "27",
"type": "Coil",
"type": "Coil_scl",
"template_values": {},
"negated_pins": {},
"inputs": {
@ -359,7 +388,8 @@
"source_pin": "q"
}
},
"outputs": {}
"outputs": {},
"scl": "\"gHVM302_Open\" := \"mHVM302_Dly\".Q;"
}
],
"language": "LAD"
@ -386,13 +416,15 @@
"type": "powerrail"
}
},
"outputs": {},
"outputs": {
"out": []
},
"scl": "// RLO: \"gBlendResetTotalizer\""
},
{
"instruction_uid": "25",
"uid": "25",
"type": "Se",
"type": "Se_scl",
"template_values": {},
"negated_pins": {},
"inputs": {
@ -402,6 +434,12 @@
"source_instruction_uid": "24",
"source_pin": "out"
},
"timer": {
"uid": "22",
"scope": "GlobalVariable",
"type": "variable",
"name": "\"mResetTotalizerTmr\""
},
"tv": {
"uid": "23",
"scope": "TypedConstant",
@ -416,7 +454,8 @@
"source_pin": "out"
}
},
"outputs": {}
"outputs": {},
"scl": "\"mResetTotalizerTmr\"(IN := \"gBlendResetTotalizer\", PT := S5T#2S); // TODO: Declarar \"mResetTotalizerTmr\" : TP; en VAR_STAT o VAR"
}
],
"language": "LAD"
@ -443,7 +482,9 @@
"type": "powerrail"
}
},
"outputs": {},
"outputs": {
"out": []
},
"scl": "// RLO: \"gFTN301_ResetTot\""
},
{
@ -463,7 +504,9 @@
"type": "powerrail"
}
},
"outputs": {},
"outputs": {
"out": []
},
"scl": "// RLO: \"mResetTotalizerTmr\""
},
{
@ -475,26 +518,28 @@
},
"negated_pins": {},
"inputs": {
"in2": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "27",
"source_pin": "out"
},
"in1": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "26",
"source_pin": "out"
},
"in2": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "27",
"source_pin": "out"
}
},
"outputs": {},
"outputs": {
"out": []
},
"scl": "// Logic O 28: \"gFTN301_ResetTot\" OR \"mResetTotalizerTmr\""
},
{
"instruction_uid": "29",
"uid": "29",
"type": "Se",
"type": "Se_scl",
"template_values": {},
"negated_pins": {},
"inputs": {
@ -504,6 +549,12 @@
"source_instruction_uid": "28",
"source_pin": "out"
},
"timer": {
"uid": "23",
"scope": "GlobalVariable",
"type": "variable",
"name": "\"mResetFTN301TotTmr\""
},
"tv": {
"uid": "24",
"scope": "TypedConstant",
@ -518,12 +569,15 @@
"source_pin": "out"
}
},
"outputs": {}
"outputs": {
"q": []
},
"scl": "\"mResetFTN301TotTmr\"(IN := \"gFTN301_ResetTot\" OR \"mResetTotalizerTmr\", PT := S5T#2S); // TODO: Declarar \"mResetFTN301TotTmr\" : TP; en VAR_STAT o VAR"
},
{
"instruction_uid": "30",
"uid": "30",
"type": "Coil",
"type": "Coil_scl",
"template_values": {},
"negated_pins": {},
"inputs": {
@ -540,7 +594,8 @@
"source_pin": "q"
}
},
"outputs": {}
"outputs": {},
"scl": "\"mResetWaterTot\" := \"mResetFTN301TotTmr\".Q;"
}
],
"language": "LAD"
@ -567,7 +622,9 @@
"type": "powerrail"
}
},
"outputs": {},
"outputs": {
"out": []
},
"scl": "// RLO: \"gFTP302_ResetTot\""
},
{
@ -587,7 +644,9 @@
"type": "powerrail"
}
},
"outputs": {},
"outputs": {
"out": []
},
"scl": "// RLO: \"mResetTotalizerTmr\""
},
{
@ -599,26 +658,28 @@
},
"negated_pins": {},
"inputs": {
"in2": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "28",
"source_pin": "out"
},
"in1": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "27",
"source_pin": "out"
},
"in2": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "28",
"source_pin": "out"
}
},
"outputs": {},
"outputs": {
"out": []
},
"scl": "// Logic O 29: \"gFTP302_ResetTot\" OR \"mResetTotalizerTmr\""
},
{
"instruction_uid": "30",
"uid": "30",
"type": "Se",
"type": "Se_scl",
"template_values": {},
"negated_pins": {},
"inputs": {
@ -628,6 +689,12 @@
"source_instruction_uid": "29",
"source_pin": "out"
},
"timer": {
"uid": "23",
"scope": "GlobalVariable",
"type": "variable",
"name": "\"mResetFTP302TotTmr\""
},
"tv": {
"uid": "24",
"scope": "TypedConstant",
@ -642,12 +709,15 @@
"source_pin": "out"
}
},
"outputs": {}
"outputs": {
"q": []
},
"scl": "\"mResetFTP302TotTmr\"(IN := \"gFTP302_ResetTot\" OR \"mResetTotalizerTmr\", PT := S5T#2S); // TODO: Declarar \"mResetFTP302TotTmr\" : TP; en VAR_STAT o VAR"
},
{
"instruction_uid": "31",
"uid": "31",
"type": "Contact",
"type": "Contact_scl",
"template_values": {},
"negated_pins": {},
"inputs": {
@ -664,12 +734,15 @@
"source_pin": "q"
}
},
"outputs": {}
"outputs": {
"out": []
},
"scl": "// RLO: \"mResetFTP302TotTmr\".Q AND \"gSyrupRoomEn\""
},
{
"instruction_uid": "32",
"uid": "32",
"type": "Coil",
"type": "Coil_scl",
"template_values": {},
"negated_pins": {},
"inputs": {
@ -686,7 +759,8 @@
"source_pin": "out"
}
},
"outputs": {}
"outputs": {},
"scl": "\"mResetSyrupTot\" := \"mResetFTP302TotTmr\".Q AND \"gSyrupRoomEn\";"
}
],
"language": "LAD"
@ -713,7 +787,9 @@
"type": "powerrail"
}
},
"outputs": {},
"outputs": {
"out": []
},
"scl": "// RLO: \"gFTM303_ResetTot\""
},
{
@ -733,7 +809,9 @@
"type": "powerrail"
}
},
"outputs": {},
"outputs": {
"out": []
},
"scl": "// RLO: \"mResetTotalizerTmr\""
},
{
@ -745,26 +823,28 @@
},
"negated_pins": {},
"inputs": {
"in2": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "27",
"source_pin": "out"
},
"in1": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "26",
"source_pin": "out"
},
"in2": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "27",
"source_pin": "out"
}
},
"outputs": {},
"outputs": {
"out": []
},
"scl": "// Logic O 28: \"gFTM303_ResetTot\" OR \"mResetTotalizerTmr\""
},
{
"instruction_uid": "29",
"uid": "29",
"type": "Se",
"type": "Se_scl",
"template_values": {},
"negated_pins": {},
"inputs": {
@ -774,6 +854,12 @@
"source_instruction_uid": "28",
"source_pin": "out"
},
"timer": {
"uid": "23",
"scope": "GlobalVariable",
"type": "variable",
"name": "\"mResetFTM303TotTmr\""
},
"tv": {
"uid": "24",
"scope": "TypedConstant",
@ -788,12 +874,15 @@
"source_pin": "out"
}
},
"outputs": {}
"outputs": {
"q": []
},
"scl": "\"mResetFTM303TotTmr\"(IN := \"gFTM303_ResetTot\" OR \"mResetTotalizerTmr\", PT := S5T#2S); // TODO: Declarar \"mResetFTM303TotTmr\" : TP; en VAR_STAT o VAR"
},
{
"instruction_uid": "30",
"uid": "30",
"type": "Coil",
"type": "Coil_scl",
"template_values": {},
"negated_pins": {},
"inputs": {
@ -810,7 +899,8 @@
"source_pin": "q"
}
},
"outputs": {}
"outputs": {},
"scl": "\"mResetCO2Tot\" := \"mResetFTM303TotTmr\".Q;"
}
],
"language": "LAD"
@ -837,7 +927,9 @@
"type": "powerrail"
}
},
"outputs": {},
"outputs": {
"out": []
},
"scl": "// RLO: \"gProductMFMResetTot\""
},
{
@ -857,7 +949,9 @@
"type": "powerrail"
}
},
"outputs": {},
"outputs": {
"out": []
},
"scl": "// RLO: \"mResetTotalizerTmr\""
},
{
@ -869,26 +963,28 @@
},
"negated_pins": {},
"inputs": {
"in2": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "27",
"source_pin": "out"
},
"in1": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "26",
"source_pin": "out"
},
"in2": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "27",
"source_pin": "out"
}
},
"outputs": {},
"outputs": {
"out": []
},
"scl": "// Logic O 28: \"gProductMFMResetTot\" OR \"mResetTotalizerTmr\""
},
{
"instruction_uid": "29",
"uid": "29",
"type": "Se",
"type": "Se_scl",
"template_values": {},
"negated_pins": {},
"inputs": {
@ -898,6 +994,12 @@
"source_instruction_uid": "28",
"source_pin": "out"
},
"timer": {
"uid": "23",
"scope": "GlobalVariable",
"type": "variable",
"name": "\"mResetProductTotTmr\""
},
"tv": {
"uid": "24",
"scope": "TypedConstant",
@ -912,12 +1014,15 @@
"source_pin": "out"
}
},
"outputs": {}
"outputs": {
"q": []
},
"scl": "\"mResetProductTotTmr\"(IN := \"gProductMFMResetTot\" OR \"mResetTotalizerTmr\", PT := S5T#2S); // TODO: Declarar \"mResetProductTotTmr\" : TP; en VAR_STAT o VAR"
},
{
"instruction_uid": "30",
"uid": "30",
"type": "Coil",
"type": "Coil_scl",
"template_values": {},
"negated_pins": {},
"inputs": {
@ -934,7 +1039,8 @@
"source_pin": "q"
}
},
"outputs": {}
"outputs": {},
"scl": "\"mResetProductTot\" := \"mResetProductTotTmr\".Q;"
}
],
"language": "LAD"
@ -961,7 +1067,9 @@
"type": "powerrail"
}
},
"outputs": {},
"outputs": {
"out": []
},
"scl": "// RLO: \"HMI_Variables_Cmd\".\"Recipe\".\"Main_Page\""
},
{
@ -986,7 +1094,9 @@
"source_pin": "out"
}
},
"outputs": {},
"outputs": {
"out": []
},
"scl": "// RLO: \"HMI_Variables_Cmd\".\"Recipe\".\"Main_Page\" AND (NOT \"mFP_Recip_Main_Page\")"
},
{
@ -1052,7 +1162,9 @@
"type": "powerrail"
}
},
"outputs": {},
"outputs": {
"out": []
},
"scl": "// RLO: \"HMI_Variables_Cmd\".\"Recipe\".\"Main_Page\""
},
{
@ -1075,35 +1187,53 @@
"source_pin": "out"
}
},
"outputs": {},
"outputs": {
"out": []
},
"scl": "// RLO: \"HMI_Variables_Cmd\".\"Recipe\".\"Main_Page\" AND \"HMI_Variables_Cmd\".\"Recipe\".\"Edit\""
},
{
"instruction_uid": "39",
"uid": "39",
"type": "SdCoil",
"type": "Se_scl",
"template_values": {},
"negated_pins": {},
"inputs": {
"operand": {
"timer": {
"uid": "27",
"scope": "GlobalVariable",
"type": "variable",
"name": "\"T_Pulse_Recipe_Edit\""
},
"in": {
"s": {
"type": "connection",
"source_instruction_type": "Contact",
"source_instruction_uid": "38",
"source_pin": "out"
},
"tv": {
"uid": "28",
"scope": "TypedConstant",
"type": "constant",
"datatype": "TypedConstant",
"value": "S5T#500ms"
},
"en": {
"type": "connection",
"source_instruction_uid": "38",
"source_instruction_type": "Contact",
"source_pin": "out"
}
},
"outputs": {}
"outputs": {
"q": []
},
"scl": "\"T_Pulse_Recipe_Edit\"(IN := \"HMI_Variables_Cmd\".\"Recipe\".\"Main_Page\" AND \"HMI_Variables_Cmd\".\"Recipe\".\"Edit\", PT := S5T#500ms); // TODO: Declarar \"T_Pulse_Recipe_Edit\" : TP; en VAR_STAT o VAR"
},
{
"instruction_uid": "40",
"uid": "40",
"type": "Contact",
"type": "Contact_scl",
"template_values": {},
"negated_pins": {},
"inputs": {
@ -1117,15 +1247,18 @@
"type": "connection",
"source_instruction_type": "SdCoil",
"source_instruction_uid": "39",
"source_pin": "out"
"source_pin": "q"
}
},
"outputs": {}
"outputs": {
"out": []
},
"scl": "// RLO: \"T_Pulse_Recipe_Edit\".Q AND \"T_Pulse_Recipe_Edit\""
},
{
"instruction_uid": "41",
"uid": "41",
"type": "RCoil",
"type": "RCoil_scl",
"template_values": {},
"negated_pins": {},
"inputs": {
@ -1142,7 +1275,8 @@
"source_pin": "out"
}
},
"outputs": {}
"outputs": {},
"scl": "IF \"T_Pulse_Recipe_Edit\".Q AND \"T_Pulse_Recipe_Edit\" THEN\n \"HMI_Variables_Cmd\".\"Recipe\".\"Edit\" := FALSE;\nEND_IF;"
},
{
"instruction_uid": "42",
@ -1161,7 +1295,9 @@
"type": "powerrail"
}
},
"outputs": {},
"outputs": {
"out": []
},
"scl": "// RLO: \"mAux_FP_M700_1\""
},
{

View File

@ -33,32 +33,41 @@ BEGIN
// Network 2: Manual Syrup Drain Valve Open - Operator Alarm (Original Language: LAD)
// Network did not produce printable SCL code.
"mHVM302_Dly"(IN := "gIN_HVM302_Aux", PT := S5T#1S); // TODO: Declarar "mHVM302_Dly" : TON; en VAR_STAT o VAR
"gHVM302_Open" := "mHVM302_Dly".Q;
// Network 3: ResetTotalizer (Original Language: LAD)
// Network did not produce printable SCL code.
"mResetTotalizerTmr"(IN := "gBlendResetTotalizer", PT := S5T#2S); // TODO: Declarar "mResetTotalizerTmr" : TP; en VAR_STAT o VAR
// Network 4: ResetWaterTot (Original Language: LAD)
// Network did not produce printable SCL code.
"mResetFTN301TotTmr"(IN := "gFTN301_ResetTot" OR "mResetTotalizerTmr", PT := S5T#2S); // TODO: Declarar "mResetFTN301TotTmr" : TP; en VAR_STAT o VAR
"mResetWaterTot" := "mResetFTN301TotTmr".Q;
// Network 5: ResetCO2Tot (Original Language: LAD)
// Network did not produce printable SCL code.
"mResetFTP302TotTmr"(IN := "gFTP302_ResetTot" OR "mResetTotalizerTmr", PT := S5T#2S); // TODO: Declarar "mResetFTP302TotTmr" : TP; en VAR_STAT o VAR
"mResetSyrupTot" := "mResetFTP302TotTmr".Q AND "gSyrupRoomEn";
// Network 6: ResetProductTot (Original Language: LAD)
// Network did not produce printable SCL code.
"mResetFTM303TotTmr"(IN := "gFTM303_ResetTot" OR "mResetTotalizerTmr", PT := S5T#2S); // TODO: Declarar "mResetFTM303TotTmr" : TP; en VAR_STAT o VAR
"mResetCO2Tot" := "mResetFTM303TotTmr".Q;
// Network 7: ResetCO2Tot (Original Language: LAD)
// Network did not produce printable SCL code.
"mResetProductTotTmr"(IN := "gProductMFMResetTot" OR "mResetTotalizerTmr", PT := S5T#2S); // TODO: Declarar "mResetProductTotTmr" : TP; en VAR_STAT o VAR
"mResetProductTot" := "mResetProductTotTmr".Q;
// Network 8: Mod Copy Recipe (Original Language: LAD)
"mAux_FP_M700_1" := "HMI_Variables_Cmd"."Recipe"."Main_Page" AND (NOT "mFP_Recip_Main_Page");
"mFP_Recip_Main_Page" := "HMI_Variables_Cmd"."Recipe"."Main_Page";
"T_Pulse_Recipe_Edit"(IN := "HMI_Variables_Cmd"."Recipe"."Main_Page" AND "HMI_Variables_Cmd"."Recipe"."Edit", PT := S5T#500ms); // TODO: Declarar "T_Pulse_Recipe_Edit" : TP; en VAR_STAT o VAR
IF "T_Pulse_Recipe_Edit".Q AND "T_Pulse_Recipe_Edit" THEN
"HMI_Variables_Cmd"."Recipe"."Edit" := FALSE;
END_IF;
IF "mAux_FP_M700_1" THEN
"HMI_Variables_Cmd"."Recipe"."Edit" := TRUE;
END_IF;

File diff suppressed because it is too large Load Diff

View File

@ -1132,6 +1132,390 @@ def process_call(instruction, network_id, scl_map, access_map):
return True
# --- Procesador de Temporizadores (TON, TOF) ---
def process_timer(instruction, network_id, scl_map, access_map):
"""
Genera SCL para Temporizadores (TON, TOF).
Requiere datos de instancia (DB o STAT).
"""
instr_uid = instruction["instruction_uid"]
instr_type = instruction["type"] # Será "TON" o "TOF"
if instr_type.endswith(SCL_SUFFIX) or "_error" in instr_type:
return False
# 1. Obtener Inputs
in_info = instruction["inputs"].get("IN") # Entrada booleana
pt_info = instruction["inputs"].get("PT") # Preset Time (Tipo TIME)
scl_in = get_scl_representation(in_info, network_id, scl_map, access_map)
scl_pt = get_scl_representation(pt_info, network_id, scl_map, access_map)
if scl_in is None or scl_pt is None:
return False # Dependencias no listas
# 2. Obtener Nombre de Instancia (NECESITA MEJORA EN x1.py)
instance_name = instruction.get("instance_db") # Reutilizar campo si x1 lo llena
if not instance_name:
# Generar placeholder si x1 no extrajo la instancia para Part
instance_name = f"#TIMER_INSTANCE_{instr_uid}" # Placeholder para VAR_TEMP o VAR_STAT
print(f"Advertencia: No se encontró instancia para {instr_type} UID {instr_uid}. Usando placeholder '{instance_name}'. Ajustar x1.py y declarar en x3.py.")
else:
instance_name = format_variable_name(instance_name) # Limpiar si viene de x1
# 3. Formatear entradas si son variables
scl_in_formatted = format_variable_name(scl_in) if in_info and in_info.get("type") == "variable" else scl_in
scl_pt_formatted = format_variable_name(scl_pt) if pt_info and pt_info.get("type") == "variable" else scl_pt
# 4. Generar la llamada SCL
# Nota: Las salidas Q y ET se acceden directamente desde la instancia.
scl_call = f"{instance_name}(IN := {scl_in_formatted}, PT := {scl_pt_formatted}); // TODO: Declarar {instance_name} : {instr_type}; en VAR_STAT o VAR"
instruction["scl"] = scl_call
instruction["type"] = instr_type + SCL_SUFFIX
# 5. Actualizar scl_map para las salidas Q y ET
map_key_q = (network_id, instr_uid, "Q")
scl_map[map_key_q] = f"{instance_name}.Q"
map_key_et = (network_id, instr_uid, "ET")
scl_map[map_key_et] = f"{instance_name}.ET"
# TON/TOF no tienen un pin ENO estándar en LAD/FBD que se mapee directamente
return True
# --- Procesador de Contadores (CTU, CTD, CTUD) ---
def process_counter(instruction, network_id, scl_map, access_map):
"""
Genera SCL para Contadores (CTU, CTD, CTUD).
Requiere datos de instancia (DB o STAT).
"""
instr_uid = instruction["instruction_uid"]
instr_type = instruction["type"] # CTU, CTD, CTUD
if instr_type.endswith(SCL_SUFFIX) or "_error" in instr_type:
return False
# 1. Obtener Inputs (varía según tipo)
params = []
resolved = True
input_pins = []
if instr_type == "CTU": input_pins = ["CU", "R", "PV"]
elif instr_type == "CTD": input_pins = ["CD", "LD", "PV"]
elif instr_type == "CTUD": input_pins = ["CU", "CD", "R", "LD", "PV"]
else:
instruction["scl"] = f"// ERROR: Tipo de contador no soportado: {instr_type}"
instruction["type"] += "_error"
return True # Procesado con error
for pin in input_pins:
pin_info = instruction["inputs"].get(pin)
if pin_info is None and pin not in ["R", "LD"]: # R y LD pueden no estar conectados
print(f"Error: Falta entrada requerida '{pin}' para {instr_type} UID {instr_uid}.")
# Permitir continuar si solo faltan R o LD opcionales? Por ahora no.
instruction["scl"] = f"// ERROR: Falta entrada requerida '{pin}' para {instr_type} UID {instr_uid}."
instruction["type"] += "_error"
return True # Error
elif pin_info: # Si el pin existe en el JSON
scl_pin = get_scl_representation(pin_info, network_id, scl_map, access_map)
if scl_pin is None:
resolved = False
break # Salir si una dependencia no está lista
scl_pin_formatted = format_variable_name(scl_pin) if pin_info.get("type") == "variable" else scl_pin
params.append(f"{pin} := {scl_pin_formatted}")
if not resolved: return False
# 2. Obtener Nombre de Instancia (NECESITA MEJORA EN x1.py)
instance_name = instruction.get("instance_db")
if not instance_name:
instance_name = f"#COUNTER_INSTANCE_{instr_uid}" # Placeholder
print(f"Advertencia: No se encontró instancia para {instr_type} UID {instr_uid}. Usando placeholder '{instance_name}'. Ajustar x1.py y declarar en x3.py.")
else:
instance_name = format_variable_name(instance_name)
# 3. Generar la llamada SCL
param_string = ", ".join(params)
scl_call = f"{instance_name}({param_string}); // TODO: Declarar {instance_name} : {instr_type}; en VAR_STAT o VAR"
instruction["scl"] = scl_call
instruction["type"] = instr_type + SCL_SUFFIX
# 4. Actualizar scl_map para las salidas (QU, QD, CV)
output_pins = []
if instr_type == "CTU": output_pins = ["QU", "CV"]
elif instr_type == "CTD": output_pins = ["QD", "CV"]
elif instr_type == "CTUD": output_pins = ["QU", "QD", "CV"]
for pin in output_pins:
map_key = (network_id, instr_uid, pin)
scl_map[map_key] = f"{instance_name}.{pin}"
# Contadores no tienen ENO estándar en LAD/FBD
return True
# --- Procesador de Comparadores (EQ ya existe, añadir otros) ---
def process_comparison(instruction, network_id, scl_map, access_map):
"""
Genera la expresión SCL para Comparadores (GT, LT, GE, LE, NE).
El resultado se propaga por scl_map['out'].
"""
instr_uid = instruction["instruction_uid"]
instr_type = instruction["type"] # GT, LT, GE, LE, NE
if instr_type.endswith(SCL_SUFFIX) or "_error" in instr_type:
return False
# Mapa de tipos a operadores SCL
op_map = {"GT": ">", "LT": "<", "GE": ">=", "LE": "<=", "NE": "<>"}
scl_operator = op_map.get(instr_type)
if not scl_operator:
instruction["scl"] = f"// ERROR: Tipo de comparación no soportado: {instr_type}"
instruction["type"] += "_error"
return True
# Obtener operandos
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 # 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 contienen espacios (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
comparison_scl = f"{op1} {scl_operator} {op2}"
# Guardar resultado en el mapa para 'out'
map_key_out = (network_id, instr_uid, "out")
scl_map[map_key_out] = f"({comparison_scl})" # Poner paréntesis por seguridad
# Manejar entrada 'pre'/RLO -> ENO (como en EQ)
pre_input = instruction["inputs"].get("pre") # Asumir 'pre' como en EQ
en_scl = get_scl_representation(pre_input, network_id, scl_map, access_map) if pre_input else "TRUE"
if en_scl is None:
return False # Dependencia 'pre'/'en' no lista
map_key_eno = (network_id, instr_uid, "eno")
scl_map[map_key_eno] = en_scl
instruction["scl"] = f"// Comparison {instr_type} {instr_uid}: {comparison_scl}"
instruction["type"] = instr_type + SCL_SUFFIX
return True
# --- Procesador de Matemáticas (ADD ya existe, añadir otros) ---
def process_math(instruction, network_id, scl_map, access_map):
"""
Genera SCL para operaciones matemáticas (SUB, MUL, DIV).
"""
instr_uid = instruction["instruction_uid"]
instr_type = instruction["type"] # SUB, MUL, DIV
if instr_type.endswith(SCL_SUFFIX) or "_error" in instr_type:
return False
# Mapa de tipos a operadores SCL
op_map = {"SUB": "-", "MUL": "*", "DIV": "/"}
scl_operator = op_map.get(instr_type)
if not scl_operator:
instruction["scl"] = f"// ERROR: Operación matemática no soportada: {instr_type}"
instruction["type"] += "_error"
return True
# Obtener EN, IN1, IN2
en_input = instruction["inputs"].get("en")
in1_info = instruction["inputs"].get("in1")
in2_info = instruction["inputs"].get("in2")
en_scl = get_scl_representation(en_input, network_id, scl_map, access_map) if en_input else "TRUE"
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 # Dependencias no listas
# Obtener destino 'out'
target_scl = get_target_scl_name(instruction, "out", network_id, default_to_temp=True)
if target_scl is None:
instruction["scl"] = f"// ERROR: {instr_type} {instr_uid} sin destino 'out'."
instruction["type"] += "_error"
return True
# 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 (especialmente para expresiones)
op1 = f"({op1})" if (" " in op1 or "+" in op1 or "-" in op1 or "*" in op1 or "/" in op1) and not op1.startswith("(") else op1
op2 = f"({op2})" if (" " in op2 or "+" in op2 or "-" in op2 or "*" in op2 or "/" in op2) and not op2.startswith("(") else op2
# Generar SCL
scl_core = f"{target_scl} := {op1} {scl_operator} {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
# Actualizar mapa SCL
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
# --- Procesador NOT ---
def process_not(instruction, network_id, scl_map, access_map):
"""Genera la expresión SCL para la inversión lógica NOT."""
instr_uid = instruction["instruction_uid"]
instr_type = instruction["type"] # Not
if instr_type.endswith(SCL_SUFFIX) or "_error" in instr_type:
return False
in_info = instruction["inputs"].get("in")
in_scl = get_scl_representation(in_info, network_id, scl_map, access_map)
if in_scl is None:
return False # Dependencia no lista
# Formatear entrada (añadir paréntesis si es complejo)
in_scl_formatted = in_scl
if (" " in in_scl or "AND" in in_scl or "OR" in in_scl) and not (in_scl.startswith("(") and in_scl.endswith(")")):
in_scl_formatted = f"({in_scl})"
result_scl = f"NOT {in_scl_formatted}"
# Guardar resultado en mapa para 'out'
map_key_out = (network_id, instr_uid, "out")
scl_map[map_key_out] = result_scl
instruction["scl"] = f"// Logic NOT {instr_uid}: {result_scl}"
instruction["type"] = instr_type + SCL_SUFFIX
# NOT no tiene EN/ENO explícito en LAD, modifica el RLO
return True
# EN x2_process.py, junto a otros procesadores
# --- Procesador para Se (Timer Pulse -> TP SCL) ---
def process_se(instruction, network_id, scl_map, access_map):
"""
Genera SCL para Temporizador de Pulso (Se -> TP).
Requiere datos de instancia (DB o STAT/TEMP).
"""
instr_uid = instruction["instruction_uid"]
instr_type = "Se" # Tipo original LAD
if instruction["type"].endswith(SCL_SUFFIX) or "_error" in instruction["type"]:
return False
# 1. Obtener Inputs: s (start), tv (time value)
# El pin 'r' (reset) no tiene equivalente directo en TP, se ignora aquí.
s_info = instruction["inputs"].get("s")
tv_info = instruction["inputs"].get("tv")
timer_instance_info = instruction["inputs"].get("timer") # Esperando que x1 lo extraiga
scl_s = get_scl_representation(s_info, network_id, scl_map, access_map)
scl_tv = get_scl_representation(tv_info, network_id, scl_map, access_map)
# Obtenemos el nombre de la variable instancia, crucial!
scl_instance_name = get_scl_representation(timer_instance_info, network_id, scl_map, access_map)
if scl_s is None or scl_tv is None:
return False # Dependencias no listas
# 2. Validar y obtener Nombre de Instancia
instance_name = None
if timer_instance_info and timer_instance_info.get("type") == "variable":
instance_name = scl_instance_name # Ya debería estar formateado por get_scl_repr
elif timer_instance_info: # Si está conectado pero no es variable directa? Raro.
print(f"Advertencia: Pin 'timer' de {instr_type} UID {instr_uid} conectado a algo inesperado: {timer_instance_info.get('type')}")
instance_name = f"#TP_INSTANCE_{instr_uid}" # Usar placeholder
else: # Si no hay pin 'timer' conectado (no debería pasar si x1 funciona)
instance_name = f"#TP_INSTANCE_{instr_uid}" # Usar placeholder
print(f"Advertencia: No se encontró conexión al pin 'timer' para {instr_type} UID {instr_uid}. Usando placeholder '{instance_name}'. ¡Revisar x1.py y XML!")
# 3. Formatear entradas si son variables (aunque get_scl_representation ya debería hacerlo)
scl_s_formatted = format_variable_name(scl_s) if s_info and s_info.get("type") == "variable" else scl_s
scl_tv_formatted = format_variable_name(scl_tv) if tv_info and tv_info.get("type") == "variable" else scl_tv
# 4. Generar la llamada SCL (TP usa IN, PT, Q, ET)
scl_call = f"{instance_name}(IN := {scl_s_formatted}, PT := {scl_tv_formatted}); // TODO: Declarar {instance_name} : TP; en VAR_STAT o VAR"
instruction["scl"] = scl_call
instruction["type"] = instr_type + SCL_SUFFIX
# 5. Actualizar scl_map usando los nombres de pin ORIGINALES mapeados si existen
output_pin_mapping_reverse = {v: k for k, v in instruction.get("_output_pin_mapping", {}).items()} # Necesitaríamos guardar el mapeo en x1
q_original_pin = "q" # Default
rt_original_pin = "rt" # Default
# Intentar encontrar los pines originales si x1 guardó el mapeo (MEJORA NECESARIA en x1)
# Por ahora, para SdCoil que mapeaba out->q, usaremos 'out' directamente
if instruction.get("type") == "Se_scl" and instruction.get("original_type") == "SdCoil": # Necesitamos guardar original_type en x1
q_original_pin = "out"
# rt no existe en SdCoil
map_key_q = (network_id, instr_uid, q_original_pin)
scl_map[map_key_q] = f"{instance_name}.Q"
if rt_original_pin: # Solo añadir rt si corresponde
map_key_rt = (network_id, instr_uid, rt_original_pin)
scl_map[map_key_rt] = f"{instance_name}.ET"
return True
# --- Procesador para Sd (On-Delay Timer -> TON SCL) ---
def process_sd(instruction, network_id, scl_map, access_map):
"""
Genera SCL para Temporizador On-Delay (Sd -> TON).
Requiere datos de instancia (DB o STAT/TEMP).
"""
instr_uid = instruction["instruction_uid"]
instr_type = "Sd" # Tipo original LAD
if instruction["type"].endswith(SCL_SUFFIX) or "_error" in instruction["type"]:
return False
# 1. Obtener Inputs: s (start), tv (time value)
# El pin 'r' (reset) no tiene equivalente directo en TON, se ignora aquí.
s_info = instruction["inputs"].get("s")
tv_info = instruction["inputs"].get("tv")
timer_instance_info = instruction["inputs"].get("timer") # Esperando que x1 lo extraiga
scl_s = get_scl_representation(s_info, network_id, scl_map, access_map)
scl_tv = get_scl_representation(tv_info, network_id, scl_map, access_map)
scl_instance_name = get_scl_representation(timer_instance_info, network_id, scl_map, access_map)
if scl_s is None or scl_tv is None:
return False # Dependencias no listas
# 2. Validar y obtener Nombre de Instancia
instance_name = None
if timer_instance_info and timer_instance_info.get("type") == "variable":
instance_name = scl_instance_name
elif timer_instance_info:
print(f"Advertencia: Pin 'timer' de {instr_type} UID {instr_uid} conectado a algo inesperado: {timer_instance_info.get('type')}")
instance_name = f"#TON_INSTANCE_{instr_uid}"
else:
instance_name = f"#TON_INSTANCE_{instr_uid}"
print(f"Advertencia: No se encontró conexión al pin 'timer' para {instr_type} UID {instr_uid}. Usando placeholder '{instance_name}'. ¡Revisar x1.py y XML!")
# 3. Formatear entradas si son variables
scl_s_formatted = format_variable_name(scl_s) if s_info and s_info.get("type") == "variable" else scl_s
scl_tv_formatted = format_variable_name(scl_tv) if tv_info and tv_info.get("type") == "variable" else scl_tv
# 4. Generar la llamada SCL (TON usa IN, PT, Q, ET)
scl_call = f"{instance_name}(IN := {scl_s_formatted}, PT := {scl_tv_formatted}); // TODO: Declarar {instance_name} : TON; en VAR_STAT o VAR"
instruction["scl"] = scl_call
instruction["type"] = instr_type + SCL_SUFFIX
# 5. Actualizar scl_map para las salidas Q y RT (mapeado a ET de TON)
map_key_q = (network_id, instr_uid, "q")
scl_map[map_key_q] = f"{instance_name}.Q"
map_key_rt = (network_id, instr_uid, "rt")
scl_map[map_key_rt] = f"{instance_name}.ET"
return True
# --- NUEVO: Procesador de Agrupación (Refinado) ---
def process_group_ifs(instruction, network_id, scl_map, access_map):
"""
@ -1289,7 +1673,6 @@ def process_group_ifs(instruction, network_id, scl_map, access_map):
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."""
@ -1356,21 +1739,27 @@ def process_json_to_scl(json_filepath):
# Lista y mapa de procesadores base
base_processors = [
process_convert,
process_mod,
process_eq,
process_contact,
process_o,
process_edge_detector,
process_add,
process_move,
process_call,
process_coil,
process_scoil, # <--- Añadir aquí
process_rcoil, # <--- Añadir aquí
process_blkmov, # El que añadimos antes
# ... otros procesadores base ...
]
process_convert,
process_mod,
process_eq,
process_contact,
process_o,
process_not, # <-- Nuevo
process_edge_detector,
process_comparison, # <-- Nuevo (para GT, LT, etc.)
process_add,
process_math, # <-- Nuevo (para SUB, MUL, DIV)
process_move,
process_timer, # <-- Nuevo
process_se, # <-- Añadido
process_sd, # <-- Añadido
process_counter, # <-- Nuevo
process_call,
process_coil,
process_scoil,
process_rcoil,
process_blkmov,
]
# Crear mapa por nombre de tipo original (en minúsculas)
processor_map = {}
for func in base_processors:
@ -1389,9 +1778,35 @@ def process_json_to_scl(json_filepath):
elif type_name == "scoil":
processor_map[type_name] = func
elif type_name == "rcoil":
processor_map[type_name] = func
else:
processor_map[type_name] = func
elif type_name == "se":
processor_map["se"] = func
processor_map["sdcoil"] = func # Mapear SdCoil a process_se basado en análisis
elif type_name == "sd":
processor_map["sd"] = func
elif type_name == "timer":
processor_map["ton"] = func # Mapear TON al procesador de timer
processor_map["tof"] = func # Mapear TOF al procesador de timer
elif type_name == "counter":
processor_map["ctu"] = func
processor_map["ctd"] = func
processor_map["ctud"] = func
elif type_name == "comparison":
processor_map["gt"] = func
processor_map["lt"] = func
processor_map["ge"] = func
processor_map["le"] = func
processor_map["ne"] = func
# EQ ya tiene su propio procesador (process_eq), así que no lo añadimos aquí.
elif type_name == "math":
processor_map["sub"] = func
processor_map["mul"] = func
processor_map["div"] = func
# ADD ya tiene su propio procesador (process_add)
elif type_name == "not":
processor_map["not"] = func # Mapear 'not'
elif type_name not in processor_map:
processor_map[type_name] = func
print("\n--- Iniciando Bucle de Procesamiento Iterativo ---")
while passes < max_passes and not processing_complete: