Segunda version
This commit is contained in:
parent
06da71cd46
commit
694df87089
|
@ -2,11 +2,52 @@
|
||||||
"block_name": "BlenderRun_ProdTime",
|
"block_name": "BlenderRun_ProdTime",
|
||||||
"block_number": 2040,
|
"block_number": 2040,
|
||||||
"language": "LAD",
|
"language": "LAD",
|
||||||
"interface": {},
|
"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": [
|
"networks": [
|
||||||
{
|
{
|
||||||
"id": "9",
|
"id": "9",
|
||||||
"title": "",
|
"title": "Seconds",
|
||||||
"logic": [
|
"logic": [
|
||||||
{
|
{
|
||||||
"instruction_uid": "26",
|
"instruction_uid": "26",
|
||||||
|
@ -15,7 +56,8 @@
|
||||||
"operand": {
|
"operand": {
|
||||||
"uid": "21",
|
"uid": "21",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"Procedure_Variables\".\"Blender_Run\".\"Running\""
|
||||||
},
|
},
|
||||||
"in": {
|
"in": {
|
||||||
"type": "powerrail"
|
"type": "powerrail"
|
||||||
|
@ -30,7 +72,8 @@
|
||||||
"operand": {
|
"operand": {
|
||||||
"uid": "22",
|
"uid": "22",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"CLK_1.0S\""
|
||||||
},
|
},
|
||||||
"in": {
|
"in": {
|
||||||
"type": "connection",
|
"type": "connection",
|
||||||
|
@ -48,12 +91,15 @@
|
||||||
"in1": {
|
"in1": {
|
||||||
"uid": "23",
|
"uid": "23",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"Blender_Variables_Pers\".\"gSLIM_Sec\""
|
||||||
},
|
},
|
||||||
"in2": {
|
"in2": {
|
||||||
"uid": "24",
|
"uid": "24",
|
||||||
"scope": "LiteralConstant",
|
"scope": "LiteralConstant",
|
||||||
"type": "unknown_access"
|
"type": "constant",
|
||||||
|
"datatype": "Int",
|
||||||
|
"value": 1
|
||||||
},
|
},
|
||||||
"en": {
|
"en": {
|
||||||
"type": "connection",
|
"type": "connection",
|
||||||
|
@ -67,7 +113,8 @@
|
||||||
{
|
{
|
||||||
"uid": "25",
|
"uid": "25",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"Blender_Variables_Pers\".\"gSLIM_Sec\""
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -76,7 +123,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "1A",
|
"id": "1A",
|
||||||
"title": "",
|
"title": "Reset Hours",
|
||||||
"logic": [
|
"logic": [
|
||||||
{
|
{
|
||||||
"instruction_uid": "24",
|
"instruction_uid": "24",
|
||||||
|
@ -85,7 +132,8 @@
|
||||||
"operand": {
|
"operand": {
|
||||||
"uid": "21",
|
"uid": "21",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"SLIM_Variables\".\"ResetHour\""
|
||||||
},
|
},
|
||||||
"in": {
|
"in": {
|
||||||
"type": "powerrail"
|
"type": "powerrail"
|
||||||
|
@ -100,7 +148,9 @@
|
||||||
"in": {
|
"in": {
|
||||||
"uid": "22",
|
"uid": "22",
|
||||||
"scope": "LiteralConstant",
|
"scope": "LiteralConstant",
|
||||||
"type": "unknown_access"
|
"type": "constant",
|
||||||
|
"datatype": "Int",
|
||||||
|
"value": 0
|
||||||
},
|
},
|
||||||
"en": {
|
"en": {
|
||||||
"type": "connection",
|
"type": "connection",
|
||||||
|
@ -114,7 +164,8 @@
|
||||||
{
|
{
|
||||||
"uid": "23",
|
"uid": "23",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"Blender_Variables_Pers\".\"gSLIM_Sec\""
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -123,7 +174,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "2B",
|
"id": "2B",
|
||||||
"title": "",
|
"title": "Seconds Counter",
|
||||||
"logic": [
|
"logic": [
|
||||||
{
|
{
|
||||||
"instruction_uid": "26",
|
"instruction_uid": "26",
|
||||||
|
@ -132,7 +183,8 @@
|
||||||
"operand": {
|
"operand": {
|
||||||
"uid": "21",
|
"uid": "21",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"gBlenderBlending\""
|
||||||
},
|
},
|
||||||
"in": {
|
"in": {
|
||||||
"type": "powerrail"
|
"type": "powerrail"
|
||||||
|
@ -147,7 +199,8 @@
|
||||||
"operand": {
|
"operand": {
|
||||||
"uid": "22",
|
"uid": "22",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"CLK_1.0S\""
|
||||||
},
|
},
|
||||||
"in": {
|
"in": {
|
||||||
"type": "connection",
|
"type": "connection",
|
||||||
|
@ -165,12 +218,15 @@
|
||||||
"in1": {
|
"in1": {
|
||||||
"uid": "23",
|
"uid": "23",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"Blender_Variables_Pers\".\"gProdSec\""
|
||||||
},
|
},
|
||||||
"in2": {
|
"in2": {
|
||||||
"uid": "24",
|
"uid": "24",
|
||||||
"scope": "LiteralConstant",
|
"scope": "LiteralConstant",
|
||||||
"type": "unknown_access"
|
"type": "constant",
|
||||||
|
"datatype": "Int",
|
||||||
|
"value": 1
|
||||||
},
|
},
|
||||||
"en": {
|
"en": {
|
||||||
"type": "connection",
|
"type": "connection",
|
||||||
|
@ -184,7 +240,8 @@
|
||||||
{
|
{
|
||||||
"uid": "25",
|
"uid": "25",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"Blender_Variables_Pers\".\"gProdSec\""
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -193,7 +250,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "3C",
|
"id": "3C",
|
||||||
"title": "",
|
"title": "Minute",
|
||||||
"logic": [
|
"logic": [
|
||||||
{
|
{
|
||||||
"instruction_uid": "24",
|
"instruction_uid": "24",
|
||||||
|
@ -202,12 +259,15 @@
|
||||||
"in1": {
|
"in1": {
|
||||||
"uid": "21",
|
"uid": "21",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"Blender_Variables_Pers\".\"gProdSec\""
|
||||||
},
|
},
|
||||||
"in2": {
|
"in2": {
|
||||||
"uid": "22",
|
"uid": "22",
|
||||||
"scope": "LiteralConstant",
|
"scope": "LiteralConstant",
|
||||||
"type": "unknown_access"
|
"type": "constant",
|
||||||
|
"datatype": "Int",
|
||||||
|
"value": 60
|
||||||
},
|
},
|
||||||
"pre": {
|
"pre": {
|
||||||
"type": "powerrail"
|
"type": "powerrail"
|
||||||
|
@ -228,7 +288,8 @@
|
||||||
"operand": {
|
"operand": {
|
||||||
"uid": "23",
|
"uid": "23",
|
||||||
"scope": "LocalVariable",
|
"scope": "LocalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"m1MinONS\""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": {}
|
"outputs": {}
|
||||||
|
@ -237,7 +298,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "4D",
|
"id": "4D",
|
||||||
"title": "",
|
"title": "Minute Counter",
|
||||||
"logic": [
|
"logic": [
|
||||||
{
|
{
|
||||||
"instruction_uid": "27",
|
"instruction_uid": "27",
|
||||||
|
@ -246,7 +307,8 @@
|
||||||
"operand": {
|
"operand": {
|
||||||
"uid": "21",
|
"uid": "21",
|
||||||
"scope": "LocalVariable",
|
"scope": "LocalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"m1MinONS\""
|
||||||
},
|
},
|
||||||
"in": {
|
"in": {
|
||||||
"type": "powerrail"
|
"type": "powerrail"
|
||||||
|
@ -261,7 +323,9 @@
|
||||||
"in": {
|
"in": {
|
||||||
"uid": "22",
|
"uid": "22",
|
||||||
"scope": "LiteralConstant",
|
"scope": "LiteralConstant",
|
||||||
"type": "unknown_access"
|
"type": "constant",
|
||||||
|
"datatype": "Int",
|
||||||
|
"value": 0
|
||||||
},
|
},
|
||||||
"en": {
|
"en": {
|
||||||
"type": "connection",
|
"type": "connection",
|
||||||
|
@ -275,7 +339,8 @@
|
||||||
{
|
{
|
||||||
"uid": "23",
|
"uid": "23",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"Blender_Variables_Pers\".\"gProdSec\""
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -287,12 +352,15 @@
|
||||||
"in1": {
|
"in1": {
|
||||||
"uid": "24",
|
"uid": "24",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"Blender_Variables_Pers\".\"gProdMin\""
|
||||||
},
|
},
|
||||||
"in2": {
|
"in2": {
|
||||||
"uid": "25",
|
"uid": "25",
|
||||||
"scope": "LiteralConstant",
|
"scope": "LiteralConstant",
|
||||||
"type": "unknown_access"
|
"type": "constant",
|
||||||
|
"datatype": "Int",
|
||||||
|
"value": 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": {
|
"outputs": {
|
||||||
|
@ -300,7 +368,8 @@
|
||||||
{
|
{
|
||||||
"uid": "26",
|
"uid": "26",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"Blender_Variables_Pers\".\"gProdMin\""
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -309,7 +378,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "5E",
|
"id": "5E",
|
||||||
"title": "",
|
"title": "Hour",
|
||||||
"logic": [
|
"logic": [
|
||||||
{
|
{
|
||||||
"instruction_uid": "24",
|
"instruction_uid": "24",
|
||||||
|
@ -318,12 +387,15 @@
|
||||||
"in1": {
|
"in1": {
|
||||||
"uid": "21",
|
"uid": "21",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"Blender_Variables_Pers\".\"gProdMin\""
|
||||||
},
|
},
|
||||||
"in2": {
|
"in2": {
|
||||||
"uid": "22",
|
"uid": "22",
|
||||||
"scope": "LiteralConstant",
|
"scope": "LiteralConstant",
|
||||||
"type": "unknown_access"
|
"type": "constant",
|
||||||
|
"datatype": "Int",
|
||||||
|
"value": 60
|
||||||
},
|
},
|
||||||
"pre": {
|
"pre": {
|
||||||
"type": "powerrail"
|
"type": "powerrail"
|
||||||
|
@ -344,7 +416,8 @@
|
||||||
"operand": {
|
"operand": {
|
||||||
"uid": "23",
|
"uid": "23",
|
||||||
"scope": "LocalVariable",
|
"scope": "LocalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"m1HourONS\""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": {}
|
"outputs": {}
|
||||||
|
@ -353,7 +426,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "6F",
|
"id": "6F",
|
||||||
"title": "",
|
"title": "Hour Counter",
|
||||||
"logic": [
|
"logic": [
|
||||||
{
|
{
|
||||||
"instruction_uid": "30",
|
"instruction_uid": "30",
|
||||||
|
@ -362,7 +435,8 @@
|
||||||
"operand": {
|
"operand": {
|
||||||
"uid": "21",
|
"uid": "21",
|
||||||
"scope": "LocalVariable",
|
"scope": "LocalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"m1HourONS\""
|
||||||
},
|
},
|
||||||
"in": {
|
"in": {
|
||||||
"type": "powerrail"
|
"type": "powerrail"
|
||||||
|
@ -377,7 +451,9 @@
|
||||||
"in": {
|
"in": {
|
||||||
"uid": "22",
|
"uid": "22",
|
||||||
"scope": "LiteralConstant",
|
"scope": "LiteralConstant",
|
||||||
"type": "unknown_access"
|
"type": "constant",
|
||||||
|
"datatype": "Int",
|
||||||
|
"value": 0
|
||||||
},
|
},
|
||||||
"en": {
|
"en": {
|
||||||
"type": "connection",
|
"type": "connection",
|
||||||
|
@ -391,7 +467,8 @@
|
||||||
{
|
{
|
||||||
"uid": "23",
|
"uid": "23",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"Blender_Variables_Pers\".\"gProdMin\""
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -403,12 +480,15 @@
|
||||||
"in1": {
|
"in1": {
|
||||||
"uid": "24",
|
"uid": "24",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"Blender_Variables_Pers\".\"gProdHour\""
|
||||||
},
|
},
|
||||||
"in2": {
|
"in2": {
|
||||||
"uid": "25",
|
"uid": "25",
|
||||||
"scope": "LiteralConstant",
|
"scope": "LiteralConstant",
|
||||||
"type": "unknown_access"
|
"type": "constant",
|
||||||
|
"datatype": "Int",
|
||||||
|
"value": 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": {
|
"outputs": {
|
||||||
|
@ -416,7 +496,8 @@
|
||||||
{
|
{
|
||||||
"uid": "26",
|
"uid": "26",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"Blender_Variables_Pers\".\"gProdHour\""
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -428,12 +509,15 @@
|
||||||
"in1": {
|
"in1": {
|
||||||
"uid": "27",
|
"uid": "27",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"Blender_Variables_Pers\".\"gBlendingMaintHour\""
|
||||||
},
|
},
|
||||||
"in2": {
|
"in2": {
|
||||||
"uid": "28",
|
"uid": "28",
|
||||||
"scope": "LiteralConstant",
|
"scope": "LiteralConstant",
|
||||||
"type": "unknown_access"
|
"type": "constant",
|
||||||
|
"datatype": "Int",
|
||||||
|
"value": 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": {
|
"outputs": {
|
||||||
|
@ -441,7 +525,8 @@
|
||||||
{
|
{
|
||||||
"uid": "29",
|
"uid": "29",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"Blender_Variables_Pers\".\"gBlendingMaintHour\""
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -450,7 +535,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "80",
|
"id": "80",
|
||||||
"title": "",
|
"title": "Counter reset",
|
||||||
"logic": [
|
"logic": [
|
||||||
{
|
{
|
||||||
"instruction_uid": "29",
|
"instruction_uid": "29",
|
||||||
|
@ -459,7 +544,8 @@
|
||||||
"operand": {
|
"operand": {
|
||||||
"uid": "21",
|
"uid": "21",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"gBlenderCIPMode\""
|
||||||
},
|
},
|
||||||
"in": {
|
"in": {
|
||||||
"type": "powerrail"
|
"type": "powerrail"
|
||||||
|
@ -474,7 +560,8 @@
|
||||||
"operand": {
|
"operand": {
|
||||||
"uid": "22",
|
"uid": "22",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"gBlenderRinseMode\""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": {}
|
"outputs": {}
|
||||||
|
@ -505,7 +592,9 @@
|
||||||
"in": {
|
"in": {
|
||||||
"uid": "23",
|
"uid": "23",
|
||||||
"scope": "LiteralConstant",
|
"scope": "LiteralConstant",
|
||||||
"type": "unknown_access"
|
"type": "constant",
|
||||||
|
"datatype": "Int",
|
||||||
|
"value": 0
|
||||||
},
|
},
|
||||||
"en": {
|
"en": {
|
||||||
"type": "connection",
|
"type": "connection",
|
||||||
|
@ -519,7 +608,8 @@
|
||||||
{
|
{
|
||||||
"uid": "24",
|
"uid": "24",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"Blender_Variables_Pers\".\"gProdSec\""
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -531,7 +621,9 @@
|
||||||
"in": {
|
"in": {
|
||||||
"uid": "25",
|
"uid": "25",
|
||||||
"scope": "LiteralConstant",
|
"scope": "LiteralConstant",
|
||||||
"type": "unknown_access"
|
"type": "constant",
|
||||||
|
"datatype": "Int",
|
||||||
|
"value": 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": {
|
"outputs": {
|
||||||
|
@ -539,7 +631,8 @@
|
||||||
{
|
{
|
||||||
"uid": "26",
|
"uid": "26",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"Blender_Variables_Pers\".\"gProdMin\""
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -551,7 +644,9 @@
|
||||||
"in": {
|
"in": {
|
||||||
"uid": "27",
|
"uid": "27",
|
||||||
"scope": "LiteralConstant",
|
"scope": "LiteralConstant",
|
||||||
"type": "unknown_access"
|
"type": "constant",
|
||||||
|
"datatype": "Int",
|
||||||
|
"value": 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": {
|
"outputs": {
|
||||||
|
@ -559,7 +654,8 @@
|
||||||
{
|
{
|
||||||
"uid": "28",
|
"uid": "28",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"Blender_Variables_Pers\".\"gProdHour\""
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -568,7 +664,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "91",
|
"id": "91",
|
||||||
"title": "",
|
"title": "Running Seconds",
|
||||||
"logic": [
|
"logic": [
|
||||||
{
|
{
|
||||||
"instruction_uid": "26",
|
"instruction_uid": "26",
|
||||||
|
@ -577,7 +673,8 @@
|
||||||
"operand": {
|
"operand": {
|
||||||
"uid": "21",
|
"uid": "21",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"Procedure_Variables\".\"Blender_Run\".\"Running\""
|
||||||
},
|
},
|
||||||
"in": {
|
"in": {
|
||||||
"type": "powerrail"
|
"type": "powerrail"
|
||||||
|
@ -592,7 +689,8 @@
|
||||||
"operand": {
|
"operand": {
|
||||||
"uid": "22",
|
"uid": "22",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"CLK_1.0S\""
|
||||||
},
|
},
|
||||||
"in": {
|
"in": {
|
||||||
"type": "connection",
|
"type": "connection",
|
||||||
|
@ -610,12 +708,15 @@
|
||||||
"in1": {
|
"in1": {
|
||||||
"uid": "23",
|
"uid": "23",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"Blender_Variables_Pers\".\"gRunningSeconds\""
|
||||||
},
|
},
|
||||||
"in2": {
|
"in2": {
|
||||||
"uid": "24",
|
"uid": "24",
|
||||||
"scope": "LiteralConstant",
|
"scope": "LiteralConstant",
|
||||||
"type": "unknown_access"
|
"type": "constant",
|
||||||
|
"datatype": "Int",
|
||||||
|
"value": 1
|
||||||
},
|
},
|
||||||
"en": {
|
"en": {
|
||||||
"type": "connection",
|
"type": "connection",
|
||||||
|
@ -629,7 +730,8 @@
|
||||||
{
|
{
|
||||||
"uid": "25",
|
"uid": "25",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"Blender_Variables_Pers\".\"gRunningSeconds\""
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -638,7 +740,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "A2",
|
"id": "A2",
|
||||||
"title": "",
|
"title": "Running Minutes",
|
||||||
"logic": [
|
"logic": [
|
||||||
{
|
{
|
||||||
"instruction_uid": "35",
|
"instruction_uid": "35",
|
||||||
|
@ -647,7 +749,8 @@
|
||||||
"in": {
|
"in": {
|
||||||
"uid": "21",
|
"uid": "21",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"Blender_Variables_Pers\".\"gRunningSeconds\""
|
||||||
},
|
},
|
||||||
"en": {
|
"en": {
|
||||||
"type": "powerrail"
|
"type": "powerrail"
|
||||||
|
@ -658,7 +761,8 @@
|
||||||
{
|
{
|
||||||
"uid": "22",
|
"uid": "22",
|
||||||
"scope": "LocalVariable",
|
"scope": "LocalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"I_DIRunning_sec\""
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -676,12 +780,15 @@
|
||||||
"in1": {
|
"in1": {
|
||||||
"uid": "23",
|
"uid": "23",
|
||||||
"scope": "LocalVariable",
|
"scope": "LocalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"I_DIRunning_sec\""
|
||||||
},
|
},
|
||||||
"in2": {
|
"in2": {
|
||||||
"uid": "24",
|
"uid": "24",
|
||||||
"scope": "TypedConstant",
|
"scope": "TypedConstant",
|
||||||
"type": "unknown_access"
|
"type": "constant",
|
||||||
|
"datatype": "Unknown",
|
||||||
|
"value": "DINT#60"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": {
|
"outputs": {
|
||||||
|
@ -689,7 +796,8 @@
|
||||||
{
|
{
|
||||||
"uid": "25",
|
"uid": "25",
|
||||||
"scope": "LocalVariable",
|
"scope": "LocalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"MOD60\""
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -707,12 +815,15 @@
|
||||||
"in1": {
|
"in1": {
|
||||||
"uid": "26",
|
"uid": "26",
|
||||||
"scope": "LocalVariable",
|
"scope": "LocalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"MOD60\""
|
||||||
},
|
},
|
||||||
"in2": {
|
"in2": {
|
||||||
"uid": "27",
|
"uid": "27",
|
||||||
"scope": "TypedConstant",
|
"scope": "TypedConstant",
|
||||||
"type": "unknown_access"
|
"type": "constant",
|
||||||
|
"datatype": "Unknown",
|
||||||
|
"value": "DINT#0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": {}
|
"outputs": {}
|
||||||
|
@ -730,7 +841,8 @@
|
||||||
"operand": {
|
"operand": {
|
||||||
"uid": "28",
|
"uid": "28",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"Procedure_Variables\".\"Blender_Run\".\"Running\""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": {}
|
"outputs": {}
|
||||||
|
@ -742,7 +854,8 @@
|
||||||
"operand": {
|
"operand": {
|
||||||
"uid": "29",
|
"uid": "29",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"CLK_1.0S\""
|
||||||
},
|
},
|
||||||
"in": {
|
"in": {
|
||||||
"type": "connection",
|
"type": "connection",
|
||||||
|
@ -760,12 +873,15 @@
|
||||||
"in1": {
|
"in1": {
|
||||||
"uid": "30",
|
"uid": "30",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"Blender_Variables_Pers\".\"gRunningMinutes\""
|
||||||
},
|
},
|
||||||
"in2": {
|
"in2": {
|
||||||
"uid": "31",
|
"uid": "31",
|
||||||
"scope": "LiteralConstant",
|
"scope": "LiteralConstant",
|
||||||
"type": "unknown_access"
|
"type": "constant",
|
||||||
|
"datatype": "Int",
|
||||||
|
"value": 1
|
||||||
},
|
},
|
||||||
"en": {
|
"en": {
|
||||||
"type": "connection",
|
"type": "connection",
|
||||||
|
@ -779,7 +895,8 @@
|
||||||
{
|
{
|
||||||
"uid": "32",
|
"uid": "32",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"Blender_Variables_Pers\".\"gRunningMinutes\""
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -791,7 +908,8 @@
|
||||||
"bit": {
|
"bit": {
|
||||||
"uid": "33",
|
"uid": "33",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"M19012\""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": {}
|
"outputs": {}
|
||||||
|
@ -809,7 +927,8 @@
|
||||||
"operand": {
|
"operand": {
|
||||||
"uid": "34",
|
"uid": "34",
|
||||||
"scope": "LocalVariable",
|
"scope": "LocalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"mRunMin\""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": {}
|
"outputs": {}
|
||||||
|
@ -818,7 +937,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "B3",
|
"id": "B3",
|
||||||
"title": "",
|
"title": "Running Hours for Maintenance",
|
||||||
"logic": [
|
"logic": [
|
||||||
{
|
{
|
||||||
"instruction_uid": "32",
|
"instruction_uid": "32",
|
||||||
|
@ -827,7 +946,8 @@
|
||||||
"operand": {
|
"operand": {
|
||||||
"uid": "21",
|
"uid": "21",
|
||||||
"scope": "LocalVariable",
|
"scope": "LocalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"mRunMin\""
|
||||||
},
|
},
|
||||||
"in": {
|
"in": {
|
||||||
"type": "powerrail"
|
"type": "powerrail"
|
||||||
|
@ -842,7 +962,8 @@
|
||||||
"in": {
|
"in": {
|
||||||
"uid": "22",
|
"uid": "22",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"Blender_Variables_Pers\".\"gRunningMinutes\""
|
||||||
},
|
},
|
||||||
"en": {
|
"en": {
|
||||||
"type": "connection",
|
"type": "connection",
|
||||||
|
@ -856,7 +977,8 @@
|
||||||
{
|
{
|
||||||
"uid": "23",
|
"uid": "23",
|
||||||
"scope": "LocalVariable",
|
"scope": "LocalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"I_DIRunning_min\""
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -874,12 +996,15 @@
|
||||||
"in1": {
|
"in1": {
|
||||||
"uid": "24",
|
"uid": "24",
|
||||||
"scope": "LocalVariable",
|
"scope": "LocalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"I_DIRunning_min\""
|
||||||
},
|
},
|
||||||
"in2": {
|
"in2": {
|
||||||
"uid": "25",
|
"uid": "25",
|
||||||
"scope": "TypedConstant",
|
"scope": "TypedConstant",
|
||||||
"type": "unknown_access"
|
"type": "constant",
|
||||||
|
"datatype": "Unknown",
|
||||||
|
"value": "DINT#60"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": {
|
"outputs": {
|
||||||
|
@ -887,7 +1012,8 @@
|
||||||
{
|
{
|
||||||
"uid": "26",
|
"uid": "26",
|
||||||
"scope": "LocalVariable",
|
"scope": "LocalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"MOD60\""
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -905,12 +1031,15 @@
|
||||||
"in1": {
|
"in1": {
|
||||||
"uid": "27",
|
"uid": "27",
|
||||||
"scope": "LocalVariable",
|
"scope": "LocalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"MOD60\""
|
||||||
},
|
},
|
||||||
"in2": {
|
"in2": {
|
||||||
"uid": "28",
|
"uid": "28",
|
||||||
"scope": "TypedConstant",
|
"scope": "TypedConstant",
|
||||||
"type": "unknown_access"
|
"type": "constant",
|
||||||
|
"datatype": "Unknown",
|
||||||
|
"value": "DINT#0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": {}
|
"outputs": {}
|
||||||
|
@ -928,12 +1057,15 @@
|
||||||
"in1": {
|
"in1": {
|
||||||
"uid": "29",
|
"uid": "29",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"Blender_Variables_Pers\".\"gRunningMaintHour\""
|
||||||
},
|
},
|
||||||
"in2": {
|
"in2": {
|
||||||
"uid": "30",
|
"uid": "30",
|
||||||
"scope": "LiteralConstant",
|
"scope": "LiteralConstant",
|
||||||
"type": "unknown_access"
|
"type": "constant",
|
||||||
|
"datatype": "Int",
|
||||||
|
"value": 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": {
|
"outputs": {
|
||||||
|
@ -941,7 +1073,8 @@
|
||||||
{
|
{
|
||||||
"uid": "31",
|
"uid": "31",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"Blender_Variables_Pers\".\"gRunningMaintHour\""
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -950,7 +1083,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "C4",
|
"id": "C4",
|
||||||
"title": "",
|
"title": "Running Hours for Maintenance",
|
||||||
"logic": [
|
"logic": [
|
||||||
{
|
{
|
||||||
"instruction_uid": "23",
|
"instruction_uid": "23",
|
||||||
|
@ -959,7 +1092,8 @@
|
||||||
"in": {
|
"in": {
|
||||||
"uid": "21",
|
"uid": "21",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"Blender_Variables_Pers\".\"gRunningMaintHour\""
|
||||||
},
|
},
|
||||||
"en": {
|
"en": {
|
||||||
"type": "powerrail"
|
"type": "powerrail"
|
||||||
|
@ -970,7 +1104,8 @@
|
||||||
{
|
{
|
||||||
"uid": "22",
|
"uid": "22",
|
||||||
"scope": "GlobalVariable",
|
"scope": "GlobalVariable",
|
||||||
"type": "unknown_access"
|
"type": "variable",
|
||||||
|
"name": "\"HMI_Variables_Status\".\"System\".\"BlendingMaintHour\""
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
283
to_jason.py
283
to_jason.py
|
@ -1,283 +0,0 @@
|
||||||
import json
|
|
||||||
import os
|
|
||||||
from lxml import etree
|
|
||||||
|
|
||||||
# --- Namespaces ---
|
|
||||||
# Define los namespaces con prefijos explícitos. Quitamos 'default'.
|
|
||||||
ns = {
|
|
||||||
'sw': 'http://www.siemens.com/automation/Openness/SW/Interface/v5',
|
|
||||||
'flg': 'http://www.siemens.com/automation/Openness/SW/NetworkSource/FlgNet/v4'
|
|
||||||
# No incluimos un prefijo para elementos sin namespace o en el namespace por defecto
|
|
||||||
}
|
|
||||||
|
|
||||||
# --- Helper Functions ---
|
|
||||||
|
|
||||||
def get_multilingual_text(element, default_lang='en-US', fallback_lang='it-IT'):
|
|
||||||
"""Intenta extraer texto de un MultilingualText, priorizando idiomas."""
|
|
||||||
if element is None:
|
|
||||||
return ""
|
|
||||||
try:
|
|
||||||
# Accedemos a los elementos sin prefijo directamente
|
|
||||||
text_item = element.xpath(f".//MultilingualTextItem[AttributeList/Culture='{default_lang}']/AttributeList/Text", namespaces=ns)
|
|
||||||
if text_item:
|
|
||||||
return text_item[0].text.strip() if text_item[0].text else ""
|
|
||||||
|
|
||||||
text_item = element.xpath(f".//MultilingualTextItem[AttributeList/Culture='{fallback_lang}']/AttributeList/Text", namespaces=ns)
|
|
||||||
if text_item:
|
|
||||||
return text_item[0].text.strip() if text_item[0].text else ""
|
|
||||||
|
|
||||||
text_item = element.xpath(".//MultilingualTextItem/AttributeList/Text", namespaces=ns)
|
|
||||||
if text_item:
|
|
||||||
return text_item[0].text.strip() if text_item[0].text else ""
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Advertencia: Error extrayendo MultilingualText: {e}")
|
|
||||||
pass
|
|
||||||
return ""
|
|
||||||
|
|
||||||
def get_symbol_name(symbol_element):
|
|
||||||
"""Construye el nombre completo del símbolo a partir de sus componentes."""
|
|
||||||
if symbol_element is None:
|
|
||||||
return None
|
|
||||||
# Accedemos a Component sin prefijo
|
|
||||||
components = symbol_element.xpath("./Component/@Name")
|
|
||||||
return ".".join(f'"{c}"' if ' ' in c else c for c in components)
|
|
||||||
|
|
||||||
def parse_access(access_element):
|
|
||||||
"""Parsea un elemento Access para obtener información de variable o constante."""
|
|
||||||
info = {
|
|
||||||
'uid': access_element.get('UId'),
|
|
||||||
'scope': access_element.get('Scope')
|
|
||||||
}
|
|
||||||
# Accedemos a Symbol y Constant sin prefijo
|
|
||||||
symbol = access_element.xpath("./Symbol", namespaces=ns)
|
|
||||||
constant = access_element.xpath("./Constant", namespaces=ns)
|
|
||||||
|
|
||||||
if symbol:
|
|
||||||
info['type'] = 'variable'
|
|
||||||
info['name'] = get_symbol_name(symbol[0])
|
|
||||||
elif constant:
|
|
||||||
# Los hijos de Constant tampoco tienen prefijo aparente
|
|
||||||
const_type_elem = constant[0].xpath("./ConstantType", namespaces=ns)
|
|
||||||
const_val_elem = constant[0].xpath("./ConstantValue", namespaces=ns)
|
|
||||||
info['datatype'] = const_type_elem[0].text if const_type_elem else 'Unknown'
|
|
||||||
info['value_str'] = const_val_elem[0].text if const_val_elem else None # Guardamos original
|
|
||||||
info['value'] = info['value_str'] # Valor procesado
|
|
||||||
info['type'] = 'constant'
|
|
||||||
|
|
||||||
# Intenta convertir el valor si es numérico o booleano
|
|
||||||
if info['value'] is not None:
|
|
||||||
if info['datatype'].lower() in ['int', 'dint', 'udint', 'sint', 'usint', 'lint', 'ulint', 'word', 'dword', 'lword']:
|
|
||||||
# Manejar DINT#60, etc.
|
|
||||||
val_str = info['value'].split('#')[-1] if '#' in info['value'] else info['value']
|
|
||||||
try:
|
|
||||||
info['value'] = int(val_str)
|
|
||||||
except (ValueError, TypeError):
|
|
||||||
info['value'] = info['value_str'] # Mantener como string si falla
|
|
||||||
elif info['datatype'].lower() == 'bool':
|
|
||||||
info['value'] = info['value'].lower() == 'true' or info['value'] == '1'
|
|
||||||
elif info['datatype'].lower() in ['real', 'lreal']:
|
|
||||||
try:
|
|
||||||
info['value'] = float(info['value'])
|
|
||||||
except (ValueError, TypeError):
|
|
||||||
info['value'] = info['value_str'] # Mantener como string si falla
|
|
||||||
# Añadir más conversiones de tipos si es necesario
|
|
||||||
else:
|
|
||||||
# Podría ser TypedConstant, que también tiene un <Constant> dentro
|
|
||||||
# Si llegamos aquí, es algo inesperado
|
|
||||||
info['type'] = 'unknown_access'
|
|
||||||
|
|
||||||
return info
|
|
||||||
|
|
||||||
|
|
||||||
def parse_part(part_element):
|
|
||||||
"""Parsea un elemento Part (instrucción)."""
|
|
||||||
return {
|
|
||||||
'uid': part_element.get('UId'),
|
|
||||||
'name': part_element.get('Name'),
|
|
||||||
# TemplateValue no parece tener prefijo
|
|
||||||
'template_values': {tv.get('Name'): tv.get('Type')
|
|
||||||
for tv in part_element.xpath("./TemplateValue", namespaces=ns)}
|
|
||||||
}
|
|
||||||
|
|
||||||
# --- Main Parsing Logic ---
|
|
||||||
|
|
||||||
def parse_network(network_element):
|
|
||||||
"""Parsea una red (CompileUnit) y extrae su lógica simplificada."""
|
|
||||||
network_logic = []
|
|
||||||
network_id = network_element.get('ID')
|
|
||||||
# Accedemos a ObjectList y MultilingualText sin prefijo
|
|
||||||
title_element = network_element.xpath("./ObjectList/MultilingualText[@CompositionName='Title']", namespaces=ns)
|
|
||||||
network_title = get_multilingual_text(title_element[0]) if title_element else f"Network {network_id}"
|
|
||||||
|
|
||||||
# Usamos el prefijo 'flg' para FlgNet
|
|
||||||
flgnet = network_element.xpath(".//flg:FlgNet", namespaces=ns)
|
|
||||||
if not flgnet:
|
|
||||||
return {'id': network_id, 'title': network_title, 'logic': [], 'error': 'FlgNet not found'}
|
|
||||||
|
|
||||||
flgnet = flgnet[0]
|
|
||||||
|
|
||||||
# 1. Mapear todos los Access y Parts por su UId
|
|
||||||
# Usamos prefijo flg: para Access y Part dentro de FlgNet
|
|
||||||
access_map = {}
|
|
||||||
for acc in flgnet.xpath(".//flg:Access", namespaces=ns):
|
|
||||||
acc_info = parse_access(acc)
|
|
||||||
access_map[acc_info['uid']] = acc_info
|
|
||||||
|
|
||||||
parts_map = {}
|
|
||||||
for part in flgnet.xpath(".//flg:Part", namespaces=ns):
|
|
||||||
part_info = parse_part(part)
|
|
||||||
parts_map[part_info['uid']] = part_info
|
|
||||||
|
|
||||||
# 2. Construir mapa de conexiones (destino -> fuente)
|
|
||||||
wire_connections = {}
|
|
||||||
# Usamos prefijo flg: para Wire y sus hijos
|
|
||||||
for wire in flgnet.xpath(".//flg:Wire", namespaces=ns):
|
|
||||||
source_uid, source_pin = None, None
|
|
||||||
dest_uid, dest_pin = None, None
|
|
||||||
|
|
||||||
children = wire.getchildren()
|
|
||||||
if not children: continue # Ignorar wires vacíos si los hubiera
|
|
||||||
|
|
||||||
source_elem = children[0]
|
|
||||||
dest_elem = children[1] if len(children) > 1 else None
|
|
||||||
|
|
||||||
# Usamos QName para comparar tags con namespace correctamente
|
|
||||||
flg_ns_uri = ns['flg']
|
|
||||||
if source_elem.tag == etree.QName(flg_ns_uri, 'Powerrail'):
|
|
||||||
source_uid, source_pin = 'POWERRAIL', 'out'
|
|
||||||
elif source_elem.tag == etree.QName(flg_ns_uri, 'IdentCon'):
|
|
||||||
source_uid = source_elem.get('UId')
|
|
||||||
source_pin = 'value' # Pin implícito para Access
|
|
||||||
elif source_elem.tag == etree.QName(flg_ns_uri, 'NameCon'):
|
|
||||||
source_uid = source_elem.get('UId')
|
|
||||||
source_pin = source_elem.get('Name')
|
|
||||||
|
|
||||||
if dest_elem is not None:
|
|
||||||
if dest_elem.tag == etree.QName(flg_ns_uri, 'IdentCon'):
|
|
||||||
dest_uid = dest_elem.get('UId')
|
|
||||||
dest_pin = 'value'
|
|
||||||
elif dest_elem.tag == etree.QName(flg_ns_uri, 'NameCon'):
|
|
||||||
dest_uid = dest_elem.get('UId')
|
|
||||||
dest_pin = dest_elem.get('Name')
|
|
||||||
|
|
||||||
if dest_uid and dest_pin and (source_uid is not None or source_pin == 'out'):
|
|
||||||
wire_connections[(dest_uid, dest_pin)] = (source_uid, source_pin)
|
|
||||||
|
|
||||||
|
|
||||||
# 3. Iterar sobre las instrucciones (Parts) y encontrar sus conexiones
|
|
||||||
for part_uid, part_info in parts_map.items():
|
|
||||||
instruction_repr = {
|
|
||||||
'instruction_uid': part_uid,
|
|
||||||
'type': part_info['name'],
|
|
||||||
'inputs': {},
|
|
||||||
'outputs': {}
|
|
||||||
}
|
|
||||||
|
|
||||||
connected_inputs = {k[1]: v for k, v in wire_connections.items() if k[0] == part_uid}
|
|
||||||
|
|
||||||
for dest_pin, (source_uid, source_pin) in connected_inputs.items():
|
|
||||||
if source_uid == 'POWERRAIL':
|
|
||||||
instruction_repr['inputs'][dest_pin] = {'type': 'powerrail'}
|
|
||||||
elif source_uid in access_map:
|
|
||||||
instruction_repr['inputs'][dest_pin] = access_map[source_uid]
|
|
||||||
elif source_uid in parts_map:
|
|
||||||
instruction_repr['inputs'][dest_pin] = {
|
|
||||||
'type': 'connection',
|
|
||||||
'source_instruction_uid': source_uid,
|
|
||||||
'source_instruction_type': parts_map[source_uid]['name'],
|
|
||||||
'source_pin': source_pin
|
|
||||||
}
|
|
||||||
else:
|
|
||||||
# Podría ser una conexión rota o no encontrada
|
|
||||||
instruction_repr['inputs'][dest_pin] = {'type': 'unknown_source', 'uid': source_uid}
|
|
||||||
|
|
||||||
# Encontrar salidas conectadas a Access
|
|
||||||
for (conn_dest_uid, conn_dest_pin), (conn_source_uid, conn_source_pin) in wire_connections.items():
|
|
||||||
if conn_source_uid == part_uid and conn_dest_uid in access_map:
|
|
||||||
if conn_source_pin not in instruction_repr['outputs']:
|
|
||||||
instruction_repr['outputs'][conn_source_pin] = []
|
|
||||||
# Añadimos la info del Access que es el destino
|
|
||||||
instruction_repr['outputs'][conn_source_pin].append(access_map[conn_dest_uid])
|
|
||||||
|
|
||||||
network_logic.append(instruction_repr)
|
|
||||||
|
|
||||||
return {'id': network_id, 'title': network_title, 'logic': network_logic}
|
|
||||||
|
|
||||||
|
|
||||||
def convert_xml_to_json(xml_filepath, json_filepath):
|
|
||||||
"""Función principal para convertir el XML a JSON."""
|
|
||||||
if not os.path.exists(xml_filepath):
|
|
||||||
print(f"Error: Archivo XML no encontrado en {xml_filepath}")
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
|
||||||
tree = etree.parse(xml_filepath)
|
|
||||||
root = tree.getroot()
|
|
||||||
|
|
||||||
# Buscar SW.Blocks.FC usando local-name() para robustez inicial
|
|
||||||
# O asumir que no tiene namespace si está bajo Document/Engineering
|
|
||||||
fc_block = root.xpath("//*[local-name()='SW.Blocks.FC']")
|
|
||||||
if not fc_block:
|
|
||||||
print("Error: No se encontró el elemento <SW.Blocks.FC>")
|
|
||||||
return
|
|
||||||
fc_block = fc_block[0]
|
|
||||||
|
|
||||||
# --- Extraer Info General (sin prefijos) ---
|
|
||||||
block_name = fc_block.xpath("./AttributeList/Name/text()")
|
|
||||||
block_number = fc_block.xpath("./AttributeList/Number/text()")
|
|
||||||
block_lang = fc_block.xpath("./AttributeList/ProgrammingLanguage/text()")
|
|
||||||
|
|
||||||
result = {
|
|
||||||
"block_name": block_name[0].strip() if block_name else "Unknown",
|
|
||||||
"block_number": int(block_number[0]) if block_number and block_number[0].isdigit() else None,
|
|
||||||
"language": block_lang[0].strip() if block_lang else "Unknown",
|
|
||||||
"interface": {},
|
|
||||||
"networks": []
|
|
||||||
}
|
|
||||||
|
|
||||||
# --- Extraer Interfaz (con prefijo sw:) ---
|
|
||||||
interface_sections = fc_block.xpath(".//sw:Interface/sw:Sections/sw:Section", namespaces=ns)
|
|
||||||
for section in interface_sections:
|
|
||||||
section_name = section.get('Name')
|
|
||||||
members = []
|
|
||||||
for member in section.xpath("./sw:Member", namespaces=ns):
|
|
||||||
members.append({
|
|
||||||
"name": member.get('Name'),
|
|
||||||
"datatype": member.get('Datatype')
|
|
||||||
})
|
|
||||||
result["interface"][section_name] = members
|
|
||||||
|
|
||||||
# --- Extraer Lógica de Redes (CompileUnit sin prefijo, contenido con flg:) ---
|
|
||||||
# Buscamos SW.Blocks.CompileUnit sin prefijo, asumiendo que es hijo directo de ObjectList
|
|
||||||
networks = fc_block.xpath("./ObjectList/SW.Blocks.CompileUnit", namespaces=ns)
|
|
||||||
network_count = 0
|
|
||||||
for network_elem in networks:
|
|
||||||
network_count += 1
|
|
||||||
parsed_network = parse_network(network_elem)
|
|
||||||
result["networks"].append(parsed_network)
|
|
||||||
|
|
||||||
if network_count == 0:
|
|
||||||
print("Advertencia: No se encontraron redes (SW.Blocks.CompileUnit). Verifica la estructura del XML.")
|
|
||||||
|
|
||||||
|
|
||||||
# --- Escribir resultado a JSON ---
|
|
||||||
with open(json_filepath, 'w', encoding='utf-8') as f:
|
|
||||||
json.dump(result, f, indent=4, ensure_ascii=False)
|
|
||||||
|
|
||||||
print(f"Conversión completada. Archivo JSON guardado en: {json_filepath}")
|
|
||||||
|
|
||||||
except etree.XMLSyntaxError as e:
|
|
||||||
print(f"Error de sintaxis XML: {e}")
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Ocurrió un error inesperado durante el procesamiento: {e}")
|
|
||||||
import traceback
|
|
||||||
traceback.print_exc()
|
|
||||||
|
|
||||||
|
|
||||||
# --- Ejecución ---
|
|
||||||
if __name__ == "__main__":
|
|
||||||
xml_file = 'BlenderRun_ProdTime.xml'
|
|
||||||
json_file = 'BlenderRun_ProdTime_simplified.json'
|
|
||||||
|
|
||||||
convert_xml_to_json(xml_file, json_file)
|
|
|
@ -0,0 +1,297 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
from lxml import etree
|
||||||
|
|
||||||
|
# --- Namespaces ---
|
||||||
|
ns = {
|
||||||
|
'iface': 'http://www.siemens.com/automation/Openness/SW/Interface/v5',
|
||||||
|
'flg': 'http://www.siemens.com/automation/Openness/SW/NetworkSource/FlgNet/v4'
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Helper Functions ---
|
||||||
|
# (get_multilingual_text, get_symbol_name, parse_access, parse_part sin cambios respecto a la última versión)
|
||||||
|
def get_multilingual_text(element, default_lang='en-US', fallback_lang='it-IT'):
|
||||||
|
"""Intenta extraer texto de un MultilingualText, priorizando idiomas."""
|
||||||
|
if element is None: return ""
|
||||||
|
try:
|
||||||
|
xpath_expr = f".//*[local-name()='MultilingualTextItem'][*[local-name()='AttributeList']/*[local-name()='Culture']='{default_lang}']/*[local-name()='AttributeList']/*[local-name()='Text']"
|
||||||
|
text_item = element.xpath(xpath_expr)
|
||||||
|
if text_item and text_item[0].text: return text_item[0].text.strip()
|
||||||
|
xpath_expr = f".//*[local-name()='MultilingualTextItem'][*[local-name()='AttributeList']/*[local-name()='Culture']='{fallback_lang}']/*[local-name()='AttributeList']/*[local-name()='Text']"
|
||||||
|
text_item = element.xpath(xpath_expr)
|
||||||
|
if text_item and text_item[0].text: return text_item[0].text.strip()
|
||||||
|
xpath_expr = f".//*[local-name()='MultilingualTextItem']/*[local-name()='AttributeList']/*[local-name()='Text']"
|
||||||
|
text_item = element.xpath(xpath_expr)
|
||||||
|
if text_item and text_item[0].text: return text_item[0].text.strip()
|
||||||
|
except Exception as e: print(f"Advertencia: Error extrayendo MultilingualText: {e}")
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def get_symbol_name(symbol_element):
|
||||||
|
"""Construye el nombre completo del símbolo a partir de sus componentes."""
|
||||||
|
if symbol_element is None: return None
|
||||||
|
try:
|
||||||
|
components = symbol_element.xpath("./*[local-name()='Component']/@Name")
|
||||||
|
if components: return ".".join(f'"{c}"' for c in components)
|
||||||
|
else:
|
||||||
|
# print(f"DEBUG: No se encontraron 'Component' en: {etree.tostring(symbol_element).decode()}")
|
||||||
|
return None
|
||||||
|
except Exception as e:
|
||||||
|
# print(f"DEBUG: Excepción en get_symbol_name: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def parse_access(access_element):
|
||||||
|
"""Parsea un elemento Access para obtener información de variable o constante."""
|
||||||
|
info = {'uid': access_element.get('UId'), 'scope': access_element.get('Scope'), 'type': 'unknown'}
|
||||||
|
symbol = access_element.xpath("./*[local-name()='Symbol']")
|
||||||
|
constant = access_element.xpath("./*[local-name()='Constant']")
|
||||||
|
if symbol:
|
||||||
|
info['type'] = 'variable'; info['name'] = get_symbol_name(symbol[0])
|
||||||
|
if info['name'] is None: info['type'] = 'error_parsing_symbol'
|
||||||
|
elif constant:
|
||||||
|
info['type'] = 'constant'
|
||||||
|
const_type_elem = constant[0].xpath("./*[local-name()='ConstantType']")
|
||||||
|
const_val_elem = constant[0].xpath("./*[local-name()='ConstantValue']")
|
||||||
|
info['datatype'] = const_type_elem[0].text if const_type_elem and const_type_elem[0].text is not None else 'Unknown'
|
||||||
|
info['value_str'] = const_val_elem[0].text if const_val_elem and const_val_elem[0].text is not None else None
|
||||||
|
if info['datatype'] == 'Unknown' and info['value_str'] is not None:
|
||||||
|
if info['value_str'].lower() in ['true', 'false']: info['datatype'] = 'Bool'
|
||||||
|
elif info['value_str'].isdigit() or (info['value_str'].startswith('-') and info['value_str'][1:].isdigit()): info['datatype'] = 'Int'
|
||||||
|
elif '.' in info['value_str']:
|
||||||
|
try: float(info['value_str']); info['datatype'] = 'Real'
|
||||||
|
except ValueError: pass
|
||||||
|
if info['value_str'] is not None:
|
||||||
|
info['value'] = info['value_str']
|
||||||
|
dtype_lower = info['datatype'].lower()
|
||||||
|
val_str_processed = info['value_str'].split('#')[-1] if '#' in info['value_str'] else info['value_str']
|
||||||
|
try:
|
||||||
|
if dtype_lower in ['int', 'dint', 'udint', 'sint', 'usint', 'lint', 'ulint', 'word', 'dword', 'lword', 'byte']: info['value'] = int(val_str_processed)
|
||||||
|
elif dtype_lower == 'bool': info['value'] = val_str_processed.lower() == 'true' or val_str_processed == '1'
|
||||||
|
elif dtype_lower in ['real', 'lreal']: info['value'] = float(val_str_processed)
|
||||||
|
except (ValueError, TypeError): info['value'] = info['value_str']
|
||||||
|
if 'value_str' in info: del info['value_str']
|
||||||
|
else: info['type'] = 'error_parsing_constant'; info['value'] = None
|
||||||
|
else: info['type'] = 'unknown_structure'
|
||||||
|
# Verifica si realmente se pudo parsear el nombre para variables
|
||||||
|
if info['type'] == 'variable' and info.get('name') is None:
|
||||||
|
# Si get_symbol_name falló y marcó como None, mantenemos error_parsing_symbol
|
||||||
|
if info.get('type') != 'error_parsing_symbol':
|
||||||
|
print(f"Advertencia: parse_access terminó con tipo 'variable' pero sin nombre para UID {info['uid']}.")
|
||||||
|
info['type'] = 'error_no_name' # Nuevo estado de error
|
||||||
|
|
||||||
|
return info
|
||||||
|
|
||||||
|
def parse_part(part_element):
|
||||||
|
"""Parsea un elemento Part (instrucción)."""
|
||||||
|
return {
|
||||||
|
'uid': part_element.get('UId'), 'name': part_element.get('Name'),
|
||||||
|
'template_values': {tv.get('Name'): tv.get('Type') for tv in part_element.xpath("./*[local-name()='TemplateValue']")}
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Main Parsing Logic ---
|
||||||
|
|
||||||
|
def parse_network(network_element):
|
||||||
|
"""Parsea una red (CompileUnit) y extrae su lógica simplificada."""
|
||||||
|
# (parse_network sin cambios respecto a la última versión)
|
||||||
|
network_logic = []
|
||||||
|
network_id = network_element.get('ID')
|
||||||
|
title_element = network_element.xpath(".//*[local-name()='MultilingualText'][@CompositionName='Title']")
|
||||||
|
network_title = get_multilingual_text(title_element[0]) if title_element else f"Network {network_id}"
|
||||||
|
flgnet = network_element.xpath(".//flg:FlgNet", namespaces=ns)
|
||||||
|
if not flgnet: return {'id': network_id, 'title': network_title, 'logic': [], 'error': 'FlgNet not found'}
|
||||||
|
flgnet = flgnet[0]
|
||||||
|
access_map = {acc_info['uid']: acc_info for acc in flgnet.xpath(".//flg:Access", namespaces=ns) if (acc_info := parse_access(acc))}
|
||||||
|
parts_map = {part_info['uid']: part_info for part in flgnet.xpath(".//flg:Part", namespaces=ns) if (part_info := parse_part(part))}
|
||||||
|
wire_connections = {}
|
||||||
|
flg_ns_uri = ns['flg']
|
||||||
|
for wire in flgnet.xpath(".//flg:Wire", namespaces=ns):
|
||||||
|
source_uid, source_pin, dest_uid, dest_pin = None, None, None, None
|
||||||
|
children = wire.getchildren()
|
||||||
|
if not children: continue
|
||||||
|
source_elem, dest_elem = children[0], children[1] if len(children) > 1 else None
|
||||||
|
if source_elem.tag == etree.QName(flg_ns_uri, 'Powerrail'): source_uid, source_pin = 'POWERRAIL', 'out'
|
||||||
|
elif source_elem.tag == etree.QName(flg_ns_uri, 'IdentCon'): source_uid, source_pin = source_elem.get('UId'), 'value'
|
||||||
|
elif source_elem.tag == etree.QName(flg_ns_uri, 'NameCon'): source_uid, source_pin = source_elem.get('UId'), source_elem.get('Name')
|
||||||
|
if dest_elem is not None:
|
||||||
|
if dest_elem.tag == etree.QName(flg_ns_uri, 'IdentCon'): dest_uid, dest_pin = dest_elem.get('UId'), 'value'
|
||||||
|
elif dest_elem.tag == etree.QName(flg_ns_uri, 'NameCon'): dest_uid, dest_pin = dest_elem.get('UId'), dest_elem.get('Name')
|
||||||
|
if dest_uid and dest_pin and (source_uid is not None or source_pin == 'out'):
|
||||||
|
dest_key = (dest_uid, dest_pin)
|
||||||
|
source_info = (source_uid, source_pin)
|
||||||
|
if dest_key not in wire_connections: wire_connections[dest_key] = []
|
||||||
|
wire_connections[dest_key].append(source_info)
|
||||||
|
all_logic_steps = {}
|
||||||
|
for part_uid, part_info in parts_map.items():
|
||||||
|
instruction_repr = {'instruction_uid': part_uid, 'type': part_info['name'], 'inputs': {}, 'outputs': {}}
|
||||||
|
for (conn_dest_uid, conn_dest_pin), sources_list in wire_connections.items():
|
||||||
|
if conn_dest_uid == part_uid:
|
||||||
|
input_sources = []
|
||||||
|
for source_uid, source_pin in sources_list:
|
||||||
|
if source_uid == 'POWERRAIL': input_sources.append({'type': 'powerrail'})
|
||||||
|
elif source_uid in access_map: input_sources.append(access_map[source_uid])
|
||||||
|
elif source_uid in parts_map: input_sources.append({'type': 'connection', 'source_instruction_uid': source_uid, 'source_instruction_type': parts_map[source_uid]['name'], 'source_pin': source_pin})
|
||||||
|
else: input_sources.append({'type': 'unknown_source', 'uid': source_uid})
|
||||||
|
if len(input_sources) == 1: instruction_repr['inputs'][conn_dest_pin] = input_sources[0]
|
||||||
|
else: instruction_repr['inputs'][conn_dest_pin] = {'type': 'OR_Branch', 'sources': input_sources}
|
||||||
|
for (conn_dest_uid, conn_dest_pin), sources_list in wire_connections.items():
|
||||||
|
for source_uid, source_pin in sources_list:
|
||||||
|
if source_uid == part_uid and conn_dest_uid in access_map:
|
||||||
|
if source_pin not in instruction_repr['outputs']: instruction_repr['outputs'][source_pin] = []
|
||||||
|
if access_map[conn_dest_uid] not in instruction_repr['outputs'][source_pin]: instruction_repr['outputs'][source_pin].append(access_map[conn_dest_uid])
|
||||||
|
all_logic_steps[part_uid] = instruction_repr
|
||||||
|
sorted_uids = sorted(all_logic_steps.keys(), key=lambda x: int(x) if x.isdigit() else float('inf'))
|
||||||
|
network_logic = [all_logic_steps[uid] for uid in sorted_uids if uid in all_logic_steps]
|
||||||
|
return {'id': network_id, 'title': network_title, 'logic': network_logic}
|
||||||
|
|
||||||
|
|
||||||
|
def convert_xml_to_json(xml_filepath, json_filepath):
|
||||||
|
"""Función principal para convertir el XML a JSON."""
|
||||||
|
if not os.path.exists(xml_filepath):
|
||||||
|
print(f"Error: Archivo XML no encontrado en {xml_filepath}")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
tree = etree.parse(xml_filepath)
|
||||||
|
root = tree.getroot()
|
||||||
|
|
||||||
|
# Buscar FC usando local-name()
|
||||||
|
fc_block_list = root.xpath("//*[local-name()='SW.Blocks.FC']")
|
||||||
|
if not fc_block_list:
|
||||||
|
print("Error: No se encontró el elemento <SW.Blocks.FC>")
|
||||||
|
return
|
||||||
|
fc_block = fc_block_list[0]
|
||||||
|
|
||||||
|
# Obtener el namespace real de fc_block (si tiene uno)
|
||||||
|
fc_block_ns_uri = fc_block.tag.split('}')[0][1:] if '}' in fc_block.tag else None
|
||||||
|
temp_ns = ns.copy() # Copiar namespaces base
|
||||||
|
fc_prefix = 'fcns' # Prefijo temporal para el namespace de fc_block
|
||||||
|
if fc_block_ns_uri:
|
||||||
|
temp_ns[fc_prefix] = fc_block_ns_uri
|
||||||
|
# Construir el tag con prefijo para búsquedas relativas si hay namespace
|
||||||
|
interface_tag = f"{fc_prefix}:Interface"
|
||||||
|
attribute_list_tag = f"{fc_prefix}:AttributeList"
|
||||||
|
object_list_tag = f"{fc_prefix}:ObjectList"
|
||||||
|
else:
|
||||||
|
# Si fc_block no tiene namespace, buscar hijos sin prefijo
|
||||||
|
interface_tag = "Interface"
|
||||||
|
attribute_list_tag = "AttributeList"
|
||||||
|
object_list_tag = "ObjectList"
|
||||||
|
|
||||||
|
print(f"DEBUG: Buscando hijos de {fc_block.tag} (Namespace URI: {fc_block_ns_uri})")
|
||||||
|
print(f"DEBUG: Usando tag para Interface: {interface_tag}")
|
||||||
|
print(f"DEBUG: Usando tag para AttributeList: {attribute_list_tag}")
|
||||||
|
print(f"DEBUG: Usando tag para ObjectList: {object_list_tag}")
|
||||||
|
|
||||||
|
# Usar el tag construido (con o sin prefijo) para buscar AttributeList y sus hijos
|
||||||
|
block_name = fc_block.xpath(f"./{attribute_list_tag}/*[local-name()='Name']/text()", namespaces=temp_ns)
|
||||||
|
block_number = fc_block.xpath(f"./{attribute_list_tag}/*[local-name()='Number']/text()", namespaces=temp_ns)
|
||||||
|
block_lang = fc_block.xpath(f"./{attribute_list_tag}/*[local-name()='ProgrammingLanguage']/text()", namespaces=temp_ns)
|
||||||
|
|
||||||
|
result = {
|
||||||
|
"block_name": block_name[0].strip() if block_name else "Unknown",
|
||||||
|
"block_number": int(block_number[0]) if block_number and block_number[0].isdigit() else None,
|
||||||
|
"language": block_lang[0].strip() if block_lang else "Unknown",
|
||||||
|
"interface": {},
|
||||||
|
"networks": []
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- CORREGIDA NUEVAMENTE: Extracción de Interfaz ---
|
||||||
|
# Buscar Interface DENTRO de AttributeList
|
||||||
|
# Usamos local-name() para robustez
|
||||||
|
interface_node_list = fc_block.xpath(f"./*[local-name()='AttributeList']/*[local-name()='Interface']")
|
||||||
|
if interface_node_list:
|
||||||
|
interface_node = interface_node_list[0] # Tomar el primer nodo Interface encontrado
|
||||||
|
print(f"DEBUG: Nodo Interface encontrado DENTRO de AttributeList!")
|
||||||
|
# Dentro de Interface, Sections/Section/Member usan el namespace 'iface'
|
||||||
|
interface_sections = interface_node.xpath(".//iface:Section", namespaces=ns) # Usar ns original aquí
|
||||||
|
if not interface_sections:
|
||||||
|
print("Advertencia: Nodo Interface encontrado, pero no se encontraron iface:Section dentro.")
|
||||||
|
section_count = 0
|
||||||
|
for section in interface_sections:
|
||||||
|
section_count += 1
|
||||||
|
section_name = section.get('Name')
|
||||||
|
members = []
|
||||||
|
member_count = 0
|
||||||
|
for member in section.xpath("./iface:Member", namespaces=ns): # Usar ns original
|
||||||
|
member_count += 1
|
||||||
|
members.append({
|
||||||
|
"name": member.get('Name'),
|
||||||
|
"datatype": member.get('Datatype')
|
||||||
|
})
|
||||||
|
if members:
|
||||||
|
print(f"DEBUG: Sección '{section_name}' encontrada con {member_count} miembros.")
|
||||||
|
result["interface"][section_name] = members
|
||||||
|
else:
|
||||||
|
print(f"DEBUG: Sección '{section_name}' encontrada pero sin miembros iface:Member.")
|
||||||
|
|
||||||
|
if section_count == 0 and not result["interface"]:
|
||||||
|
print("Advertencia: Nodo Interface encontrado, pero sin secciones iface:Section válidas.")
|
||||||
|
|
||||||
|
else:
|
||||||
|
# Si no se encontró Interface DENTRO de AttributeList
|
||||||
|
print("Advertencia: No se encontró el nodo <Interface> DENTRO de <AttributeList>.")
|
||||||
|
# Si no se encontró Interface DENTRO de AttributeList
|
||||||
|
print("Advertencia: No se encontró el nodo <Interface> DENTRO de <AttributeList>.")
|
||||||
|
# Sacar la expresión XPath fuera de la f-string para evitar SyntaxError
|
||||||
|
attribute_list_nodes = fc_block.xpath("./*[local-name()='AttributeList']")
|
||||||
|
if attribute_list_nodes:
|
||||||
|
attribute_list_content = etree.tostring(attribute_list_nodes[0], pretty_print=True).decode()
|
||||||
|
else:
|
||||||
|
attribute_list_content = 'AttributeList no encontrado'
|
||||||
|
print(f"DEBUG: Contenido de AttributeList: {attribute_list_content}")
|
||||||
|
|
||||||
|
# --- Extracción Lógica de Redes ---
|
||||||
|
# Buscar ObjectList usando tag construido, luego CompileUnit sin prefijo
|
||||||
|
object_list_node = fc_block.xpath(f"./{object_list_tag}", namespaces=temp_ns)
|
||||||
|
networks = []
|
||||||
|
if object_list_node:
|
||||||
|
networks = object_list_node[0].xpath("./*[local-name()='SW.Blocks.CompileUnit']") # Buscar CompileUnit por local-name
|
||||||
|
|
||||||
|
network_count = 0
|
||||||
|
for network_elem in networks:
|
||||||
|
network_count += 1
|
||||||
|
parsed_network = parse_network(network_elem)
|
||||||
|
result["networks"].append(parsed_network)
|
||||||
|
|
||||||
|
if network_count == 0:
|
||||||
|
print("Advertencia: No se encontraron redes (SW.Blocks.CompileUnit).")
|
||||||
|
|
||||||
|
|
||||||
|
# --- Escribir resultado a JSON ---
|
||||||
|
# Añadir un chequeo final antes de escribir
|
||||||
|
if not result["interface"]:
|
||||||
|
print("ADVERTENCIA FINAL: La sección 'interface' está vacía en el JSON resultante.")
|
||||||
|
variable_names_found = any(
|
||||||
|
acc.get('type') == 'variable' and acc.get('name') is not None
|
||||||
|
for net in result.get('networks', [])
|
||||||
|
for instr in net.get('logic', [])
|
||||||
|
for pin_data in instr.get('inputs', {}).values() if isinstance(pin_data, dict)
|
||||||
|
for acc in ([pin_data] if pin_data.get('type') != 'OR_Branch' else pin_data.get('sources', []))
|
||||||
|
) or any(
|
||||||
|
acc.get('type') == 'variable' and acc.get('name') is not None
|
||||||
|
for net in result.get('networks', [])
|
||||||
|
for instr in net.get('logic', [])
|
||||||
|
for pin_data_list in instr.get('outputs', {}).values() if isinstance(pin_data_list, list)
|
||||||
|
for acc in pin_data_list if isinstance(acc, dict)
|
||||||
|
)
|
||||||
|
if not variable_names_found:
|
||||||
|
print("ADVERTENCIA FINAL: Parece que no se extrajeron nombres de variables en las redes.")
|
||||||
|
|
||||||
|
|
||||||
|
with open(json_filepath, 'w', encoding='utf-8') as f:
|
||||||
|
json.dump(result, f, indent=4, ensure_ascii=False)
|
||||||
|
|
||||||
|
print(f"Conversión completada. Archivo JSON guardado en: {json_filepath}")
|
||||||
|
|
||||||
|
except etree.XMLSyntaxError as e:
|
||||||
|
print(f"Error de sintaxis XML: {e}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Ocurrió un error inesperado durante el procesamiento: {e}")
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
|
# --- Ejecución ---
|
||||||
|
if __name__ == "__main__":
|
||||||
|
xml_file = 'BlenderRun_ProdTime.xml'
|
||||||
|
json_file = 'BlenderRun_ProdTime_simplified.json'
|
||||||
|
convert_xml_to_json(xml_file, json_file)
|
Loading…
Reference in New Issue