Compare commits
4 Commits
c22f98d865
...
66c5a076ab
Author | SHA1 | Date |
---|---|---|
|
66c5a076ab | |
|
6c604176a1 | |
|
5213d09bcf | |
|
4e3aba9a2a |
|
@ -8,6 +8,8 @@ __pycache__/
|
|||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
XML Project/
|
||||
XML Proyect/
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
|
|
|
@ -1,477 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Document>
|
||||
<Engineering version="V18" />
|
||||
<SW.Blocks.FC ID="0">
|
||||
<AttributeList>
|
||||
<AutoNumber>false</AutoNumber>
|
||||
<HeaderFamily>TASK2</HeaderFamily>
|
||||
<Interface><Sections xmlns="http://www.siemens.com/automation/Openness/SW/Interface/v5">
|
||||
<Section Name="Input" />
|
||||
<Section Name="Output" />
|
||||
<Section Name="InOut" />
|
||||
<Section Name="Temp" />
|
||||
<Section Name="Constant" />
|
||||
<Section Name="Return">
|
||||
<Member Name="Ret_Val" Datatype="Void" />
|
||||
</Section>
|
||||
</Sections></Interface>
|
||||
<MemoryLayout>Standard</MemoryLayout>
|
||||
<Name>BlenderCtrl_ProdModeInit</Name>
|
||||
<Namespace />
|
||||
<Number>2012</Number>
|
||||
<ProgrammingLanguage>LAD</ProgrammingLanguage>
|
||||
<SetENOAutomatically>false</SetENOAutomatically>
|
||||
</AttributeList>
|
||||
<ObjectList>
|
||||
<MultilingualText ID="1" CompositionName="Comment">
|
||||
<ObjectList>
|
||||
<MultilingualTextItem ID="2" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>it-IT</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="3" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>de-DE</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="4" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>en-US</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="5" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>es-ES</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="6" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>fr-FR</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="7" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>zh-CN</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="8" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>ja-JP</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
</ObjectList>
|
||||
</MultilingualText>
|
||||
<SW.Blocks.CompileUnit ID="9" CompositionName="CompileUnits">
|
||||
<AttributeList>
|
||||
<NetworkSource><FlgNet xmlns="http://www.siemens.com/automation/Openness/SW/NetworkSource/FlgNet/v4">
|
||||
<Parts>
|
||||
<Call UId="21">
|
||||
<CallInfo Name="BlenderPID_PIDResInteg" BlockType="FC" />
|
||||
</Call>
|
||||
</Parts>
|
||||
<Wires>
|
||||
<Wire UId="22">
|
||||
<Powerrail />
|
||||
<NameCon UId="21" Name="en" />
|
||||
</Wire>
|
||||
</Wires>
|
||||
</FlgNet></NetworkSource>
|
||||
<ProgrammingLanguage>LAD</ProgrammingLanguage>
|
||||
</AttributeList>
|
||||
<ObjectList>
|
||||
<MultilingualText ID="A" CompositionName="Comment">
|
||||
<ObjectList>
|
||||
<MultilingualTextItem ID="B" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>it-IT</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="C" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>de-DE</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="D" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>en-US</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="E" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>es-ES</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="F" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>fr-FR</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="10" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>zh-CN</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="11" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>ja-JP</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
</ObjectList>
|
||||
</MultilingualText>
|
||||
<MultilingualText ID="12" CompositionName="Title">
|
||||
<ObjectList>
|
||||
<MultilingualTextItem ID="13" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>it-IT</Culture>
|
||||
<Text>PID Reset Integral</Text>
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="14" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>de-DE</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="15" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>en-US</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="16" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>es-ES</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="17" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>fr-FR</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="18" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>zh-CN</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="19" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>ja-JP</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
</ObjectList>
|
||||
</MultilingualText>
|
||||
</ObjectList>
|
||||
</SW.Blocks.CompileUnit>
|
||||
<SW.Blocks.CompileUnit ID="1A" CompositionName="CompileUnits">
|
||||
<AttributeList>
|
||||
<NetworkSource><FlgNet xmlns="http://www.siemens.com/automation/Openness/SW/NetworkSource/FlgNet/v4">
|
||||
<Parts>
|
||||
<Call UId="21">
|
||||
<CallInfo Name="BlenderCtrl_InitErrors" BlockType="FC" />
|
||||
</Call>
|
||||
</Parts>
|
||||
<Wires>
|
||||
<Wire UId="22">
|
||||
<Powerrail />
|
||||
<NameCon UId="21" Name="en" />
|
||||
</Wire>
|
||||
</Wires>
|
||||
</FlgNet></NetworkSource>
|
||||
<ProgrammingLanguage>LAD</ProgrammingLanguage>
|
||||
</AttributeList>
|
||||
<ObjectList>
|
||||
<MultilingualText ID="1B" CompositionName="Comment">
|
||||
<ObjectList>
|
||||
<MultilingualTextItem ID="1C" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>it-IT</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="1D" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>de-DE</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="1E" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>en-US</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="1F" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>es-ES</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="20" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>fr-FR</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="21" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>zh-CN</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="22" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>ja-JP</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
</ObjectList>
|
||||
</MultilingualText>
|
||||
<MultilingualText ID="23" CompositionName="Title">
|
||||
<ObjectList>
|
||||
<MultilingualTextItem ID="24" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>it-IT</Culture>
|
||||
<Text>Ctrl Init Errors</Text>
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="25" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>de-DE</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="26" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>en-US</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="27" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>es-ES</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="28" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>fr-FR</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="29" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>zh-CN</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="2A" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>ja-JP</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
</ObjectList>
|
||||
</MultilingualText>
|
||||
</ObjectList>
|
||||
</SW.Blocks.CompileUnit>
|
||||
<SW.Blocks.CompileUnit ID="2B" CompositionName="CompileUnits">
|
||||
<AttributeList>
|
||||
<NetworkSource><FlgNet xmlns="http://www.siemens.com/automation/Openness/SW/NetworkSource/FlgNet/v4">
|
||||
<Parts>
|
||||
<Access Scope="LiteralConstant" UId="21">
|
||||
<Constant>
|
||||
<ConstantType>Real</ConstantType>
|
||||
<ConstantValue>0.0</ConstantValue>
|
||||
</Constant>
|
||||
</Access>
|
||||
<Access Scope="GlobalVariable" UId="22">
|
||||
<Symbol>
|
||||
<Component Name="HMI_Variables_Status" />
|
||||
<Component Name="Analog_Values" />
|
||||
<Component Name="TP301RunOutCount" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Part Name="Move" UId="23" DisabledENO="false">
|
||||
<TemplateValue Name="Card" Type="Cardinality">1</TemplateValue>
|
||||
</Part>
|
||||
</Parts>
|
||||
<Wires>
|
||||
<Wire UId="24">
|
||||
<IdentCon UId="21" />
|
||||
<NameCon UId="23" Name="in" />
|
||||
</Wire>
|
||||
<Wire UId="25">
|
||||
<NameCon UId="23" Name="out1" />
|
||||
<IdentCon UId="22" />
|
||||
</Wire>
|
||||
<Wire UId="26">
|
||||
<Powerrail />
|
||||
<NameCon UId="23" Name="en" />
|
||||
</Wire>
|
||||
</Wires>
|
||||
</FlgNet></NetworkSource>
|
||||
<ProgrammingLanguage>LAD</ProgrammingLanguage>
|
||||
</AttributeList>
|
||||
<ObjectList>
|
||||
<MultilingualText ID="2C" CompositionName="Comment">
|
||||
<ObjectList>
|
||||
<MultilingualTextItem ID="2D" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>it-IT</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="2E" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>de-DE</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="2F" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>en-US</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="30" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>es-ES</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="31" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>fr-FR</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="32" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>zh-CN</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="33" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>ja-JP</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
</ObjectList>
|
||||
</MultilingualText>
|
||||
<MultilingualText ID="34" CompositionName="Title">
|
||||
<ObjectList>
|
||||
<MultilingualTextItem ID="35" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>it-IT</Culture>
|
||||
<Text>RunOut Counter</Text>
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="36" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>de-DE</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="37" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>en-US</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="38" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>es-ES</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="39" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>fr-FR</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="3A" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>zh-CN</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="3B" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>ja-JP</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
</ObjectList>
|
||||
</MultilingualText>
|
||||
</ObjectList>
|
||||
</SW.Blocks.CompileUnit>
|
||||
<MultilingualText ID="3C" CompositionName="Title">
|
||||
<ObjectList>
|
||||
<MultilingualTextItem ID="3D" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>it-IT</Culture>
|
||||
<Text>Prode Mode Init</Text>
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="3E" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>de-DE</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="3F" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>en-US</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="40" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>es-ES</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="41" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>fr-FR</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="42" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>zh-CN</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="43" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>ja-JP</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
</ObjectList>
|
||||
</MultilingualText>
|
||||
</ObjectList>
|
||||
</SW.Blocks.FC>
|
||||
</Document>
|
|
@ -1,97 +0,0 @@
|
|||
{
|
||||
"block_name": "BlenderCtrl_ProdModeInit",
|
||||
"block_number": 2012,
|
||||
"language": "LAD",
|
||||
"block_comment": "",
|
||||
"interface": {
|
||||
"Return": [
|
||||
{
|
||||
"name": "Ret_Val",
|
||||
"datatype": "Void"
|
||||
}
|
||||
]
|
||||
},
|
||||
"networks": [
|
||||
{
|
||||
"id": "9",
|
||||
"title": "PID Reset Integral",
|
||||
"comment": "",
|
||||
"logic": [
|
||||
{
|
||||
"instruction_uid": "21",
|
||||
"uid": "21",
|
||||
"type": "Call",
|
||||
"block_name": "BlenderPID_PIDResInteg",
|
||||
"block_type": "FC",
|
||||
"inputs": {
|
||||
"en": {
|
||||
"type": "powerrail"
|
||||
}
|
||||
},
|
||||
"outputs": {}
|
||||
}
|
||||
],
|
||||
"language": "LAD"
|
||||
},
|
||||
{
|
||||
"id": "1A",
|
||||
"title": "Ctrl Init Errors",
|
||||
"comment": "",
|
||||
"logic": [
|
||||
{
|
||||
"instruction_uid": "21",
|
||||
"uid": "21",
|
||||
"type": "Call",
|
||||
"block_name": "BlenderCtrl_InitErrors",
|
||||
"block_type": "FC",
|
||||
"inputs": {
|
||||
"en": {
|
||||
"type": "powerrail"
|
||||
}
|
||||
},
|
||||
"outputs": {}
|
||||
}
|
||||
],
|
||||
"language": "LAD"
|
||||
},
|
||||
{
|
||||
"id": "2B",
|
||||
"title": "RunOut Counter",
|
||||
"comment": "",
|
||||
"logic": [
|
||||
{
|
||||
"instruction_uid": "23",
|
||||
"uid": "23",
|
||||
"type": "Move",
|
||||
"template_values": {
|
||||
"Card": "Cardinality"
|
||||
},
|
||||
"negated_pins": {},
|
||||
"inputs": {
|
||||
"en": {
|
||||
"type": "powerrail"
|
||||
},
|
||||
"in": {
|
||||
"uid": "21",
|
||||
"scope": "LiteralConstant",
|
||||
"type": "constant",
|
||||
"datatype": "Real",
|
||||
"value": 0.0
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"out1": [
|
||||
{
|
||||
"uid": "22",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"HMI_Variables_Status\".\"Analog_Values\".\"TP301RunOutCount\""
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"language": "LAD"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
{
|
||||
"block_name": "BlenderCtrl_ProdModeInit",
|
||||
"block_number": 2012,
|
||||
"language": "LAD",
|
||||
"block_comment": "",
|
||||
"interface": {
|
||||
"Return": [
|
||||
{
|
||||
"name": "Ret_Val",
|
||||
"datatype": "Void"
|
||||
}
|
||||
]
|
||||
},
|
||||
"networks": [
|
||||
{
|
||||
"id": "9",
|
||||
"title": "PID Reset Integral",
|
||||
"comment": "",
|
||||
"logic": [
|
||||
{
|
||||
"instruction_uid": "21",
|
||||
"uid": "21",
|
||||
"type": "Call_FC_sympy_processed",
|
||||
"block_name": "BlenderPID_PIDResInteg",
|
||||
"block_type": "FC",
|
||||
"inputs": {
|
||||
"en": {
|
||||
"type": "powerrail"
|
||||
}
|
||||
},
|
||||
"outputs": {},
|
||||
"scl": "BlenderPID_PIDResInteg();"
|
||||
}
|
||||
],
|
||||
"language": "LAD"
|
||||
},
|
||||
{
|
||||
"id": "1A",
|
||||
"title": "Ctrl Init Errors",
|
||||
"comment": "",
|
||||
"logic": [
|
||||
{
|
||||
"instruction_uid": "21",
|
||||
"uid": "21",
|
||||
"type": "Call_FC_sympy_processed",
|
||||
"block_name": "BlenderCtrl_InitErrors",
|
||||
"block_type": "FC",
|
||||
"inputs": {
|
||||
"en": {
|
||||
"type": "powerrail"
|
||||
}
|
||||
},
|
||||
"outputs": {},
|
||||
"scl": "BlenderCtrl_InitErrors();"
|
||||
}
|
||||
],
|
||||
"language": "LAD"
|
||||
},
|
||||
{
|
||||
"id": "2B",
|
||||
"title": "RunOut Counter",
|
||||
"comment": "",
|
||||
"logic": [
|
||||
{
|
||||
"instruction_uid": "23",
|
||||
"uid": "23",
|
||||
"type": "Move_sympy_processed",
|
||||
"template_values": {
|
||||
"Card": "Cardinality"
|
||||
},
|
||||
"negated_pins": {},
|
||||
"inputs": {
|
||||
"en": {
|
||||
"type": "powerrail"
|
||||
},
|
||||
"in": {
|
||||
"uid": "21",
|
||||
"scope": "LiteralConstant",
|
||||
"type": "constant",
|
||||
"datatype": "Real",
|
||||
"value": 0.0
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"out1": [
|
||||
{
|
||||
"uid": "22",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"HMI_Variables_Status\".\"Analog_Values\".\"TP301RunOutCount\""
|
||||
}
|
||||
]
|
||||
},
|
||||
"scl": "\"HMI_Variables_Status\".\"Analog_Values\".\"TP301RunOutCount\" := 0.0;"
|
||||
}
|
||||
],
|
||||
"language": "LAD"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
// Block Name (Original): BlenderCtrl_ProdModeInit
|
||||
// Block Number: 2012
|
||||
// Original Language: LAD
|
||||
|
||||
FUNCTION_BLOCK "BlenderCtrl_ProdModeInit"
|
||||
{ S7_Optimized_Access := 'TRUE' }
|
||||
VERSION : 0.1
|
||||
|
||||
VAR_RETURN
|
||||
Ret_Val : Void;
|
||||
END_VAR
|
||||
|
||||
VAR_TEMP
|
||||
END_VAR
|
||||
|
||||
BEGIN
|
||||
|
||||
// Network 1: PID Reset Integral (Original Language: LAD)
|
||||
|
||||
BlenderPID_PIDResInteg();
|
||||
|
||||
// Network 2: Ctrl Init Errors (Original Language: LAD)
|
||||
|
||||
BlenderCtrl_InitErrors();
|
||||
|
||||
// Network 3: RunOut Counter (Original Language: LAD)
|
||||
|
||||
"HMI_Variables_Status"."Analog_Values"."TP301RunOutCount" := 0.0;
|
||||
|
||||
END_FUNCTION_BLOCK
|
10030
BlenderCtrl__Main.xml
10030
BlenderCtrl__Main.xml
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,365 +0,0 @@
|
|||
// Block Name (Original): BlenderCtrl__Main
|
||||
// Block Number: 2000
|
||||
// Original Language: LAD
|
||||
|
||||
FUNCTION_BLOCK "BlenderCtrl__Main"
|
||||
{ S7_Optimized_Access := 'TRUE' }
|
||||
VERSION : 0.1
|
||||
|
||||
VAR_RETURN
|
||||
Ret_Val : Void;
|
||||
END_VAR
|
||||
|
||||
VAR_TEMP
|
||||
All_Auto_RETVAL : Int;
|
||||
Reset_SP_Word_RETVAL : Int;
|
||||
mResetWaterTot : Bool;
|
||||
mResetSyrupTot : Bool;
|
||||
mResetCO2Tot : Bool;
|
||||
mResetProductTot : Bool;
|
||||
Block_Move_Err : Int;
|
||||
END_VAR
|
||||
|
||||
BEGIN
|
||||
|
||||
// Network 1: Clock Generation (Original Language: LAD)
|
||||
|
||||
Clock_Signal();
|
||||
|
||||
// Network 2: Machine Init (Original Language: LAD)
|
||||
|
||||
BlenderCtrl_MachineInit();
|
||||
|
||||
// Network 3: Filler Head (Original Language: LAD)
|
||||
|
||||
IF "AUX FALSE" THEN
|
||||
"Block_Move_Err" := BLKMOV(SRCBLK := "HMI_PID"."PPM303", DSTBLK => "Filler_Head_Variables"."FillerHead"); // ADVERTENCIA: BLKMOV usado directamente, probablemente no compile!
|
||||
END_IF;
|
||||
|
||||
// Network 4: Emergency Pressed (Original Language: LAD)
|
||||
|
||||
"gEmergencyPressed" := "M19000" AND NOT "gIN_VoltageOk";
|
||||
"M19000" := "gIN_VoltageOk"; // N_TRIG("gIN_VoltageOk") - Mem: "M19000"
|
||||
|
||||
// Network 5: Air and CO2 pressure ok and auxiliary ok (Original Language: LAD)
|
||||
|
||||
"gBlenderSuppliesOk" := ("gIN_VoltageOk" AND "gIN_LinePressCO2Ok" AND "HMI_Digital"."_PAL_S11"."Filtered") OR ("gIN_VoltageOk" AND "gIN_LinePressCO2Ok" AND NOT "Disable_Bit") OR ("gIN_VoltageOk" AND "gWorkshopTest" AND "HMI_Digital"."_PAL_S11"."Filtered" AND NOT "gWorkshop_Co2_Presence" AND NOT "gWorkshop_CIP_Signals") OR ("gIN_VoltageOk" AND "gWorkshopTest" AND NOT "gWorkshop_Co2_Presence" AND NOT "gWorkshop_CIP_Signals" AND NOT "Disable_Bit");
|
||||
|
||||
// Network 6: Blender State Num (Original Language: LAD)
|
||||
|
||||
"HMI_Variables_Status"."Procedures"."BlenderStateNum" := 0;
|
||||
|
||||
// Network 7: Delay Power On (Original Language: LAD)
|
||||
|
||||
"mDelayPowerOnTmr"(IN := "FirstScan", PT := S5T#2S); // TODO: Declarar "mDelayPowerOnTmr" : TP;
|
||||
|
||||
// Network 8: Production Mode (Original Language: LAD)
|
||||
|
||||
"gBlenderProdMode" := "HMI_Variables_Status"."System"."Blender_Prod_CIP";
|
||||
|
||||
// Network 9: CIp Mode (Original Language: LAD)
|
||||
|
||||
"gBlenderCIPMode" := NOT "HMI_Variables_Status"."System"."Blender_Prod_CIP";
|
||||
IF NOT "HMI_Variables_Status"."System"."Blender_Prod_CIP" THEN
|
||||
"HMI_Variables_Status"."Procedures"."BlenderStateNum" := 19;
|
||||
END_IF;
|
||||
|
||||
// Network 10: Error Faults (Original Language: LAD)
|
||||
|
||||
IF NOT "AUX FALSE" THEN
|
||||
"HMI_Variables_Status"."Meters"."QTM3012_PRD_Fault" := FALSE;
|
||||
END_IF;
|
||||
IF NOT "AUX FALSE" THEN
|
||||
"gmPDS2000_Error_Fault" := FALSE;
|
||||
END_IF;
|
||||
IF NOT "AUX FALSE" THEN
|
||||
"HMI_Variables_Status"."Meters"."QTM3012_PRD_Run" := FALSE;
|
||||
END_IF;
|
||||
IF NOT "AUX FALSE" THEN
|
||||
"gNoFreezeProductMeter" := FALSE;
|
||||
END_IF;
|
||||
|
||||
// Network 11: Filler Bottle Count Used to push Product (Original Language: LAD)
|
||||
|
||||
"System_RunOut_Variables"."ProdPipeRunOutFillerBott" := NOT "System_RunOut_Variables"."ProdPipeRunOutWaterCount";
|
||||
|
||||
// Network 12: Water Bypass Enable (Original Language: LAD)
|
||||
|
||||
"gStillWaterByPassEn" := ("HMI_Blender_Parameters"."Processor_Options"."Blender_OPT"."_StillWaterByPass" AND "Blender_Variables_Pers"."gWaterRecipe" AND NOT "Blender_Variables_Pers"."gCarboStillRecipe") OR ("HMI_Blender_Parameters"."Processor_Options"."Blender_OPT"."_ByPassDeair" AND "Blender_Variables_Pers"."gWaterRecipe" AND NOT "HMI_Blender_Parameters"."Processor_Options"."Blender_OPT"."_Deaireation" AND NOT "Blender_Variables_Pers"."gCarboStillRecipe");
|
||||
|
||||
// Network 13: Still Water Bypass (Original Language: LAD)
|
||||
|
||||
"gBlendFiStillWaterByPass" := "HMI_Blender_Parameters"."Processor_Options"."Blender_OPT"."_StillWaterByPass" AND "Blender_Variables_Pers"."gWaterRecipe" AND "HMI_Blender_Parameters"."Processor_Options"."Blender_OPT"."_BlendFillSystem" AND NOT "Blender_Variables_Pers"."gCarboStillRecipe";
|
||||
|
||||
// Network 14: Manual Syrup Drain Valve Open - Operator Alarm (Original Language: LAD)
|
||||
|
||||
"gHVP301_Open" := ("gSyrupRoomEn" AND "gBlenderCIPMode" AND "gIN_CIP_CIPRunning" AND "Procedure_Variables"."Blender_Run"."Running" AND NOT "gIN_HVP301_Aux") OR ("gSyrupRoomEn" AND "Procedure_Variables"."FTP302Line_Preparation"."Done" AND NOT "gIN_HVP301_Aux" AND NOT "HMI_Blender_Parameters"."Processor_Options"."Blender_OPT"."_FastChangeOverEnabled" AND NOT "Procedure_Variables"."Syr_RunOut"."Done");
|
||||
|
||||
// Network 15: Manual Syrup Drain Valve Open - Operator Alarm (Original Language: LAD)
|
||||
|
||||
"mHVM302_Dly"(IN := "gIN_HVM302_Aux", PT := S5T#1S); // TODO: Declarar "mHVM302_Dly" : TON;
|
||||
"gHVM302_Open" := "mHVM302_Dly".Q;
|
||||
|
||||
// Network 16: Maselli Control (Original Language: LAD)
|
||||
|
||||
IF Eq("HMI_Blender_Parameters"."Processor_Options"."Blender_OPT"."_MeterType", 6) THEN
|
||||
Maselli_PA_Control();
|
||||
END_IF;
|
||||
|
||||
// Network 17: mPDS Control (Original Language: LAD)
|
||||
|
||||
IF Eq("HMI_Blender_Parameters"."Processor_Options"."Blender_OPT"."_MeterType", 5) THEN
|
||||
mPDS_PA_Control();
|
||||
END_IF;
|
||||
|
||||
// Network 18: mPDS Syrup Control (Original Language: LAD)
|
||||
|
||||
IF "HMI_Blender_Parameters"."Processor_Options"."Blender_OPT"."_SyrBrixMeter" THEN
|
||||
mPDS_SYR_PA_Control();
|
||||
END_IF;
|
||||
|
||||
// Network 19: Co2 Analog Input (Original Language: LAD)
|
||||
// GetProdBrixCO2_FromAnalogIn
|
||||
// CALL "GetProdBrixCO2_FromAn"
|
||||
// NOP 0
|
||||
|
||||
IF Eq("HMI_Blender_Parameters"."Processor_Options"."Blender_OPT"."_MeterType", 3) THEN
|
||||
GetProdBrixCO2_Anal_Inpt();
|
||||
END_IF;
|
||||
|
||||
// Network 20: Quality (Original Language: LAD)
|
||||
|
||||
ProductQuality();
|
||||
|
||||
// Network 21: Input Data (Original Language: LAD)
|
||||
|
||||
"Input_Data"();
|
||||
|
||||
// Network 22: Sel Brix Source Check (Original Language: LAD)
|
||||
|
||||
SelCheckBrixSource();
|
||||
|
||||
// Network 23: Check Water Cooling System Temperature (Original Language: LAD)
|
||||
|
||||
IF "HMI_Blender_Parameters"."Processor_Options"."Blender_OPT"."_InverterRecirPumpPPM306" THEN
|
||||
CTRLCoolingSystem();
|
||||
END_IF;
|
||||
|
||||
// Network 24: Tank Level (Original Language: LAD)
|
||||
|
||||
TankLevel();
|
||||
|
||||
// Network 25: Production ONS (Original Language: LAD)
|
||||
|
||||
"gProductionONS" := "gBlenderProdMode" AND NOT "mDelayPowerOnTmr" AND NOT "M19001";
|
||||
|
||||
// Network 26: Blender Prod Mode Init (Original Language: LAD)
|
||||
|
||||
IF ("gProductionONS" AND NOT "Blender_Variables_Pers"."gBlenderStarted") OR ("Procedure_Variables"."Blender_Rinse"."ONS_Done" AND NOT "Blender_Variables_Pers"."gBlenderStarted") THEN
|
||||
BlenderCtrl_ProdModeInit();
|
||||
END_IF;
|
||||
|
||||
// Network 27: Rinse ONS (Original Language: LAD)
|
||||
|
||||
"gRinseONS" := "HMI_Variables_Status"."System"."Blender_Prod_CIP" AND NOT "mDelayPowerOnTmr" AND NOT "M19002";
|
||||
|
||||
// Network 28: CIP ONS (Original Language: LAD)
|
||||
|
||||
"gCIPONS" := "gBlenderCIPMode" AND NOT "mDelayPowerOnTmr" AND NOT "M19003";
|
||||
|
||||
// Network 29: CIp Mode Init (Original Language: LAD)
|
||||
|
||||
IF "gCIPONS" THEN
|
||||
BlenderCtrl_CIPModeInit();
|
||||
END_IF;
|
||||
|
||||
// Network 30: Reset SPWords (Original Language: LAD)
|
||||
|
||||
BlenderCtrl_ResetSPWord();
|
||||
|
||||
// Network 31: Blender Run Control (Original Language: LAD)
|
||||
|
||||
BlenderRun__Control();
|
||||
|
||||
// Network 32: Tank Pressure Control (Original Language: LAD)
|
||||
|
||||
Prod_Tank_PressCtrl();
|
||||
|
||||
// Network 33: Balaiage (Original Language: LAD)
|
||||
|
||||
Baialage();
|
||||
|
||||
// Network 34: First Production (Original Language: LAD)
|
||||
|
||||
"FirstProduction_Data"();
|
||||
|
||||
// Network 35: CIP MAIN Calling (Original Language: LAD)
|
||||
|
||||
CIPMain();
|
||||
|
||||
// Network 36: Blender Rinse (Original Language: LAD)
|
||||
|
||||
BlenderRinse();
|
||||
|
||||
// Network 37: Safeties (Original Language: LAD)
|
||||
|
||||
Safeties();
|
||||
|
||||
// Network 38: Instrument Scanner (Original Language: LAD)
|
||||
|
||||
Instrument_Scanner();
|
||||
|
||||
// Network 39: Vacuum Control (Original Language: LAD)
|
||||
|
||||
VacuumCtrl();
|
||||
|
||||
// Network 40: Syrup Room Control (Original Language: LAD)
|
||||
|
||||
SyrupRoomCtrl();
|
||||
|
||||
// Network 41: Blend Procedure Data (Original Language: LAD)
|
||||
|
||||
IF NOT "mDelayPowerOnTmr" THEN
|
||||
"Blender_Procedure Data"();
|
||||
END_IF;
|
||||
|
||||
// Network 42: Pneumatic Valve Control (Original Language: LAD)
|
||||
|
||||
Pneumatic_Valve_Ctrl();
|
||||
|
||||
// Network 43: Pumps Control (Original Language: LAD)
|
||||
|
||||
PumpsControl();
|
||||
|
||||
// Network 44: Prod Report Manager (Original Language: LAD)
|
||||
|
||||
IF "HMI_Blender_Parameters"."Processor_Options"."Blender_OPT"."_Report" THEN
|
||||
ProdReportManager();
|
||||
END_IF;
|
||||
|
||||
// Network 45: Outputs (Original Language: LAD)
|
||||
|
||||
Output();
|
||||
|
||||
// Network 46: SLIM BLOCK (Original Language: LAD)
|
||||
|
||||
SLIM_Block();
|
||||
|
||||
// Network 47: Interlocking Panel 1 (Original Language: LAD)
|
||||
|
||||
Interlocking_Panel_1();
|
||||
|
||||
// Network 48: Filler Control (Original Language: LAD)
|
||||
|
||||
FillerControl();
|
||||
|
||||
// Network 49: Blender Ctrl Update PWORD (Original Language: LAD)
|
||||
|
||||
BlenderCtrl_UpdatePWord();
|
||||
|
||||
// Network 50: ResetTotalizer (Original Language: LAD)
|
||||
|
||||
"mResetTotalizerTmr"(IN := "gBlendResetTotalizer", PT := S5T#2S); // TODO: Declarar "mResetTotalizerTmr" : TP;
|
||||
|
||||
// Network 51: ResetWaterTot (Original Language: LAD)
|
||||
|
||||
"mResetFTN301TotTmr"(IN := "gFTN301_ResetTot" OR "mResetTotalizerTmr", PT := S5T#2S); // TODO: Declarar "mResetFTN301TotTmr" : TP;
|
||||
"mResetWaterTot" := "mResetFTN301TotTmr".Q;
|
||||
|
||||
// Network 52: Water VFM Reset Totalizer (Original Language: LAD)
|
||||
|
||||
IF "gFTN301_ResetTot" THEN
|
||||
"gFTN301_ResetTot" := FALSE;
|
||||
END_IF;
|
||||
|
||||
// Network 53: ResetCO2Tot (Original Language: LAD)
|
||||
|
||||
"mResetFTP302TotTmr"(IN := "mResetTotalizerTmr" OR "gFTP302_ResetTot", PT := S5T#2S); // TODO: Declarar "mResetFTP302TotTmr" : TP;
|
||||
"mResetSyrupTot" := "gSyrupRoomEn" AND "mResetFTP302TotTmr".Q;
|
||||
|
||||
// Network 54: Syrup MFM Reset Totalizer (Original Language: LAD)
|
||||
|
||||
IF "gFTP302_ResetTot" THEN
|
||||
"gFTP302_ResetTot" := FALSE;
|
||||
END_IF;
|
||||
|
||||
// Network 55: ResetProductTot (Original Language: LAD)
|
||||
|
||||
"mResetFTM303TotTmr"(IN := "mResetTotalizerTmr" OR "gFTM303_ResetTot", PT := S5T#2S); // TODO: Declarar "mResetFTM303TotTmr" : TP;
|
||||
"mResetCO2Tot" := "mResetFTM303TotTmr".Q;
|
||||
|
||||
// Network 56: CO2 MFM Reset Tot (Original Language: LAD)
|
||||
|
||||
IF "gFTM303_ResetTot" THEN
|
||||
"gFTM303_ResetTot" := FALSE;
|
||||
END_IF;
|
||||
|
||||
// Network 57: ResetCO2Tot (Original Language: LAD)
|
||||
|
||||
"mResetProductTotTmr"(IN := "mResetTotalizerTmr" OR "gProductMFMResetTot", PT := S5T#2S); // TODO: Declarar "mResetProductTotTmr" : TP;
|
||||
"mResetProductTot" := "mResetProductTotTmr".Q;
|
||||
|
||||
// Network 58: Reset Totalizer (Original Language: LAD)
|
||||
|
||||
IF "gProductMFMResetTot" THEN
|
||||
"gProductMFMResetTot" := FALSE;
|
||||
END_IF;
|
||||
|
||||
// Network 59: Reset Totalizer (Original Language: LAD)
|
||||
|
||||
IF "gBlendResetTotalizer" THEN
|
||||
"gBlendResetTotalizer" := FALSE;
|
||||
END_IF;
|
||||
|
||||
// Network 60: Blender Ctrl Command (Original Language: LAD)
|
||||
|
||||
IF NOT "HMI_Blender_Parameters"."Processor_Options"."Blender_OPT"."_Simulation" THEN
|
||||
BlenderCtrl_MFM_Command();
|
||||
END_IF;
|
||||
|
||||
// Network 61: DP Global Diag (Original Language: LAD)
|
||||
|
||||
CPU_DP_Global_Diag();
|
||||
|
||||
// Network 62: Profibus (Original Language: LAD)
|
||||
|
||||
Profibus_Network();
|
||||
|
||||
// Network 63: Valve Fault (Original Language: LAD)
|
||||
|
||||
ModValveFault();
|
||||
|
||||
// Network 64: All Auto (Original Language: LAD)
|
||||
|
||||
IF ("M19011" AND NOT "HMI_Variables_Cmd"."Commands_From_HMI"."F7_DeviceControl"."Command") OR ("M19011" AND NOT "HMI_Variables_Cmd"."Commands_From_HMI"."F7_DeviceControl"."Enable") THEN
|
||||
BlenderCtrl_All_Auto();
|
||||
END_IF;
|
||||
"HMI_Variables_Cmd"."Commands_From_HMI"."F7_DeviceControl"."Light" := "HMI_Variables_Cmd"."Commands_From_HMI"."F7_DeviceControl"."Command" AND "HMI_Variables_Cmd"."Commands_From_HMI"."F7_DeviceControl"."Enable";
|
||||
|
||||
// Network 65: Ctrl HMI Manual Active (Original Language: LAD)
|
||||
|
||||
BlenderCtrl_ManualActive();
|
||||
|
||||
// Network 66: 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;
|
||||
IF "T_Pulse_Recipe_Edit" AND "T_Pulse_Recipe_Edit".Q THEN
|
||||
"HMI_Variables_Cmd"."Recipe"."Edit" := FALSE;
|
||||
END_IF;
|
||||
IF "mAux_FP_M700_1" THEN
|
||||
"HMI_Variables_Cmd"."Recipe"."Edit" := TRUE;
|
||||
END_IF;
|
||||
|
||||
// Network 67: to HMI - Recipe Management (Original Language: LAD)
|
||||
|
||||
IF "AUX TRUE" THEN
|
||||
"RecipeManagement_Data"();
|
||||
END_IF;
|
||||
|
||||
// Network 68: Recipe Calculation (Original Language: LAD)
|
||||
|
||||
RecipeCalculation();
|
||||
|
||||
END_FUNCTION_BLOCK
|
File diff suppressed because it is too large
Load Diff
995
TestLAD.xml
995
TestLAD.xml
|
@ -1,995 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Document>
|
||||
<Engineering version="V18" />
|
||||
<SW.Blocks.FC ID="0">
|
||||
<AttributeList>
|
||||
<Interface><Sections xmlns="http://www.siemens.com/automation/Openness/SW/Interface/v5">
|
||||
<Section Name="Input" />
|
||||
<Section Name="Output" />
|
||||
<Section Name="InOut" />
|
||||
<Section Name="Temp">
|
||||
<Member Name="mWaterMaxFlow" Datatype="Real" />
|
||||
<Member Name="mWaterMinFlow" Datatype="Real" />
|
||||
<Member Name="mSyrupMaxFlow" Datatype="Real" />
|
||||
<Member Name="mSyrupMinFlow" Datatype="Real" />
|
||||
<Member Name="mMinRatio" Datatype="Real" />
|
||||
<Member Name="mMaxRatio" Datatype="Real" />
|
||||
<Member Name="mBevBrixMax" Datatype="Real" />
|
||||
<Member Name="mBevBrixMin" Datatype="Real" />
|
||||
</Section>
|
||||
<Section Name="Constant" />
|
||||
<Section Name="Return">
|
||||
<Member Name="Ret_Val" Datatype="Real" />
|
||||
</Section>
|
||||
</Sections></Interface>
|
||||
<MemoryLayout>Optimized</MemoryLayout>
|
||||
<Name>TestLAD</Name>
|
||||
<Namespace />
|
||||
<Number>2</Number>
|
||||
<ProgrammingLanguage>LAD</ProgrammingLanguage>
|
||||
<SetENOAutomatically>false</SetENOAutomatically>
|
||||
</AttributeList>
|
||||
<ObjectList>
|
||||
<MultilingualText ID="1" CompositionName="Comment">
|
||||
<ObjectList>
|
||||
<MultilingualTextItem ID="2" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>it-IT</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="3" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>de-DE</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="4" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>en-US</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="5" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>es-ES</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="6" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>fr-FR</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="7" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>zh-CN</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="8" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>ja-JP</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
</ObjectList>
|
||||
</MultilingualText>
|
||||
<SW.Blocks.CompileUnit ID="9" CompositionName="CompileUnits">
|
||||
<AttributeList>
|
||||
<NetworkSource><StructuredText xmlns="http://www.siemens.com/automation/Openness/SW/NetworkSource/StructuredText/v3">
|
||||
<NewLine UId="21" />
|
||||
<Token Text="IF" UId="22" />
|
||||
<Blank UId="23" />
|
||||
<Access Scope="GlobalVariable" UId="24">
|
||||
<Symbol UId="25">
|
||||
<Component Name="Blender_Variables" UId="26">
|
||||
<BooleanAttribute Name="HasQuotes" UId="27">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="28" />
|
||||
<Component Name="gSP_H2O" UId="29" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="30" />
|
||||
<Token Text="<>" UId="31" />
|
||||
<Blank UId="32" />
|
||||
<Access Scope="LiteralConstant" UId="33">
|
||||
<Constant UId="34">
|
||||
<ConstantValue UId="36">0</ConstantValue>
|
||||
</Constant>
|
||||
</Access>
|
||||
<Blank UId="37" />
|
||||
<Token Text="THEN" UId="38" />
|
||||
<NewLine UId="39" />
|
||||
<Blank Num="4" UId="40" />
|
||||
<Access Scope="GlobalVariable" UId="41">
|
||||
<Symbol UId="42">
|
||||
<Component Name="Blender_Variables" UId="43">
|
||||
<BooleanAttribute Name="HasQuotes" UId="44">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="45" />
|
||||
<Component Name="gWaterVFMCalcError" UId="46" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="47" />
|
||||
<Token Text=":=" UId="48" />
|
||||
<Blank UId="49" />
|
||||
<Access Scope="GlobalVariable" UId="50">
|
||||
<Symbol UId="51">
|
||||
<Component Name="Blender_Variables" UId="52">
|
||||
<BooleanAttribute Name="HasQuotes" UId="53">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="54" />
|
||||
<Component Name="gWaterVFMMeasError" UId="55" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="56" />
|
||||
<Token Text="/" UId="57" />
|
||||
<Blank UId="58" />
|
||||
<Access Scope="LiteralConstant" UId="59">
|
||||
<Constant UId="60">
|
||||
<ConstantValue UId="62">100</ConstantValue>
|
||||
</Constant>
|
||||
</Access>
|
||||
<Blank UId="63" />
|
||||
<Token Text="*" UId="64" />
|
||||
<Blank UId="65" />
|
||||
<Access Scope="GlobalVariable" UId="66">
|
||||
<Symbol UId="67">
|
||||
<Component Name="Blender_Variables" UId="68">
|
||||
<BooleanAttribute Name="HasQuotes" UId="69">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="70" />
|
||||
<Component Name="gSP_H2O" UId="71" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Token Text=";" UId="72" />
|
||||
<NewLine UId="73" />
|
||||
<Token Text="END_IF" UId="74" />
|
||||
<Token Text=";" UId="75" />
|
||||
<NewLine UId="76" />
|
||||
<Token Text="IF" UId="77" />
|
||||
<Blank UId="78" />
|
||||
<Access Scope="GlobalVariable" UId="79">
|
||||
<Symbol UId="80">
|
||||
<Component Name="Blender_Variables" UId="81">
|
||||
<BooleanAttribute Name="HasQuotes" UId="82">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="83" />
|
||||
<Component Name="gSP_SYR" UId="84" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="85" />
|
||||
<Token Text="<>" UId="86" />
|
||||
<Blank UId="87" />
|
||||
<Access Scope="LiteralConstant" UId="88">
|
||||
<Constant UId="89">
|
||||
<ConstantValue UId="91">0</ConstantValue>
|
||||
</Constant>
|
||||
</Access>
|
||||
<Blank UId="92" />
|
||||
<Token Text="THEN" UId="93" />
|
||||
<NewLine UId="94" />
|
||||
<Blank Num="4" UId="95" />
|
||||
<Access Scope="GlobalVariable" UId="96">
|
||||
<Symbol UId="97">
|
||||
<Component Name="Blender_Variables" UId="98">
|
||||
<BooleanAttribute Name="HasQuotes" UId="99">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="100" />
|
||||
<Component Name="gSyrupMFMCalcError" UId="101" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="102" />
|
||||
<Token Text=":=" UId="103" />
|
||||
<Blank UId="104" />
|
||||
<Token Text="(" UId="105" />
|
||||
<Access Scope="GlobalVariable" UId="106">
|
||||
<Symbol UId="107">
|
||||
<Component Name="Blender_Variables" UId="108">
|
||||
<BooleanAttribute Name="HasQuotes" UId="109">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="110" />
|
||||
<Component Name="gSyrupMFMMeasError" UId="111" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="112" />
|
||||
<Token Text="/" UId="113" />
|
||||
<Blank UId="114" />
|
||||
<Access Scope="LiteralConstant" UId="115">
|
||||
<Constant UId="116">
|
||||
<ConstantValue UId="118">100</ConstantValue>
|
||||
</Constant>
|
||||
</Access>
|
||||
<Blank UId="119" />
|
||||
<Token Text="+" UId="120" />
|
||||
<Blank UId="121" />
|
||||
<Token Text="(" UId="122" />
|
||||
<Access Scope="GlobalVariable" UId="123">
|
||||
<Symbol UId="124">
|
||||
<Component Name="Blender_Variables" UId="125">
|
||||
<BooleanAttribute Name="HasQuotes" UId="126">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="127" />
|
||||
<Component Name="gSyrupMFMZeroStab" UId="128" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="129" />
|
||||
<Token Text="/" UId="130" />
|
||||
<Blank UId="131" />
|
||||
<Token Text="(" UId="132" />
|
||||
<Access Scope="GlobalVariable" UId="133">
|
||||
<Symbol UId="134">
|
||||
<Component Name="Blender_Variables" UId="135">
|
||||
<BooleanAttribute Name="HasQuotes" UId="136">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="137" />
|
||||
<Component Name="gSP_SYR" UId="138" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="139" />
|
||||
<Token Text="*" UId="140" />
|
||||
<Blank UId="141" />
|
||||
<Access Scope="LiteralConstant" UId="142">
|
||||
<Constant UId="143">
|
||||
<ConstantValue UId="145">60</ConstantValue>
|
||||
</Constant>
|
||||
</Access>
|
||||
<Token Text=")" UId="146" />
|
||||
<Token Text=")" UId="147" />
|
||||
<Blank UId="148" />
|
||||
<Token Text="/" UId="149" />
|
||||
<Blank UId="150" />
|
||||
<Access Scope="LiteralConstant" UId="151">
|
||||
<Constant UId="152">
|
||||
<ConstantValue UId="154">100</ConstantValue>
|
||||
</Constant>
|
||||
</Access>
|
||||
<Token Text=")" UId="155" />
|
||||
<Blank UId="156" />
|
||||
<Token Text="*" UId="157" />
|
||||
<Blank UId="158" />
|
||||
<Access Scope="GlobalVariable" UId="159">
|
||||
<Symbol UId="160">
|
||||
<Component Name="Blender_Variables" UId="161">
|
||||
<BooleanAttribute Name="HasQuotes" UId="162">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="163" />
|
||||
<Component Name="gSP_SYR" UId="164" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Token Text=";" UId="165" />
|
||||
<NewLine UId="166" />
|
||||
<Token Text="END_IF" UId="167" />
|
||||
<Token Text=";" UId="168" />
|
||||
<NewLine UId="169" />
|
||||
<Token Text="IF" UId="170" />
|
||||
<Blank UId="171" />
|
||||
<Access Scope="GlobalVariable" UId="172">
|
||||
<Symbol UId="173">
|
||||
<Component Name="Blender_Variables" UId="174">
|
||||
<BooleanAttribute Name="HasQuotes" UId="175">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="176" />
|
||||
<Component Name="gSP_CO2" UId="177" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="178" />
|
||||
<Token Text="<>" UId="179" />
|
||||
<Blank UId="180" />
|
||||
<Access Scope="LiteralConstant" UId="181">
|
||||
<Constant UId="182">
|
||||
<ConstantValue UId="184">0</ConstantValue>
|
||||
</Constant>
|
||||
</Access>
|
||||
<Blank UId="185" />
|
||||
<Token Text="THEN" UId="186" />
|
||||
<NewLine UId="187" />
|
||||
<Blank Num="4" UId="188" />
|
||||
<Access Scope="GlobalVariable" UId="189">
|
||||
<Symbol UId="190">
|
||||
<Component Name="Blender_Variables" UId="191">
|
||||
<BooleanAttribute Name="HasQuotes" UId="192">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="193" />
|
||||
<Component Name="gCO2MFMCalcError" UId="194" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="195" />
|
||||
<Token Text=":=" UId="196" />
|
||||
<Blank UId="197" />
|
||||
<Token Text="(" UId="198" />
|
||||
<Access Scope="GlobalVariable" UId="199">
|
||||
<Symbol UId="200">
|
||||
<Component Name="Blender_Variables" UId="201">
|
||||
<BooleanAttribute Name="HasQuotes" UId="202">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="203" />
|
||||
<Component Name="gCO2MFMMeasError" UId="204" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="205" />
|
||||
<Token Text="/" UId="206" />
|
||||
<Blank UId="207" />
|
||||
<Access Scope="LiteralConstant" UId="208">
|
||||
<Constant UId="209">
|
||||
<ConstantValue UId="211">100</ConstantValue>
|
||||
</Constant>
|
||||
</Access>
|
||||
<Blank UId="212" />
|
||||
<Token Text="+" UId="213" />
|
||||
<Blank UId="214" />
|
||||
<Token Text="(" UId="215" />
|
||||
<Access Scope="GlobalVariable" UId="216">
|
||||
<Symbol UId="217">
|
||||
<Component Name="Blender_Variables" UId="218">
|
||||
<BooleanAttribute Name="HasQuotes" UId="219">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="220" />
|
||||
<Component Name="gCO2MFMZeroStab" UId="221" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="222" />
|
||||
<Token Text="/" UId="223" />
|
||||
<Blank UId="224" />
|
||||
<Token Text="(" UId="225" />
|
||||
<Access Scope="GlobalVariable" UId="226">
|
||||
<Symbol UId="227">
|
||||
<Component Name="Blender_Variables" UId="228">
|
||||
<BooleanAttribute Name="HasQuotes" UId="229">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="230" />
|
||||
<Component Name="gSP_CO2" UId="231" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="232" />
|
||||
<Token Text="*" UId="233" />
|
||||
<Blank UId="234" />
|
||||
<Access Scope="LiteralConstant" UId="235">
|
||||
<Constant UId="236">
|
||||
<ConstantValue UId="238">60</ConstantValue>
|
||||
</Constant>
|
||||
</Access>
|
||||
<Blank UId="239" />
|
||||
<Token Text="/" UId="240" />
|
||||
<Blank UId="241" />
|
||||
<Access Scope="LiteralConstant" UId="242">
|
||||
<Constant UId="243">
|
||||
<ConstantValue UId="245">1000</ConstantValue>
|
||||
</Constant>
|
||||
</Access>
|
||||
<Token Text=")" UId="246" />
|
||||
<Token Text=")" UId="247" />
|
||||
<Blank UId="248" />
|
||||
<Token Text="/" UId="249" />
|
||||
<Blank UId="250" />
|
||||
<Access Scope="LiteralConstant" UId="251">
|
||||
<Constant UId="252">
|
||||
<ConstantValue UId="254">100</ConstantValue>
|
||||
</Constant>
|
||||
</Access>
|
||||
<Token Text=")" UId="255" />
|
||||
<Blank UId="256" />
|
||||
<Token Text="*" UId="257" />
|
||||
<Blank UId="258" />
|
||||
<Access Scope="GlobalVariable" UId="259">
|
||||
<Symbol UId="260">
|
||||
<Component Name="Blender_Variables" UId="261">
|
||||
<BooleanAttribute Name="HasQuotes" UId="262">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="263" />
|
||||
<Component Name="gSP_CO2" UId="264" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Token Text=";" UId="265" />
|
||||
<NewLine UId="266" />
|
||||
<Token Text="END_IF" UId="267" />
|
||||
<Token Text=";" UId="268" />
|
||||
<NewLine UId="269" />
|
||||
<Access Scope="LocalVariable" UId="270">
|
||||
<Symbol UId="271">
|
||||
<Component Name="mWaterMaxFlow" UId="272" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="273" />
|
||||
<Token Text=":=" UId="274" />
|
||||
<Blank UId="275" />
|
||||
<Access Scope="GlobalVariable" UId="276">
|
||||
<Symbol UId="277">
|
||||
<Component Name="Blender_Variables" UId="278">
|
||||
<BooleanAttribute Name="HasQuotes" UId="279">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="280" />
|
||||
<Component Name="gSP_H2O" UId="281" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="282" />
|
||||
<Token Text="+" UId="283" />
|
||||
<Blank UId="284" />
|
||||
<Access Scope="GlobalVariable" UId="285">
|
||||
<Symbol UId="286">
|
||||
<Component Name="Blender_Variables" UId="287">
|
||||
<BooleanAttribute Name="HasQuotes" UId="288">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="289" />
|
||||
<Component Name="gWaterVFMCalcError" UId="290" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Token Text=";" UId="291" />
|
||||
<NewLine UId="292" />
|
||||
<Access Scope="LocalVariable" UId="293">
|
||||
<Symbol UId="294">
|
||||
<Component Name="mWaterMinFlow" UId="295" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="296" />
|
||||
<Token Text=":=" UId="297" />
|
||||
<Blank UId="298" />
|
||||
<Access Scope="GlobalVariable" UId="299">
|
||||
<Symbol UId="300">
|
||||
<Component Name="Blender_Variables" UId="301">
|
||||
<BooleanAttribute Name="HasQuotes" UId="302">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="303" />
|
||||
<Component Name="gSP_H2O" UId="304" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="305" />
|
||||
<Token Text="-" UId="306" />
|
||||
<Blank UId="307" />
|
||||
<Access Scope="GlobalVariable" UId="308">
|
||||
<Symbol UId="309">
|
||||
<Component Name="Blender_Variables" UId="310">
|
||||
<BooleanAttribute Name="HasQuotes" UId="311">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="312" />
|
||||
<Component Name="gWaterVFMCalcError" UId="313" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Token Text=";" UId="314" />
|
||||
<NewLine UId="315" />
|
||||
<Token Text="IF" UId="316" />
|
||||
<Blank UId="317" />
|
||||
<Access Scope="GlobalVariable" UId="318">
|
||||
<Symbol UId="319">
|
||||
<Component Name="HMI_Blender_Parameters" UId="320">
|
||||
<BooleanAttribute Name="HasQuotes" UId="321">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="322" />
|
||||
<Component Name="Actual_Recipe_Parameters" UId="323" />
|
||||
<Token Text="." UId="324" />
|
||||
<Component Name="_SyrupDensity" UId="325" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="326" />
|
||||
<Token Text="<>" UId="327" />
|
||||
<Blank UId="328" />
|
||||
<Access Scope="LiteralConstant" UId="329">
|
||||
<Constant UId="330">
|
||||
<ConstantValue UId="332">0</ConstantValue>
|
||||
</Constant>
|
||||
</Access>
|
||||
<Blank UId="333" />
|
||||
<Token Text="THEN" UId="334" />
|
||||
<NewLine UId="335" />
|
||||
<Blank Num="4" UId="336" />
|
||||
<Access Scope="LocalVariable" UId="337">
|
||||
<Symbol UId="338">
|
||||
<Component Name="mSyrupMaxFlow" UId="339" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="340" />
|
||||
<Token Text=":=" UId="341" />
|
||||
<Blank UId="342" />
|
||||
<Token Text="(" UId="343" />
|
||||
<Access Scope="GlobalVariable" UId="344">
|
||||
<Symbol UId="345">
|
||||
<Component Name="Blender_Variables" UId="346">
|
||||
<BooleanAttribute Name="HasQuotes" UId="347">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="348" />
|
||||
<Component Name="gSP_SYR" UId="349" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="350" />
|
||||
<Token Text="+" UId="351" />
|
||||
<Blank UId="352" />
|
||||
<Access Scope="GlobalVariable" UId="353">
|
||||
<Symbol UId="354">
|
||||
<Component Name="Blender_Variables" UId="355">
|
||||
<BooleanAttribute Name="HasQuotes" UId="356">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="357" />
|
||||
<Component Name="gSyrupMFMCalcError" UId="358" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Token Text=")" UId="359" />
|
||||
<Blank UId="360" />
|
||||
<Token Text="/" UId="361" />
|
||||
<Blank UId="362" />
|
||||
<Access Scope="GlobalVariable" UId="363">
|
||||
<Symbol UId="364">
|
||||
<Component Name="HMI_Blender_Parameters" UId="365">
|
||||
<BooleanAttribute Name="HasQuotes" UId="366">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="367" />
|
||||
<Component Name="Actual_Recipe_Parameters" UId="368" />
|
||||
<Token Text="." UId="369" />
|
||||
<Component Name="_SyrupDensity" UId="370" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Token Text=";" UId="371" />
|
||||
<NewLine UId="372" />
|
||||
<Blank Num="4" UId="373" />
|
||||
<Access Scope="LocalVariable" UId="374">
|
||||
<Symbol UId="375">
|
||||
<Component Name="mSyrupMinFlow" UId="376" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="377" />
|
||||
<Token Text=":=" UId="378" />
|
||||
<Blank UId="379" />
|
||||
<Token Text="(" UId="380" />
|
||||
<Access Scope="GlobalVariable" UId="381">
|
||||
<Symbol UId="382">
|
||||
<Component Name="Blender_Variables" UId="383">
|
||||
<BooleanAttribute Name="HasQuotes" UId="384">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="385" />
|
||||
<Component Name="gSP_SYR" UId="386" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="387" />
|
||||
<Token Text="-" UId="388" />
|
||||
<Blank UId="389" />
|
||||
<Access Scope="GlobalVariable" UId="390">
|
||||
<Symbol UId="391">
|
||||
<Component Name="Blender_Variables" UId="392">
|
||||
<BooleanAttribute Name="HasQuotes" UId="393">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="394" />
|
||||
<Component Name="gSyrupMFMCalcError" UId="395" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Token Text=")" UId="396" />
|
||||
<Blank UId="397" />
|
||||
<Token Text="/" UId="398" />
|
||||
<Blank UId="399" />
|
||||
<Access Scope="GlobalVariable" UId="400">
|
||||
<Symbol UId="401">
|
||||
<Component Name="HMI_Blender_Parameters" UId="402">
|
||||
<BooleanAttribute Name="HasQuotes" UId="403">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="404" />
|
||||
<Component Name="Actual_Recipe_Parameters" UId="405" />
|
||||
<Token Text="." UId="406" />
|
||||
<Component Name="_SyrupDensity" UId="407" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Token Text=";" UId="408" />
|
||||
<NewLine UId="409" />
|
||||
<Token Text="END_IF" UId="410" />
|
||||
<Token Text=";" UId="411" />
|
||||
<NewLine UId="412" />
|
||||
<Token Text="IF" UId="413" />
|
||||
<Blank UId="414" />
|
||||
<Access Scope="LocalVariable" UId="415">
|
||||
<Symbol UId="416">
|
||||
<Component Name="mSyrupMaxFlow" UId="417" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="418" />
|
||||
<Token Text="<>" UId="419" />
|
||||
<Blank UId="420" />
|
||||
<Access Scope="LiteralConstant" UId="421">
|
||||
<Constant UId="422">
|
||||
<ConstantValue UId="424">0</ConstantValue>
|
||||
</Constant>
|
||||
</Access>
|
||||
<Blank UId="425" />
|
||||
<Token Text="THEN" UId="426" />
|
||||
<NewLine UId="427" />
|
||||
<Blank Num="4" UId="428" />
|
||||
<Access Scope="LocalVariable" UId="429">
|
||||
<Symbol UId="430">
|
||||
<Component Name="mMinRatio" UId="431" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="432" />
|
||||
<Token Text=":=" UId="433" />
|
||||
<Blank UId="434" />
|
||||
<Access Scope="LocalVariable" UId="435">
|
||||
<Symbol UId="436">
|
||||
<Component Name="mWaterMinFlow" UId="437" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="438" />
|
||||
<Token Text="/" UId="439" />
|
||||
<Blank UId="440" />
|
||||
<Access Scope="LocalVariable" UId="441">
|
||||
<Symbol UId="442">
|
||||
<Component Name="mSyrupMaxFlow" UId="443" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Token Text=";" UId="444" />
|
||||
<NewLine UId="445" />
|
||||
<Token Text="END_IF" UId="446" />
|
||||
<Token Text=";" UId="447" />
|
||||
<NewLine UId="448" />
|
||||
<Token Text="IF" UId="449" />
|
||||
<Blank UId="450" />
|
||||
<Access Scope="LocalVariable" UId="451">
|
||||
<Symbol UId="452">
|
||||
<Component Name="mSyrupMinFlow" UId="453" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="454" />
|
||||
<Token Text="<>" UId="455" />
|
||||
<Blank UId="456" />
|
||||
<Access Scope="LiteralConstant" UId="457">
|
||||
<Constant UId="458">
|
||||
<ConstantValue UId="460">0</ConstantValue>
|
||||
</Constant>
|
||||
</Access>
|
||||
<Blank UId="461" />
|
||||
<Token Text="THEN" UId="462" />
|
||||
<NewLine UId="463" />
|
||||
<Blank Num="4" UId="464" />
|
||||
<Access Scope="LocalVariable" UId="465">
|
||||
<Symbol UId="466">
|
||||
<Component Name="mMaxRatio" UId="467" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="468" />
|
||||
<Token Text=":=" UId="469" />
|
||||
<Blank UId="470" />
|
||||
<Access Scope="LocalVariable" UId="471">
|
||||
<Symbol UId="472">
|
||||
<Component Name="mWaterMaxFlow" UId="473" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="474" />
|
||||
<Token Text="/" UId="475" />
|
||||
<Blank UId="476" />
|
||||
<Access Scope="LocalVariable" UId="477">
|
||||
<Symbol UId="478">
|
||||
<Component Name="mSyrupMinFlow" UId="479" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Token Text=";" UId="480" />
|
||||
<NewLine UId="481" />
|
||||
<Token Text="END_IF" UId="482" />
|
||||
<Token Text=";" UId="483" />
|
||||
<NewLine UId="484" />
|
||||
<Token Text="IF" UId="485" />
|
||||
<Blank UId="486" />
|
||||
<Access Scope="GlobalVariable" UId="487">
|
||||
<Symbol UId="488">
|
||||
<Component Name="HMI_Blender_Parameters" UId="489">
|
||||
<BooleanAttribute Name="HasQuotes" UId="490">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="491" />
|
||||
<Component Name="Actual_Recipe_Parameters" UId="492" />
|
||||
<Token Text="." UId="493" />
|
||||
<Component Name="_SyrupDensity" UId="494" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="495" />
|
||||
<Token Text="<>" UId="496" />
|
||||
<Blank UId="497" />
|
||||
<Access Scope="LiteralConstant" UId="498">
|
||||
<Constant UId="499">
|
||||
<ConstantValue UId="501">0</ConstantValue>
|
||||
</Constant>
|
||||
</Access>
|
||||
<Blank UId="502" />
|
||||
<Token Text="THEN" UId="503" />
|
||||
<NewLine UId="504" />
|
||||
<Blank Num="4" UId="505" />
|
||||
<Access Scope="LocalVariable" UId="506">
|
||||
<Symbol UId="507">
|
||||
<Component Name="mBevBrixMax" UId="508" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="509" />
|
||||
<Token Text=":=" UId="510" />
|
||||
<Blank UId="511" />
|
||||
<Access Scope="GlobalVariable" UId="512">
|
||||
<Symbol UId="513">
|
||||
<Component Name="HMI_Blender_Parameters" UId="514">
|
||||
<BooleanAttribute Name="HasQuotes" UId="515">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="516" />
|
||||
<Component Name="Actual_Recipe_Parameters" UId="517" />
|
||||
<Token Text="." UId="518" />
|
||||
<Component Name="_SyrupBrix" UId="519" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="520" />
|
||||
<Token Text="/" UId="521" />
|
||||
<Blank UId="522" />
|
||||
<Token Text="(" UId="523" />
|
||||
<Token Text="(" UId="524" />
|
||||
<Access Scope="LocalVariable" UId="525">
|
||||
<Symbol UId="526">
|
||||
<Component Name="mMinRatio" UId="527" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="528" />
|
||||
<Token Text="/" UId="529" />
|
||||
<Blank UId="530" />
|
||||
<Access Scope="GlobalVariable" UId="531">
|
||||
<Symbol UId="532">
|
||||
<Component Name="HMI_Blender_Parameters" UId="533">
|
||||
<BooleanAttribute Name="HasQuotes" UId="534">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="535" />
|
||||
<Component Name="Actual_Recipe_Parameters" UId="536" />
|
||||
<Token Text="." UId="537" />
|
||||
<Component Name="_SyrupDensity" UId="538" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Token Text=")" UId="539" />
|
||||
<Blank UId="540" />
|
||||
<Token Text="+" UId="541" />
|
||||
<Blank UId="542" />
|
||||
<Access Scope="LiteralConstant" UId="543">
|
||||
<Constant UId="544">
|
||||
<ConstantValue UId="546">1</ConstantValue>
|
||||
</Constant>
|
||||
</Access>
|
||||
<Token Text=")" UId="547" />
|
||||
<Token Text=";" UId="548" />
|
||||
<NewLine UId="549" />
|
||||
<Blank Num="4" UId="550" />
|
||||
<Access Scope="LocalVariable" UId="551">
|
||||
<Symbol UId="552">
|
||||
<Component Name="mBevBrixMin" UId="553" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="554" />
|
||||
<Token Text=":=" UId="555" />
|
||||
<Blank UId="556" />
|
||||
<Access Scope="GlobalVariable" UId="557">
|
||||
<Symbol UId="558">
|
||||
<Component Name="HMI_Blender_Parameters" UId="559">
|
||||
<BooleanAttribute Name="HasQuotes" UId="560">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="561" />
|
||||
<Component Name="Actual_Recipe_Parameters" UId="562" />
|
||||
<Token Text="." UId="563" />
|
||||
<Component Name="_SyrupBrix" UId="564" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="565" />
|
||||
<Token Text="/" UId="566" />
|
||||
<Blank UId="567" />
|
||||
<Token Text="(" UId="568" />
|
||||
<Token Text="(" UId="569" />
|
||||
<Access Scope="LocalVariable" UId="570">
|
||||
<Symbol UId="571">
|
||||
<Component Name="mMaxRatio" UId="572" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="573" />
|
||||
<Token Text="/" UId="574" />
|
||||
<Blank UId="575" />
|
||||
<Access Scope="GlobalVariable" UId="576">
|
||||
<Symbol UId="577">
|
||||
<Component Name="HMI_Blender_Parameters" UId="578">
|
||||
<BooleanAttribute Name="HasQuotes" UId="579">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="580" />
|
||||
<Component Name="Actual_Recipe_Parameters" UId="581" />
|
||||
<Token Text="." UId="582" />
|
||||
<Component Name="_SyrupDensity" UId="583" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Token Text=")" UId="584" />
|
||||
<Blank UId="585" />
|
||||
<Token Text="+" UId="586" />
|
||||
<Blank UId="587" />
|
||||
<Access Scope="LiteralConstant" UId="588">
|
||||
<Constant UId="589">
|
||||
<ConstantValue UId="591">1</ConstantValue>
|
||||
</Constant>
|
||||
</Access>
|
||||
<Token Text=")" UId="592" />
|
||||
<Token Text=";" UId="593" />
|
||||
<NewLine UId="594" />
|
||||
<Token Text="END_IF" UId="595" />
|
||||
<Token Text=";" UId="596" />
|
||||
<NewLine UId="597" />
|
||||
<Access Scope="GlobalVariable" UId="598">
|
||||
<Symbol UId="599">
|
||||
<Component Name="Blender_Variables" UId="600">
|
||||
<BooleanAttribute Name="HasQuotes" UId="601">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="602" />
|
||||
<Component Name="gBlenderBlendMaxError" UId="603" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="604" />
|
||||
<Token Text=":=" UId="605" />
|
||||
<Blank UId="606" />
|
||||
<Access Scope="LocalVariable" UId="607">
|
||||
<Symbol UId="608">
|
||||
<Component Name="mBevBrixMax" UId="609" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="610" />
|
||||
<Token Text="-" UId="611" />
|
||||
<Blank UId="612" />
|
||||
<Access Scope="LocalVariable" UId="613">
|
||||
<Symbol UId="614">
|
||||
<Component Name="mBevBrixMin" UId="615" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Token Text=";" UId="616" />
|
||||
<NewLine Num="2" UId="617" />
|
||||
<Access Scope="LocalVariable" UId="618">
|
||||
<Symbol UId="619">
|
||||
<Component Name="TestLAD" UId="620" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Blank UId="621" />
|
||||
<Token Text=":=" UId="622" />
|
||||
<Blank UId="623" />
|
||||
<Access Scope="GlobalVariable" UId="624">
|
||||
<Symbol UId="625">
|
||||
<Component Name="Blender_Variables" UId="626">
|
||||
<BooleanAttribute Name="HasQuotes" UId="627">true</BooleanAttribute>
|
||||
</Component>
|
||||
<Token Text="." UId="628" />
|
||||
<Component Name="gBlenderBlendMaxError" UId="629" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Token Text=";" UId="630" />
|
||||
</StructuredText></NetworkSource>
|
||||
<ProgrammingLanguage>SCL</ProgrammingLanguage>
|
||||
</AttributeList>
|
||||
<ObjectList>
|
||||
<MultilingualText ID="A" CompositionName="Comment">
|
||||
<ObjectList>
|
||||
<MultilingualTextItem ID="B" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>it-IT</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="C" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>de-DE</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="D" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>en-US</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="E" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>es-ES</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="F" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>fr-FR</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="10" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>zh-CN</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="11" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>ja-JP</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
</ObjectList>
|
||||
</MultilingualText>
|
||||
<MultilingualText ID="12" CompositionName="Title">
|
||||
<ObjectList>
|
||||
<MultilingualTextItem ID="13" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>it-IT</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="14" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>de-DE</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="15" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>en-US</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="16" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>es-ES</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="17" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>fr-FR</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="18" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>zh-CN</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="19" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>ja-JP</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
</ObjectList>
|
||||
</MultilingualText>
|
||||
</ObjectList>
|
||||
</SW.Blocks.CompileUnit>
|
||||
<MultilingualText ID="1A" CompositionName="Title">
|
||||
<ObjectList>
|
||||
<MultilingualTextItem ID="1B" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>it-IT</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="1C" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>de-DE</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="1D" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>en-US</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="1E" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>es-ES</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="1F" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>fr-FR</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="20" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>zh-CN</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="21" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>ja-JP</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
</ObjectList>
|
||||
</MultilingualText>
|
||||
</ObjectList>
|
||||
</SW.Blocks.FC>
|
||||
</Document>
|
|
@ -1,63 +0,0 @@
|
|||
{
|
||||
"block_name": "TestLAD",
|
||||
"block_number": 2,
|
||||
"language": "LAD",
|
||||
"block_comment": "",
|
||||
"interface": {
|
||||
"Temp": [
|
||||
{
|
||||
"name": "mWaterMaxFlow",
|
||||
"datatype": "Real"
|
||||
},
|
||||
{
|
||||
"name": "mWaterMinFlow",
|
||||
"datatype": "Real"
|
||||
},
|
||||
{
|
||||
"name": "mSyrupMaxFlow",
|
||||
"datatype": "Real"
|
||||
},
|
||||
{
|
||||
"name": "mSyrupMinFlow",
|
||||
"datatype": "Real"
|
||||
},
|
||||
{
|
||||
"name": "mMinRatio",
|
||||
"datatype": "Real"
|
||||
},
|
||||
{
|
||||
"name": "mMaxRatio",
|
||||
"datatype": "Real"
|
||||
},
|
||||
{
|
||||
"name": "mBevBrixMax",
|
||||
"datatype": "Real"
|
||||
},
|
||||
{
|
||||
"name": "mBevBrixMin",
|
||||
"datatype": "Real"
|
||||
}
|
||||
],
|
||||
"Return": [
|
||||
{
|
||||
"name": "Ret_Val",
|
||||
"datatype": "Real"
|
||||
}
|
||||
]
|
||||
},
|
||||
"networks": [
|
||||
{
|
||||
"id": "9",
|
||||
"title": "",
|
||||
"comment": "",
|
||||
"language": "SCL",
|
||||
"logic": [
|
||||
{
|
||||
"instruction_uid": "SCL_9",
|
||||
"type": "RAW_SCL_CHUNK",
|
||||
"scl": "IF \"Blender_Variables\".gSP_H2O <> 0 THEN\n \"Blender_Variables\".gWaterVFMCalcError := \"Blender_Variables\".gWaterVFMMeasError / 100 * \"Blender_Variables\".gSP_H2O;\nEND_IF;\nIF \"Blender_Variables\".gSP_SYR <> 0 THEN\n \"Blender_Variables\".gSyrupMFMCalcError := (\"Blender_Variables\".gSyrupMFMMeasError / 100 + (\"Blender_Variables\".gSyrupMFMZeroStab / (\"Blender_Variables\".gSP_SYR * 60)) / 100) * \"Blender_Variables\".gSP_SYR;\nEND_IF;\nIF \"Blender_Variables\".gSP_CO2 <> 0 THEN\n \"Blender_Variables\".gCO2MFMCalcError := (\"Blender_Variables\".gCO2MFMMeasError / 100 + (\"Blender_Variables\".gCO2MFMZeroStab / (\"Blender_Variables\".gSP_CO2 * 60 / 1000)) / 100) * \"Blender_Variables\".gSP_CO2;\nEND_IF;\n\"mWaterMaxFlow\" := \"Blender_Variables\".gSP_H2O + \"Blender_Variables\".gWaterVFMCalcError;\n\"mWaterMinFlow\" := \"Blender_Variables\".gSP_H2O - \"Blender_Variables\".gWaterVFMCalcError;\nIF \"HMI_Blender_Parameters\".Actual_Recipe_Parameters._SyrupDensity <> 0 THEN\n \"mSyrupMaxFlow\" := (\"Blender_Variables\".gSP_SYR + \"Blender_Variables\".gSyrupMFMCalcError) / \"HMI_Blender_Parameters\".Actual_Recipe_Parameters._SyrupDensity;\n \"mSyrupMinFlow\" := (\"Blender_Variables\".gSP_SYR - \"Blender_Variables\".gSyrupMFMCalcError) / \"HMI_Blender_Parameters\".Actual_Recipe_Parameters._SyrupDensity;\nEND_IF;\nIF \"mSyrupMaxFlow\" <> 0 THEN\n \"mMinRatio\" := \"mWaterMinFlow\" / \"mSyrupMaxFlow\";\nEND_IF;\nIF \"mSyrupMinFlow\" <> 0 THEN\n \"mMaxRatio\" := \"mWaterMaxFlow\" / \"mSyrupMinFlow\";\nEND_IF;\nIF \"HMI_Blender_Parameters\".Actual_Recipe_Parameters._SyrupDensity <> 0 THEN\n \"mBevBrixMax\" := \"HMI_Blender_Parameters\".Actual_Recipe_Parameters._SyrupBrix / ((\"mMinRatio\" / \"HMI_Blender_Parameters\".Actual_Recipe_Parameters._SyrupDensity) + 1);\n \"mBevBrixMin\" := \"HMI_Blender_Parameters\".Actual_Recipe_Parameters._SyrupBrix / ((\"mMaxRatio\" / \"HMI_Blender_Parameters\".Actual_Recipe_Parameters._SyrupDensity) + 1);\nEND_IF;\n\"Blender_Variables\".gBlenderBlendMaxError := \"mBevBrixMax\" - \"mBevBrixMin\";\n\"TestLAD\" := \"Blender_Variables\".gBlenderBlendMaxError;"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
{
|
||||
"block_name": "TestLAD",
|
||||
"block_number": 2,
|
||||
"language": "LAD",
|
||||
"block_comment": "",
|
||||
"interface": {
|
||||
"Temp": [
|
||||
{
|
||||
"name": "mWaterMaxFlow",
|
||||
"datatype": "Real"
|
||||
},
|
||||
{
|
||||
"name": "mWaterMinFlow",
|
||||
"datatype": "Real"
|
||||
},
|
||||
{
|
||||
"name": "mSyrupMaxFlow",
|
||||
"datatype": "Real"
|
||||
},
|
||||
{
|
||||
"name": "mSyrupMinFlow",
|
||||
"datatype": "Real"
|
||||
},
|
||||
{
|
||||
"name": "mMinRatio",
|
||||
"datatype": "Real"
|
||||
},
|
||||
{
|
||||
"name": "mMaxRatio",
|
||||
"datatype": "Real"
|
||||
},
|
||||
{
|
||||
"name": "mBevBrixMax",
|
||||
"datatype": "Real"
|
||||
},
|
||||
{
|
||||
"name": "mBevBrixMin",
|
||||
"datatype": "Real"
|
||||
}
|
||||
],
|
||||
"Return": [
|
||||
{
|
||||
"name": "Ret_Val",
|
||||
"datatype": "Real"
|
||||
}
|
||||
]
|
||||
},
|
||||
"networks": [
|
||||
{
|
||||
"id": "9",
|
||||
"title": "",
|
||||
"comment": "",
|
||||
"language": "SCL",
|
||||
"logic": [
|
||||
{
|
||||
"instruction_uid": "SCL_9",
|
||||
"type": "RAW_SCL_CHUNK",
|
||||
"scl": "IF \"Blender_Variables\".gSP_H2O <> 0 THEN\n \"Blender_Variables\".gWaterVFMCalcError := \"Blender_Variables\".gWaterVFMMeasError / 100 * \"Blender_Variables\".gSP_H2O;\nEND_IF;\nIF \"Blender_Variables\".gSP_SYR <> 0 THEN\n \"Blender_Variables\".gSyrupMFMCalcError := (\"Blender_Variables\".gSyrupMFMMeasError / 100 + (\"Blender_Variables\".gSyrupMFMZeroStab / (\"Blender_Variables\".gSP_SYR * 60)) / 100) * \"Blender_Variables\".gSP_SYR;\nEND_IF;\nIF \"Blender_Variables\".gSP_CO2 <> 0 THEN\n \"Blender_Variables\".gCO2MFMCalcError := (\"Blender_Variables\".gCO2MFMMeasError / 100 + (\"Blender_Variables\".gCO2MFMZeroStab / (\"Blender_Variables\".gSP_CO2 * 60 / 1000)) / 100) * \"Blender_Variables\".gSP_CO2;\nEND_IF;\n\"mWaterMaxFlow\" := \"Blender_Variables\".gSP_H2O + \"Blender_Variables\".gWaterVFMCalcError;\n\"mWaterMinFlow\" := \"Blender_Variables\".gSP_H2O - \"Blender_Variables\".gWaterVFMCalcError;\nIF \"HMI_Blender_Parameters\".Actual_Recipe_Parameters._SyrupDensity <> 0 THEN\n \"mSyrupMaxFlow\" := (\"Blender_Variables\".gSP_SYR + \"Blender_Variables\".gSyrupMFMCalcError) / \"HMI_Blender_Parameters\".Actual_Recipe_Parameters._SyrupDensity;\n \"mSyrupMinFlow\" := (\"Blender_Variables\".gSP_SYR - \"Blender_Variables\".gSyrupMFMCalcError) / \"HMI_Blender_Parameters\".Actual_Recipe_Parameters._SyrupDensity;\nEND_IF;\nIF \"mSyrupMaxFlow\" <> 0 THEN\n \"mMinRatio\" := \"mWaterMinFlow\" / \"mSyrupMaxFlow\";\nEND_IF;\nIF \"mSyrupMinFlow\" <> 0 THEN\n \"mMaxRatio\" := \"mWaterMaxFlow\" / \"mSyrupMinFlow\";\nEND_IF;\nIF \"HMI_Blender_Parameters\".Actual_Recipe_Parameters._SyrupDensity <> 0 THEN\n \"mBevBrixMax\" := \"HMI_Blender_Parameters\".Actual_Recipe_Parameters._SyrupBrix / ((\"mMinRatio\" / \"HMI_Blender_Parameters\".Actual_Recipe_Parameters._SyrupDensity) + 1);\n \"mBevBrixMin\" := \"HMI_Blender_Parameters\".Actual_Recipe_Parameters._SyrupBrix / ((\"mMaxRatio\" / \"HMI_Blender_Parameters\".Actual_Recipe_Parameters._SyrupDensity) + 1);\nEND_IF;\n\"Blender_Variables\".gBlenderBlendMaxError := \"mBevBrixMax\" - \"mBevBrixMin\";\n\"TestLAD\" := \"Blender_Variables\".gBlenderBlendMaxError;"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
// Block Name (Original): TestLAD
|
||||
// Block Number: 2
|
||||
// Original Language: LAD
|
||||
|
||||
FUNCTION_BLOCK "TestLAD"
|
||||
{ S7_Optimized_Access := 'TRUE' }
|
||||
VERSION : 0.1
|
||||
|
||||
VAR_RETURN
|
||||
Ret_Val : Real;
|
||||
END_VAR
|
||||
|
||||
VAR_TEMP
|
||||
mWaterMaxFlow : Real;
|
||||
mWaterMinFlow : Real;
|
||||
mSyrupMaxFlow : Real;
|
||||
mSyrupMinFlow : Real;
|
||||
mMinRatio : Real;
|
||||
mMaxRatio : Real;
|
||||
mBevBrixMax : Real;
|
||||
mBevBrixMin : Real;
|
||||
END_VAR
|
||||
|
||||
BEGIN
|
||||
|
||||
// Network 1: (Original Language: SCL)
|
||||
|
||||
IF "Blender_Variables".gSP_H2O <> 0 THEN
|
||||
"Blender_Variables".gWaterVFMCalcError := "Blender_Variables".gWaterVFMMeasError / 100 * "Blender_Variables".gSP_H2O;
|
||||
END_IF;
|
||||
IF "Blender_Variables".gSP_SYR <> 0 THEN
|
||||
"Blender_Variables".gSyrupMFMCalcError := ("Blender_Variables".gSyrupMFMMeasError / 100 + ("Blender_Variables".gSyrupMFMZeroStab / ("Blender_Variables".gSP_SYR * 60)) / 100) * "Blender_Variables".gSP_SYR;
|
||||
END_IF;
|
||||
IF "Blender_Variables".gSP_CO2 <> 0 THEN
|
||||
"Blender_Variables".gCO2MFMCalcError := ("Blender_Variables".gCO2MFMMeasError / 100 + ("Blender_Variables".gCO2MFMZeroStab / ("Blender_Variables".gSP_CO2 * 60 / 1000)) / 100) * "Blender_Variables".gSP_CO2;
|
||||
END_IF;
|
||||
"mWaterMaxFlow" := "Blender_Variables".gSP_H2O + "Blender_Variables".gWaterVFMCalcError;
|
||||
"mWaterMinFlow" := "Blender_Variables".gSP_H2O - "Blender_Variables".gWaterVFMCalcError;
|
||||
IF "HMI_Blender_Parameters".Actual_Recipe_Parameters._SyrupDensity <> 0 THEN
|
||||
"mSyrupMaxFlow" := ("Blender_Variables".gSP_SYR + "Blender_Variables".gSyrupMFMCalcError) / "HMI_Blender_Parameters".Actual_Recipe_Parameters._SyrupDensity;
|
||||
"mSyrupMinFlow" := ("Blender_Variables".gSP_SYR - "Blender_Variables".gSyrupMFMCalcError) / "HMI_Blender_Parameters".Actual_Recipe_Parameters._SyrupDensity;
|
||||
END_IF;
|
||||
IF "mSyrupMaxFlow" <> 0 THEN
|
||||
"mMinRatio" := "mWaterMinFlow" / "mSyrupMaxFlow";
|
||||
END_IF;
|
||||
IF "mSyrupMinFlow" <> 0 THEN
|
||||
"mMaxRatio" := "mWaterMaxFlow" / "mSyrupMinFlow";
|
||||
END_IF;
|
||||
IF "HMI_Blender_Parameters".Actual_Recipe_Parameters._SyrupDensity <> 0 THEN
|
||||
"mBevBrixMax" := "HMI_Blender_Parameters".Actual_Recipe_Parameters._SyrupBrix / (("mMinRatio" / "HMI_Blender_Parameters".Actual_Recipe_Parameters._SyrupDensity) + 1);
|
||||
"mBevBrixMin" := "HMI_Blender_Parameters".Actual_Recipe_Parameters._SyrupBrix / (("mMaxRatio" / "HMI_Blender_Parameters".Actual_Recipe_Parameters._SyrupDensity) + 1);
|
||||
END_IF;
|
||||
"Blender_Variables".gBlenderBlendMaxError := "mBevBrixMax" - "mBevBrixMin";
|
||||
"TestLAD" := "Blender_Variables".gBlenderBlendMaxError;
|
||||
|
||||
END_FUNCTION_BLOCK
|
|
@ -1,763 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Document>
|
||||
<Engineering version="V18" />
|
||||
<SW.Blocks.FC ID="0">
|
||||
<AttributeList>
|
||||
<Interface><Sections xmlns="http://www.siemens.com/automation/Openness/SW/Interface/v5">
|
||||
<Section Name="Input" />
|
||||
<Section Name="Output" />
|
||||
<Section Name="InOut" />
|
||||
<Section Name="Temp">
|
||||
<Member Name="All_Auto_RETVAL" Datatype="Int" />
|
||||
<Member Name="Reset_SP_Word_RETVAL" Datatype="Int" />
|
||||
<Member Name="mResetWaterTot" Datatype="Bool" />
|
||||
<Member Name="mResetSyrupTot" Datatype="Bool" />
|
||||
<Member Name="mResetCO2Tot" Datatype="Bool" />
|
||||
<Member Name="mResetProductTot" Datatype="Bool" />
|
||||
<Member Name="Block_Move_Err" Datatype="Int" />
|
||||
<Member Name="Dim_HMI_Device" Datatype="Int" />
|
||||
<Member Name="PDim_HMI_Device" Datatype="DWord" />
|
||||
<Member Name="Dim_HMI_PID" Datatype="Int" />
|
||||
<Member Name="PDim_HMI_PID" Datatype="DWord" />
|
||||
</Section>
|
||||
<Section Name="Constant" />
|
||||
<Section Name="Return">
|
||||
<Member Name="Ret_Val" Datatype="Void" />
|
||||
</Section>
|
||||
</Sections></Interface>
|
||||
<MemoryLayout>Optimized</MemoryLayout>
|
||||
<Name>TestLAD</Name>
|
||||
<Namespace />
|
||||
<Number>2</Number>
|
||||
<ProgrammingLanguage>LAD</ProgrammingLanguage>
|
||||
<SetENOAutomatically>false</SetENOAutomatically>
|
||||
</AttributeList>
|
||||
<ObjectList>
|
||||
<MultilingualText ID="1" CompositionName="Comment">
|
||||
<ObjectList>
|
||||
<MultilingualTextItem ID="2" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>it-IT</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="3" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>de-DE</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="4" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>en-US</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="5" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>es-ES</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="6" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>fr-FR</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="7" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>zh-CN</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="8" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>ja-JP</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
</ObjectList>
|
||||
</MultilingualText>
|
||||
<SW.Blocks.CompileUnit ID="9" CompositionName="CompileUnits">
|
||||
<AttributeList>
|
||||
<NetworkSource><StatementList xmlns="http://www.siemens.com/automation/Openness/SW/NetworkSource/StatementList/v4">
|
||||
<StlStatement UId="24">
|
||||
<StlToken Text="SET" />
|
||||
</StlStatement>
|
||||
<StlStatement UId="25">
|
||||
<StlToken Text="R" />
|
||||
<Access Scope="GlobalVariable">
|
||||
<Symbol>
|
||||
<Component Name="HMI_Alarms" />
|
||||
<Component Name="gH_Message" AccessModifier="Array">
|
||||
<Access Scope="LiteralConstant">
|
||||
<Constant>
|
||||
<ConstantType>DInt</ConstantType>
|
||||
<ConstantValue>3</ConstantValue>
|
||||
</Constant>
|
||||
</Access>
|
||||
</Component>
|
||||
</Symbol>
|
||||
</Access>
|
||||
</StlStatement>
|
||||
</StatementList></NetworkSource>
|
||||
<ProgrammingLanguage>STL</ProgrammingLanguage>
|
||||
</AttributeList>
|
||||
<ObjectList>
|
||||
<MultilingualText ID="A" CompositionName="Comment">
|
||||
<ObjectList>
|
||||
<MultilingualTextItem ID="B" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>it-IT</Culture>
|
||||
<Text> DEVICE</Text>
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="C" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>de-DE</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="D" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>en-US</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="E" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>es-ES</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="F" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>fr-FR</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="10" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>zh-CN</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="11" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>ja-JP</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
</ObjectList>
|
||||
</MultilingualText>
|
||||
<MultilingualText ID="12" CompositionName="Title">
|
||||
<ObjectList>
|
||||
<MultilingualTextItem ID="13" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>it-IT</Culture>
|
||||
<Text>Set manual active</Text>
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="14" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>de-DE</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="15" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>en-US</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="16" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>es-ES</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="17" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>fr-FR</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="18" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>zh-CN</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="19" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>ja-JP</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
</ObjectList>
|
||||
</MultilingualText>
|
||||
</ObjectList>
|
||||
</SW.Blocks.CompileUnit>
|
||||
<SW.Blocks.CompileUnit ID="1A" CompositionName="CompileUnits">
|
||||
<AttributeList>
|
||||
<NetworkSource><StatementList xmlns="http://www.siemens.com/automation/Openness/SW/NetworkSource/StatementList/v4">
|
||||
<StlStatement UId="24">
|
||||
<StlToken Text="OPEN_DB" />
|
||||
<Access Scope="GlobalVariable">
|
||||
<Symbol>
|
||||
<Component Name="HMI_Device" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
</StlStatement>
|
||||
<StlStatement UId="26">
|
||||
<StlToken Text="L_DBLG" />
|
||||
</StlStatement>
|
||||
<StlStatement UId="27">
|
||||
<StlToken Text="T" />
|
||||
<Access Scope="LocalVariable">
|
||||
<Symbol>
|
||||
<Component Name="Dim_HMI_Device" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
</StlStatement>
|
||||
<StlStatement UId="29">
|
||||
<StlToken Text="L" />
|
||||
<Access Scope="LiteralConstant">
|
||||
<Constant>
|
||||
<ConstantType>ARef</ConstantType>
|
||||
<ConstantValue>P#0.0</ConstantValue>
|
||||
</Constant>
|
||||
</Access>
|
||||
</StlStatement>
|
||||
<StlStatement UId="31">
|
||||
<StlToken Text="L" />
|
||||
<Access Scope="LocalVariable">
|
||||
<Symbol>
|
||||
<Component Name="Dim_HMI_Device" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
</StlStatement>
|
||||
<StlStatement UId="33">
|
||||
<StlToken Text="SLD" />
|
||||
<Access Scope="LiteralConstant">
|
||||
<Constant>
|
||||
<ConstantType>Int</ConstantType>
|
||||
<ConstantValue>3</ConstantValue>
|
||||
</Constant>
|
||||
</Access>
|
||||
</StlStatement>
|
||||
<StlStatement UId="35">
|
||||
<StlToken Text="ADD_D" />
|
||||
</StlStatement>
|
||||
<StlStatement UId="36">
|
||||
<StlToken Text="T" />
|
||||
<Access Scope="LocalVariable">
|
||||
<Symbol>
|
||||
<Component Name="PDim_HMI_Device" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
</StlStatement>
|
||||
<StlStatement UId="38">
|
||||
<StlToken Text="L" />
|
||||
<Access Scope="LiteralConstant">
|
||||
<Constant>
|
||||
<ConstantType>ARef</ConstantType>
|
||||
<ConstantValue>P#0.0</ConstantValue>
|
||||
</Constant>
|
||||
</Access>
|
||||
</StlStatement>
|
||||
<StlStatement UId="40">
|
||||
<StlToken Text="LAR1_ACCU1" />
|
||||
</StlStatement>
|
||||
<StlStatement UId="41">
|
||||
<LabelDeclaration>
|
||||
<Label Name="M100" />
|
||||
</LabelDeclaration>
|
||||
<StlToken Text="NOP_0" />
|
||||
</StlStatement>
|
||||
<StlStatement UId="43">
|
||||
<StlToken Text="OPEN_DB" />
|
||||
<Access Scope="GlobalVariable">
|
||||
<Symbol>
|
||||
<Component Name="HMI_Device" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
</StlStatement>
|
||||
<StlStatement UId="45">
|
||||
<StlToken Text="A" />
|
||||
<Access Scope="Address">
|
||||
<Indirect Width="Bit" Area="DB" Register="AR1" BitOffset="7" />
|
||||
<LineComment>
|
||||
<Text> config</Text>
|
||||
</LineComment>
|
||||
</Access>
|
||||
</StlStatement>
|
||||
<StlStatement UId="48">
|
||||
<StlToken Text="AN" />
|
||||
<Access Scope="Address">
|
||||
<Indirect Width="Bit" Area="DB" Register="AR1" BitOffset="0" />
|
||||
<LineComment>
|
||||
<Text> auto</Text>
|
||||
</LineComment>
|
||||
</Access>
|
||||
</StlStatement>
|
||||
<StlStatement UId="51">
|
||||
<StlToken Text="S" />
|
||||
<Access Scope="GlobalVariable">
|
||||
<Symbol>
|
||||
<Component Name="HMI_Alarms" />
|
||||
<Component Name="gH_Message" AccessModifier="Array">
|
||||
<Access Scope="LiteralConstant">
|
||||
<Constant>
|
||||
<ConstantType>DInt</ConstantType>
|
||||
<ConstantValue>3</ConstantValue>
|
||||
</Constant>
|
||||
</Access>
|
||||
</Component>
|
||||
</Symbol>
|
||||
</Access>
|
||||
</StlStatement>
|
||||
<StlStatement UId="53">
|
||||
<StlToken Text="ADDAR1" />
|
||||
<Access Scope="LiteralConstant">
|
||||
<Constant>
|
||||
<ConstantType>ARef</ConstantType>
|
||||
<ConstantValue>P#2.0</ConstantValue>
|
||||
</Constant>
|
||||
</Access>
|
||||
</StlStatement>
|
||||
<StlStatement UId="55">
|
||||
<StlToken Text="TAR1_ACCU1" />
|
||||
</StlStatement>
|
||||
<StlStatement UId="56">
|
||||
<StlToken Text="L" />
|
||||
<Access Scope="LocalVariable">
|
||||
<Symbol>
|
||||
<Component Name="PDim_HMI_Device" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
</StlStatement>
|
||||
<StlStatement UId="58">
|
||||
<StlToken Text="LT_D" />
|
||||
</StlStatement>
|
||||
<StlStatement UId="59">
|
||||
<StlToken Text="JC" />
|
||||
<Access Scope="Label">
|
||||
<Label Name="M100" />
|
||||
</Access>
|
||||
</StlStatement>
|
||||
</StatementList></NetworkSource>
|
||||
<ProgrammingLanguage>STL</ProgrammingLanguage>
|
||||
</AttributeList>
|
||||
<ObjectList>
|
||||
<MultilingualText ID="1B" CompositionName="Comment">
|
||||
<ObjectList>
|
||||
<MultilingualTextItem ID="1C" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>it-IT</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="1D" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>de-DE</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="1E" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>en-US</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="1F" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>es-ES</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="20" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>fr-FR</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="21" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>zh-CN</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="22" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>ja-JP</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
</ObjectList>
|
||||
</MultilingualText>
|
||||
<MultilingualText ID="23" CompositionName="Title">
|
||||
<ObjectList>
|
||||
<MultilingualTextItem ID="24" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>it-IT</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="25" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>de-DE</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="26" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>en-US</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="27" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>es-ES</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="28" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>fr-FR</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="29" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>zh-CN</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="2A" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>ja-JP</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
</ObjectList>
|
||||
</MultilingualText>
|
||||
</ObjectList>
|
||||
</SW.Blocks.CompileUnit>
|
||||
<SW.Blocks.CompileUnit ID="2B" CompositionName="CompileUnits">
|
||||
<AttributeList>
|
||||
<NetworkSource><StatementList xmlns="http://www.siemens.com/automation/Openness/SW/NetworkSource/StatementList/v4">
|
||||
<StlStatement UId="24">
|
||||
<LineComment>
|
||||
<Text> PID</Text>
|
||||
</LineComment>
|
||||
<StlToken Text="COMMENT" />
|
||||
</StlStatement>
|
||||
<StlStatement UId="26">
|
||||
<StlToken Text="OPEN_DB" />
|
||||
<Access Scope="GlobalVariable">
|
||||
<Symbol>
|
||||
<Component Name="HMI_PID" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
</StlStatement>
|
||||
<StlStatement UId="28">
|
||||
<StlToken Text="L_DBLG" />
|
||||
</StlStatement>
|
||||
<StlStatement UId="29">
|
||||
<StlToken Text="T" />
|
||||
<Access Scope="LocalVariable">
|
||||
<Symbol>
|
||||
<Component Name="Dim_HMI_PID" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
</StlStatement>
|
||||
<StlStatement UId="31">
|
||||
<StlToken Text="L" />
|
||||
<Access Scope="LiteralConstant">
|
||||
<Constant>
|
||||
<ConstantType>ARef</ConstantType>
|
||||
<ConstantValue>P#0.0</ConstantValue>
|
||||
</Constant>
|
||||
</Access>
|
||||
</StlStatement>
|
||||
<StlStatement UId="33">
|
||||
<StlToken Text="L" />
|
||||
<Access Scope="LocalVariable">
|
||||
<Symbol>
|
||||
<Component Name="Dim_HMI_PID" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
</StlStatement>
|
||||
<StlStatement UId="35">
|
||||
<StlToken Text="SLD" />
|
||||
<Access Scope="LiteralConstant">
|
||||
<Constant>
|
||||
<ConstantType>Int</ConstantType>
|
||||
<ConstantValue>3</ConstantValue>
|
||||
</Constant>
|
||||
</Access>
|
||||
</StlStatement>
|
||||
<StlStatement UId="37">
|
||||
<StlToken Text="ADD_D" />
|
||||
</StlStatement>
|
||||
<StlStatement UId="38">
|
||||
<StlToken Text="T" />
|
||||
<Access Scope="LocalVariable">
|
||||
<Symbol>
|
||||
<Component Name="PDim_HMI_PID" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
</StlStatement>
|
||||
<StlStatement UId="40">
|
||||
<StlToken Text="L" />
|
||||
<Access Scope="LiteralConstant">
|
||||
<Constant>
|
||||
<ConstantType>ARef</ConstantType>
|
||||
<ConstantValue>P#0.0</ConstantValue>
|
||||
</Constant>
|
||||
</Access>
|
||||
</StlStatement>
|
||||
<StlStatement UId="42">
|
||||
<StlToken Text="LAR1_ACCU1" />
|
||||
</StlStatement>
|
||||
<StlStatement UId="43">
|
||||
<LabelDeclaration>
|
||||
<Label Name="M101" />
|
||||
</LabelDeclaration>
|
||||
<StlToken Text="NOP_0" />
|
||||
</StlStatement>
|
||||
<StlStatement UId="45">
|
||||
<StlToken Text="OPEN_DB" />
|
||||
<Access Scope="GlobalVariable">
|
||||
<Symbol>
|
||||
<Component Name="HMI_PID" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
</StlStatement>
|
||||
<StlStatement UId="47">
|
||||
<StlToken Text="A" />
|
||||
<Access Scope="Address">
|
||||
<Indirect Width="Bit" Area="DB" Register="AR1" BitOffset="7" />
|
||||
<LineComment>
|
||||
<Text> config</Text>
|
||||
</LineComment>
|
||||
</Access>
|
||||
</StlStatement>
|
||||
<StlStatement UId="50">
|
||||
<StlToken Text="A_BRACK" />
|
||||
</StlStatement>
|
||||
<StlStatement UId="51">
|
||||
<StlToken Text="A" />
|
||||
<Access Scope="Address">
|
||||
<Indirect Width="Bit" Area="DB" Register="AR1" BitOffset="16" />
|
||||
<LineComment>
|
||||
<Text> ManOut</Text>
|
||||
</LineComment>
|
||||
</Access>
|
||||
</StlStatement>
|
||||
<StlStatement UId="54">
|
||||
<StlToken Text="O" />
|
||||
<Access Scope="Address">
|
||||
<Indirect Width="Bit" Area="DB" Register="AR1" BitOffset="24" />
|
||||
<LineComment>
|
||||
<Text> LocalSP</Text>
|
||||
</LineComment>
|
||||
</Access>
|
||||
</StlStatement>
|
||||
<StlStatement UId="57">
|
||||
<StlToken Text="BRACKET" />
|
||||
</StlStatement>
|
||||
<StlStatement UId="58">
|
||||
<StlToken Text="S" />
|
||||
<Access Scope="GlobalVariable">
|
||||
<Symbol>
|
||||
<Component Name="HMI_Alarms" />
|
||||
<Component Name="gH_Message" AccessModifier="Array">
|
||||
<Access Scope="LiteralConstant">
|
||||
<Constant>
|
||||
<ConstantType>DInt</ConstantType>
|
||||
<ConstantValue>3</ConstantValue>
|
||||
</Constant>
|
||||
</Access>
|
||||
</Component>
|
||||
</Symbol>
|
||||
</Access>
|
||||
</StlStatement>
|
||||
<StlStatement UId="60">
|
||||
<StlToken Text="ADDAR1" />
|
||||
<Access Scope="LiteralConstant">
|
||||
<Constant>
|
||||
<ConstantType>ARef</ConstantType>
|
||||
<ConstantValue>P#76.0</ConstantValue>
|
||||
</Constant>
|
||||
</Access>
|
||||
</StlStatement>
|
||||
<StlStatement UId="62">
|
||||
<StlToken Text="TAR1_ACCU1" />
|
||||
</StlStatement>
|
||||
<StlStatement UId="63">
|
||||
<StlToken Text="L" />
|
||||
<Access Scope="LocalVariable">
|
||||
<Symbol>
|
||||
<Component Name="PDim_HMI_PID" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
</StlStatement>
|
||||
<StlStatement UId="65">
|
||||
<StlToken Text="LT_D" />
|
||||
</StlStatement>
|
||||
<StlStatement UId="66">
|
||||
<StlToken Text="JC" />
|
||||
<Access Scope="Label">
|
||||
<Label Name="M101" />
|
||||
</Access>
|
||||
</StlStatement>
|
||||
</StatementList></NetworkSource>
|
||||
<ProgrammingLanguage>STL</ProgrammingLanguage>
|
||||
</AttributeList>
|
||||
<ObjectList>
|
||||
<MultilingualText ID="2C" CompositionName="Comment">
|
||||
<ObjectList>
|
||||
<MultilingualTextItem ID="2D" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>it-IT</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="2E" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>de-DE</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="2F" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>en-US</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="30" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>es-ES</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="31" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>fr-FR</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="32" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>zh-CN</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="33" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>ja-JP</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
</ObjectList>
|
||||
</MultilingualText>
|
||||
<MultilingualText ID="34" CompositionName="Title">
|
||||
<ObjectList>
|
||||
<MultilingualTextItem ID="35" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>it-IT</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="36" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>de-DE</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="37" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>en-US</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="38" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>es-ES</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="39" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>fr-FR</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="3A" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>zh-CN</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="3B" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>ja-JP</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
</ObjectList>
|
||||
</MultilingualText>
|
||||
</ObjectList>
|
||||
</SW.Blocks.CompileUnit>
|
||||
<MultilingualText ID="3C" CompositionName="Title">
|
||||
<ObjectList>
|
||||
<MultilingualTextItem ID="3D" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>it-IT</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="3E" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>de-DE</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="3F" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>en-US</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="40" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>es-ES</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="41" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>fr-FR</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="42" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>zh-CN</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="43" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>ja-JP</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
</ObjectList>
|
||||
</MultilingualText>
|
||||
</ObjectList>
|
||||
</SW.Blocks.FC>
|
||||
</Document>
|
|
@ -1,101 +0,0 @@
|
|||
{
|
||||
"block_name": "TestLAD",
|
||||
"block_number": 2,
|
||||
"language": "LAD",
|
||||
"block_comment": "",
|
||||
"interface": {
|
||||
"Temp": [
|
||||
{
|
||||
"name": "All_Auto_RETVAL",
|
||||
"datatype": "Int"
|
||||
},
|
||||
{
|
||||
"name": "Reset_SP_Word_RETVAL",
|
||||
"datatype": "Int"
|
||||
},
|
||||
{
|
||||
"name": "mResetWaterTot",
|
||||
"datatype": "Bool"
|
||||
},
|
||||
{
|
||||
"name": "mResetSyrupTot",
|
||||
"datatype": "Bool"
|
||||
},
|
||||
{
|
||||
"name": "mResetCO2Tot",
|
||||
"datatype": "Bool"
|
||||
},
|
||||
{
|
||||
"name": "mResetProductTot",
|
||||
"datatype": "Bool"
|
||||
},
|
||||
{
|
||||
"name": "Block_Move_Err",
|
||||
"datatype": "Int"
|
||||
},
|
||||
{
|
||||
"name": "Dim_HMI_Device",
|
||||
"datatype": "Int"
|
||||
},
|
||||
{
|
||||
"name": "PDim_HMI_Device",
|
||||
"datatype": "DWord"
|
||||
},
|
||||
{
|
||||
"name": "Dim_HMI_PID",
|
||||
"datatype": "Int"
|
||||
},
|
||||
{
|
||||
"name": "PDim_HMI_PID",
|
||||
"datatype": "DWord"
|
||||
}
|
||||
],
|
||||
"Return": [
|
||||
{
|
||||
"name": "Ret_Val",
|
||||
"datatype": "Void"
|
||||
}
|
||||
]
|
||||
},
|
||||
"networks": [
|
||||
{
|
||||
"id": "9",
|
||||
"title": "Set manual active",
|
||||
"comment": "DEVICE",
|
||||
"language": "STL",
|
||||
"logic": [
|
||||
{
|
||||
"instruction_uid": "UNS_9",
|
||||
"type": "UNSUPPORTED_LANG",
|
||||
"scl": "// Network 9 uses unsupported language: STL\n"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "1A",
|
||||
"title": "",
|
||||
"comment": "",
|
||||
"language": "STL",
|
||||
"logic": [
|
||||
{
|
||||
"instruction_uid": "UNS_1A",
|
||||
"type": "UNSUPPORTED_LANG",
|
||||
"scl": "// Network 1A uses unsupported language: STL\n"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "2B",
|
||||
"title": "",
|
||||
"comment": "",
|
||||
"language": "STL",
|
||||
"logic": [
|
||||
{
|
||||
"instruction_uid": "UNS_2B",
|
||||
"type": "UNSUPPORTED_LANG",
|
||||
"scl": "// Network 2B uses unsupported language: STL\n"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,101 +0,0 @@
|
|||
{
|
||||
"block_name": "TestLAD",
|
||||
"block_number": 2,
|
||||
"language": "LAD",
|
||||
"block_comment": "",
|
||||
"interface": {
|
||||
"Temp": [
|
||||
{
|
||||
"name": "All_Auto_RETVAL",
|
||||
"datatype": "Int"
|
||||
},
|
||||
{
|
||||
"name": "Reset_SP_Word_RETVAL",
|
||||
"datatype": "Int"
|
||||
},
|
||||
{
|
||||
"name": "mResetWaterTot",
|
||||
"datatype": "Bool"
|
||||
},
|
||||
{
|
||||
"name": "mResetSyrupTot",
|
||||
"datatype": "Bool"
|
||||
},
|
||||
{
|
||||
"name": "mResetCO2Tot",
|
||||
"datatype": "Bool"
|
||||
},
|
||||
{
|
||||
"name": "mResetProductTot",
|
||||
"datatype": "Bool"
|
||||
},
|
||||
{
|
||||
"name": "Block_Move_Err",
|
||||
"datatype": "Int"
|
||||
},
|
||||
{
|
||||
"name": "Dim_HMI_Device",
|
||||
"datatype": "Int"
|
||||
},
|
||||
{
|
||||
"name": "PDim_HMI_Device",
|
||||
"datatype": "DWord"
|
||||
},
|
||||
{
|
||||
"name": "Dim_HMI_PID",
|
||||
"datatype": "Int"
|
||||
},
|
||||
{
|
||||
"name": "PDim_HMI_PID",
|
||||
"datatype": "DWord"
|
||||
}
|
||||
],
|
||||
"Return": [
|
||||
{
|
||||
"name": "Ret_Val",
|
||||
"datatype": "Void"
|
||||
}
|
||||
]
|
||||
},
|
||||
"networks": [
|
||||
{
|
||||
"id": "9",
|
||||
"title": "Set manual active",
|
||||
"comment": "DEVICE",
|
||||
"language": "STL",
|
||||
"logic": [
|
||||
{
|
||||
"instruction_uid": "UNS_9",
|
||||
"type": "UNSUPPORTED_LANG",
|
||||
"scl": "// Network 9 uses unsupported language: STL\n"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "1A",
|
||||
"title": "",
|
||||
"comment": "",
|
||||
"language": "STL",
|
||||
"logic": [
|
||||
{
|
||||
"instruction_uid": "UNS_1A",
|
||||
"type": "UNSUPPORTED_LANG",
|
||||
"scl": "// Network 1A uses unsupported language: STL\n"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "2B",
|
||||
"title": "",
|
||||
"comment": "",
|
||||
"language": "STL",
|
||||
"logic": [
|
||||
{
|
||||
"instruction_uid": "UNS_2B",
|
||||
"type": "UNSUPPORTED_LANG",
|
||||
"scl": "// Network 2B uses unsupported language: STL\n"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
// Block Name (Original): TestLAD
|
||||
// Block Number: 2
|
||||
// Original Language: LAD
|
||||
|
||||
FUNCTION_BLOCK "TestLAD"
|
||||
{ S7_Optimized_Access := 'TRUE' }
|
||||
VERSION : 0.1
|
||||
|
||||
VAR_RETURN
|
||||
Ret_Val : Void;
|
||||
END_VAR
|
||||
|
||||
VAR_TEMP
|
||||
All_Auto_RETVAL : Int;
|
||||
Reset_SP_Word_RETVAL : Int;
|
||||
mResetWaterTot : Bool;
|
||||
mResetSyrupTot : Bool;
|
||||
mResetCO2Tot : Bool;
|
||||
mResetProductTot : Bool;
|
||||
Block_Move_Err : Int;
|
||||
Dim_HMI_Device : Int;
|
||||
PDim_HMI_Device : DWord;
|
||||
Dim_HMI_PID : Int;
|
||||
PDim_HMI_PID : DWord;
|
||||
END_VAR
|
||||
|
||||
BEGIN
|
||||
|
||||
// Network 1: Set manual active (Original Language: STL)
|
||||
// DEVICE
|
||||
|
||||
// Network 9 uses unsupported language: STL
|
||||
|
||||
// Network 2: (Original Language: STL)
|
||||
|
||||
// Network 1A uses unsupported language: STL
|
||||
|
||||
// Network 3: (Original Language: STL)
|
||||
|
||||
// Network 2B uses unsupported language: STL
|
||||
|
||||
END_FUNCTION_BLOCK
|
|
@ -5,18 +5,21 @@ import sys
|
|||
import locale
|
||||
import glob # <--- Importar glob para buscar archivos
|
||||
|
||||
|
||||
# (Función get_console_encoding y variable CONSOLE_ENCODING como en la respuesta anterior)
|
||||
def get_console_encoding():
|
||||
"""Obtiene la codificación preferida de la consola, con fallback."""
|
||||
try:
|
||||
return locale.getpreferredencoding(False)
|
||||
except Exception:
|
||||
return 'cp1252'
|
||||
return "cp1252"
|
||||
|
||||
|
||||
CONSOLE_ENCODING = get_console_encoding()
|
||||
# Descomenta la siguiente línea si quieres ver la codificación detectada:
|
||||
# print(f"Detected console encoding: {CONSOLE_ENCODING}")
|
||||
|
||||
|
||||
# (Función run_script como en la respuesta anterior, usando CONSOLE_ENCODING)
|
||||
def run_script(script_name, xml_arg):
|
||||
"""Runs a given script with the specified XML file argument."""
|
||||
|
@ -24,12 +27,14 @@ def run_script(script_name, xml_arg):
|
|||
command = [sys.executable, script_path, xml_arg]
|
||||
print(f"\n--- Running {script_name} with argument: {xml_arg} ---")
|
||||
try:
|
||||
result = subprocess.run(command,
|
||||
result = subprocess.run(
|
||||
command,
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
encoding=CONSOLE_ENCODING,
|
||||
errors='replace') # 'replace' para evitar errores
|
||||
errors="replace",
|
||||
) # 'replace' para evitar errores
|
||||
|
||||
# Imprimir stdout y stderr
|
||||
# Eliminar saltos de línea extra al final si existen
|
||||
|
@ -49,8 +54,16 @@ def run_script(script_name, xml_arg):
|
|||
except subprocess.CalledProcessError as e:
|
||||
print(f"Error running {script_name}:")
|
||||
print(f"Return code: {e.returncode}")
|
||||
stdout_decoded = e.stdout.decode(CONSOLE_ENCODING, errors='replace').strip() if isinstance(e.stdout, bytes) else (e.stdout or "").strip()
|
||||
stderr_decoded = e.stderr.decode(CONSOLE_ENCODING, errors='replace').strip() if isinstance(e.stderr, bytes) else (e.stderr or "").strip()
|
||||
stdout_decoded = (
|
||||
e.stdout.decode(CONSOLE_ENCODING, errors="replace").strip()
|
||||
if isinstance(e.stdout, bytes)
|
||||
else (e.stdout or "").strip()
|
||||
)
|
||||
stderr_decoded = (
|
||||
e.stderr.decode(CONSOLE_ENCODING, errors="replace").strip()
|
||||
if isinstance(e.stderr, bytes)
|
||||
else (e.stderr or "").strip()
|
||||
)
|
||||
if stdout_decoded:
|
||||
print("--- Stdout ---")
|
||||
print(stdout_decoded)
|
||||
|
@ -63,12 +76,13 @@ def run_script(script_name, xml_arg):
|
|||
print(f"An unexpected error occurred while running {script_name}: {e}")
|
||||
return False
|
||||
|
||||
|
||||
# --- NUEVA FUNCIÓN PARA SELECCIONAR ARCHIVO ---
|
||||
def select_xml_file():
|
||||
"""Busca archivos .xml, los lista y pide al usuario que elija uno."""
|
||||
print("No XML file specified. Searching for XML files in current directory...")
|
||||
# Buscar archivos .xml en el directorio actual (.)
|
||||
xml_files = sorted(glob.glob('*.xml')) # sorted para orden alfabético
|
||||
xml_files = sorted(glob.glob("*.xml")) # sorted para orden alfabético
|
||||
|
||||
if not xml_files:
|
||||
print("Error: No .xml files found in the current directory.")
|
||||
|
@ -80,7 +94,9 @@ def select_xml_file():
|
|||
|
||||
while True:
|
||||
try:
|
||||
choice = input(f"Enter the number of the file to process (1-{len(xml_files)}): ")
|
||||
choice = input(
|
||||
f"Enter the number of the file to process (1-{len(xml_files)}): "
|
||||
)
|
||||
choice_num = int(choice)
|
||||
if 1 <= choice_num <= len(xml_files):
|
||||
selected_file = xml_files[choice_num - 1]
|
||||
|
@ -93,10 +109,106 @@ def select_xml_file():
|
|||
except EOFError: # Manejar si la entrada se cierra inesperadamente
|
||||
print("\nSelection cancelled.")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
# --- FIN NUEVA FUNCIÓN ---
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Imports necesarios para esta sección
|
||||
import os
|
||||
import sys
|
||||
import glob # Asegúrate de que glob esté importado al principio del archivo
|
||||
|
||||
# Directorio base donde buscar los archivos XML (relativo al script)
|
||||
base_search_dir = "XML Project"
|
||||
script_dir = os.path.dirname(__file__) # Directorio donde está x0_main.py
|
||||
xml_project_dir = os.path.join(script_dir, base_search_dir)
|
||||
|
||||
print(f"Buscando archivos XML recursivamente en: '{xml_project_dir}'")
|
||||
|
||||
# Verificar si el directorio 'XML Project' existe
|
||||
if not os.path.isdir(xml_project_dir):
|
||||
print(
|
||||
f"Error: El directorio '{xml_project_dir}' no existe o no es un directorio."
|
||||
)
|
||||
print(
|
||||
"Por favor, crea el directorio 'XML Project' en la misma carpeta que este script y coloca tus archivos XML dentro."
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
# Buscar todos los archivos .xml recursivamente dentro de xml_project_dir
|
||||
# Usamos os.path.join para construir la ruta de búsqueda correctamente
|
||||
# y '**/*.xml' para la recursividad con glob
|
||||
search_pattern = os.path.join(xml_project_dir, "**", "*.xml")
|
||||
xml_files_found = glob.glob(search_pattern, recursive=True)
|
||||
|
||||
if not xml_files_found:
|
||||
print(
|
||||
f"No se encontraron archivos XML en '{xml_project_dir}' o sus subdirectorios."
|
||||
)
|
||||
sys.exit(0) # Salir limpiamente si no hay archivos
|
||||
|
||||
print(f"Se encontraron {len(xml_files_found)} archivos XML para procesar:")
|
||||
# Ordenar para un procesamiento predecible (opcional)
|
||||
xml_files_found.sort()
|
||||
for xml_file in xml_files_found:
|
||||
# Imprimir la ruta relativa desde el directorio del script para claridad
|
||||
print(f" - {os.path.relpath(xml_file, script_dir)}")
|
||||
|
||||
# Scripts a ejecutar en secuencia (asegúrate que los nombres son correctos)
|
||||
script1 = "x1_to_json.py"
|
||||
script2 = "x2_process.py"
|
||||
script3 = "x3_generate_scl.py"
|
||||
|
||||
# Procesar cada archivo encontrado
|
||||
processed_count = 0
|
||||
failed_count = 0
|
||||
for xml_filepath in xml_files_found:
|
||||
print(
|
||||
f"\n--- Iniciando pipeline para: {os.path.relpath(xml_filepath, script_dir)} ---"
|
||||
)
|
||||
|
||||
# Usar la ruta absoluta para evitar problemas si los scripts cambian de directorio
|
||||
absolute_xml_filepath = os.path.abspath(xml_filepath)
|
||||
|
||||
# Ejecutar los scripts en secuencia para el archivo actual
|
||||
# La función run_script ya está definida en tu script x0_main.py
|
||||
success = True
|
||||
if not run_script(script1, absolute_xml_filepath):
|
||||
print(
|
||||
f"\nPipeline falló en el script '{script1}' para el archivo: {os.path.relpath(xml_filepath, script_dir)}"
|
||||
)
|
||||
success = False
|
||||
elif not run_script(script2, absolute_xml_filepath):
|
||||
print(
|
||||
f"\nPipeline falló en el script '{script2}' para el archivo: {os.path.relpath(xml_filepath, script_dir)}"
|
||||
)
|
||||
success = False
|
||||
elif not run_script(script3, absolute_xml_filepath):
|
||||
print(
|
||||
f"\nPipeline falló en el script '{script3}' para el archivo: {os.path.relpath(xml_filepath, script_dir)}"
|
||||
)
|
||||
success = False
|
||||
|
||||
if success:
|
||||
print(
|
||||
f"--- Pipeline completado exitosamente para: {os.path.relpath(xml_filepath, script_dir)} ---"
|
||||
)
|
||||
processed_count += 1
|
||||
else:
|
||||
failed_count += 1
|
||||
print(
|
||||
f"--- Pipeline falló para: {os.path.relpath(xml_filepath, script_dir)} ---"
|
||||
)
|
||||
|
||||
print("\n--- Resumen Final del Procesamiento ---")
|
||||
print(f"Total de archivos XML encontrados: {len(xml_files_found)}")
|
||||
print(
|
||||
f"Archivos procesados exitosamente por el pipeline completo: {processed_count}"
|
||||
)
|
||||
print(f"Archivos que fallaron en algún punto del pipeline: {failed_count}")
|
||||
print("---------------------------------------")
|
||||
xml_filename = None
|
||||
|
||||
# Comprobar si se pasó un argumento de línea de comandos
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -23,36 +23,60 @@ SCL_SUFFIX = "_sympy_processed" # New suffix to indicate processing method
|
|||
GROUPED_COMMENT = "// Logic included in grouped IF"
|
||||
SIMPLIFIED_IF_COMMENT = "// Simplified IF condition by script" # May still be useful
|
||||
|
||||
|
||||
# Global data variable
|
||||
# Global data dictionary (consider passing 'data' as argument if needed elsewhere)
|
||||
# It's currently used by process_group_ifs implicitly via the outer scope,
|
||||
# which works but passing it explicitly might be cleaner.
|
||||
data = {}
|
||||
|
||||
|
||||
def process_group_ifs(instruction, network_id, sympy_map, symbol_manager, data):
|
||||
"""
|
||||
Busca condiciones (ya procesadas -> tienen expr SymPy en sympy_map)
|
||||
y, si habilitan un grupo (>1) de bloques funcionales (con SCL ya generado),
|
||||
construye el bloque IF agrupado CON LA CONDICIÓN SIMPLIFICADA.
|
||||
Modifica el campo 'scl' de la instrucción generadora de condición.
|
||||
(Esta es la implementación de la función como la tenías en el archivo original)
|
||||
"""
|
||||
instr_uid = instruction["instruction_uid"]
|
||||
instr_type_original = instruction.get("type", "").replace(SCL_SUFFIX, "").replace("_error", "")
|
||||
instr_type_original = (
|
||||
instruction.get("type", "").replace(SCL_SUFFIX, "").replace("_error", "")
|
||||
)
|
||||
made_change = False
|
||||
|
||||
# Check if this instruction *could* generate a condition suitable for grouping
|
||||
# It must have been processed by the new SymPy method
|
||||
if (
|
||||
not instruction.get("type", "").endswith(SCL_SUFFIX) # Check if processed by new method
|
||||
not instruction.get("type", "").endswith(
|
||||
SCL_SUFFIX
|
||||
) # Check if processed by new method
|
||||
or "_error" in instruction.get("type", "")
|
||||
or instruction.get("grouped", False)
|
||||
or instr_type_original not in [ # Original types that produce boolean results
|
||||
"Contact", "O", "Eq", "Ne", "Gt", "Lt", "Ge", "Le", "PBox", "NBox", "And", "Xor", "Not" # Add others like comparison
|
||||
or instr_type_original
|
||||
not in [ # Original types that produce boolean results
|
||||
"Contact",
|
||||
"O",
|
||||
"Eq",
|
||||
"Ne",
|
||||
"Gt",
|
||||
"Lt",
|
||||
"Ge",
|
||||
"Le",
|
||||
"PBox",
|
||||
"NBox",
|
||||
"And",
|
||||
"Xor",
|
||||
"Not", # Add others like comparison
|
||||
]
|
||||
):
|
||||
return False
|
||||
|
||||
# Avoid reagruping if SCL already contains a complex IF (less likely now)
|
||||
current_scl = instruction.get("scl", "")
|
||||
if current_scl.strip().startswith("IF") and "END_IF;" in current_scl and GROUPED_COMMENT not in current_scl:
|
||||
if (
|
||||
current_scl.strip().startswith("IF")
|
||||
and "END_IF;" in current_scl
|
||||
and GROUPED_COMMENT not in current_scl
|
||||
):
|
||||
return False
|
||||
|
||||
# *** Get the SymPy expression for the condition ***
|
||||
|
@ -60,20 +84,34 @@ def process_group_ifs(instruction, network_id, sympy_map, symbol_manager, data):
|
|||
sympy_condition_expr = sympy_map.get(map_key_out)
|
||||
|
||||
# No SymPy expression found or trivial conditions
|
||||
if sympy_condition_expr is None or sympy_condition_expr in [sympy.true, sympy.false]:
|
||||
if sympy_condition_expr is None or sympy_condition_expr in [
|
||||
sympy.true,
|
||||
sympy.false,
|
||||
]:
|
||||
return False
|
||||
|
||||
# --- Find consumer instructions (logic similar to before) ---
|
||||
grouped_instructions_cores = []
|
||||
consumer_instr_list = []
|
||||
network_logic = next((net["logic"] for net in data["networks"] if net["id"] == network_id), [])
|
||||
if not network_logic: return False
|
||||
network_logic = next(
|
||||
(net["logic"] for net in data["networks"] if net["id"] == network_id), []
|
||||
)
|
||||
if not network_logic:
|
||||
return False
|
||||
|
||||
groupable_types = [ # Types whose *final SCL* we want to group
|
||||
"Move", "Add", "Sub", "Mul", "Div", "Mod", "Convert",
|
||||
"Call_FC", "Call_FB", # Assuming these generate final SCL in their processors now
|
||||
"Move",
|
||||
"Add",
|
||||
"Sub",
|
||||
"Mul",
|
||||
"Div",
|
||||
"Mod",
|
||||
"Convert",
|
||||
"Call_FC",
|
||||
"Call_FB", # Assuming these generate final SCL in their processors now
|
||||
# SCoil/RCoil might also be groupable if their SCL is final assignment
|
||||
"SCoil", "RCoil"
|
||||
"SCoil",
|
||||
"RCoil",
|
||||
]
|
||||
|
||||
for consumer_instr in network_logic:
|
||||
|
@ -83,19 +121,27 @@ def process_group_ifs(instruction, network_id, sympy_map, symbol_manager, data):
|
|||
|
||||
consumer_en = consumer_instr.get("inputs", {}).get("en")
|
||||
consumer_type = consumer_instr.get("type", "") # Current type suffix matters
|
||||
consumer_type_original = consumer_type.replace(SCL_SUFFIX, "").replace("_error", "")
|
||||
consumer_type_original = consumer_type.replace(SCL_SUFFIX, "").replace(
|
||||
"_error", ""
|
||||
)
|
||||
|
||||
is_enabled_by_us = False
|
||||
if ( isinstance(consumer_en, dict) and consumer_en.get("type") == "connection" and
|
||||
consumer_en.get("source_instruction_uid") == instr_uid and
|
||||
consumer_en.get("source_pin") == "out"):
|
||||
if (
|
||||
isinstance(consumer_en, dict)
|
||||
and consumer_en.get("type") == "connection"
|
||||
and consumer_en.get("source_instruction_uid") == instr_uid
|
||||
and consumer_en.get("source_pin") == "out"
|
||||
):
|
||||
is_enabled_by_us = True
|
||||
|
||||
# Check if consumer is groupable AND has its final SCL generated
|
||||
# The suffix check needs adjustment based on how terminating processors set it.
|
||||
# Assuming processors like Move, Add, Call, SCoil, RCoil NOW generate final SCL and add a suffix.
|
||||
if ( is_enabled_by_us and consumer_type.endswith(SCL_SUFFIX) and # Or a specific "final_scl" suffix
|
||||
consumer_type_original in groupable_types ):
|
||||
if (
|
||||
is_enabled_by_us
|
||||
and consumer_type.endswith(SCL_SUFFIX) # Or a specific "final_scl" suffix
|
||||
and consumer_type_original in groupable_types
|
||||
):
|
||||
|
||||
consumer_scl = consumer_instr.get("scl", "")
|
||||
# Extract core SCL (logic is similar, maybe simpler if SCL is cleaner now)
|
||||
|
@ -103,9 +149,15 @@ def process_group_ifs(instruction, network_id, sympy_map, symbol_manager, data):
|
|||
if consumer_scl:
|
||||
# If consumer SCL itself is an IF generated by EN, take the body
|
||||
if consumer_scl.strip().startswith("IF"):
|
||||
match = re.search(r"THEN\s*(.*?)\s*END_IF;", consumer_scl, re.DOTALL | re.IGNORECASE)
|
||||
match = re.search(
|
||||
r"THEN\s*(.*?)\s*END_IF;",
|
||||
consumer_scl,
|
||||
re.DOTALL | re.IGNORECASE,
|
||||
)
|
||||
core_scl = match.group(1).strip() if match else None
|
||||
elif not consumer_scl.strip().startswith("//"): # Otherwise, take the whole line if not comment
|
||||
elif not consumer_scl.strip().startswith(
|
||||
"//"
|
||||
): # Otherwise, take the whole line if not comment
|
||||
core_scl = consumer_scl.strip()
|
||||
|
||||
if core_scl:
|
||||
|
@ -114,12 +166,16 @@ def process_group_ifs(instruction, network_id, sympy_map, symbol_manager, data):
|
|||
|
||||
# --- If groupable consumers found ---
|
||||
if len(grouped_instructions_cores) > 1:
|
||||
print(f"INFO: Agrupando {len(grouped_instructions_cores)} instr. bajo condición de {instr_type_original} UID {instr_uid}")
|
||||
print(
|
||||
f"INFO: Agrupando {len(grouped_instructions_cores)} instr. bajo condición de {instr_type_original} UID {instr_uid}"
|
||||
)
|
||||
|
||||
# *** Simplify the SymPy condition ***
|
||||
try:
|
||||
# simplified_expr = sympy.simplify_logic(sympy_condition_expr, force=True)
|
||||
simplified_expr = sympy.logic.boolalg.to_dnf(sympy_condition_expr, simplify=True)
|
||||
simplified_expr = sympy.logic.boolalg.to_dnf(
|
||||
sympy_condition_expr, simplify=True
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Error simplifying condition for grouping UID {instr_uid}: {e}")
|
||||
simplified_expr = sympy_condition_expr # Fallback
|
||||
|
@ -130,7 +186,9 @@ def process_group_ifs(instruction, network_id, sympy_map, symbol_manager, data):
|
|||
# *** Build the grouped IF SCL ***
|
||||
scl_grouped_lines = [f"IF {condition_scl_simplified} THEN"]
|
||||
for core_line in grouped_instructions_cores:
|
||||
indented_core = "\n".join([f" {line.strip()}" for line in core_line.splitlines()])
|
||||
indented_core = "\n".join(
|
||||
[f" {line.strip()}" for line in core_line.splitlines()]
|
||||
)
|
||||
scl_grouped_lines.append(indented_core)
|
||||
scl_grouped_lines.append("END_IF;")
|
||||
final_grouped_scl = "\n".join(scl_grouped_lines)
|
||||
|
@ -145,6 +203,7 @@ def process_group_ifs(instruction, network_id, sympy_map, symbol_manager, data):
|
|||
|
||||
return made_change
|
||||
|
||||
|
||||
def load_processors(processors_dir="processors"):
|
||||
"""
|
||||
Escanea el directorio, importa módulos, construye el mapa y una lista
|
||||
|
@ -168,7 +227,9 @@ def load_processors(processors_dir="processors"):
|
|||
try:
|
||||
module = importlib.import_module(full_module_name)
|
||||
|
||||
if hasattr(module, 'get_processor_info') and callable(module.get_processor_info):
|
||||
if hasattr(module, "get_processor_info") and callable(
|
||||
module.get_processor_info
|
||||
):
|
||||
processor_info = module.get_processor_info()
|
||||
info_list = []
|
||||
if isinstance(processor_info, dict):
|
||||
|
@ -176,29 +237,51 @@ def load_processors(processors_dir="processors"):
|
|||
elif isinstance(processor_info, list):
|
||||
info_list = processor_info
|
||||
else:
|
||||
print(f" Advertencia: get_processor_info en {full_module_name} devolvió tipo inesperado. Se ignora.")
|
||||
print(
|
||||
f" Advertencia: get_processor_info en {full_module_name} devolvió tipo inesperado. Se ignora."
|
||||
)
|
||||
continue
|
||||
|
||||
for info in info_list:
|
||||
if isinstance(info, dict) and 'type_name' in info and 'processor_func' in info:
|
||||
type_name = info['type_name'].lower()
|
||||
processor_func = info['processor_func']
|
||||
if (
|
||||
isinstance(info, dict)
|
||||
and "type_name" in info
|
||||
and "processor_func" in info
|
||||
):
|
||||
type_name = info["type_name"].lower()
|
||||
processor_func = info["processor_func"]
|
||||
# Obtener prioridad, usar default si no existe
|
||||
priority = info.get('priority', default_priority)
|
||||
priority = info.get("priority", default_priority)
|
||||
|
||||
if callable(processor_func):
|
||||
if type_name in processor_map:
|
||||
print(f" Advertencia: '{type_name}' en {full_module_name} sobrescribe definición anterior.")
|
||||
print(
|
||||
f" Advertencia: '{type_name}' en {full_module_name} sobrescribe definición anterior."
|
||||
)
|
||||
processor_map[type_name] = processor_func
|
||||
# Añadir a la lista para ordenar
|
||||
processor_list_unsorted.append({'priority': priority, 'type_name': type_name, 'func': processor_func})
|
||||
print(f" - Cargado '{type_name}' (Prio: {priority}) desde {module_name_rel}.py")
|
||||
processor_list_unsorted.append(
|
||||
{
|
||||
"priority": priority,
|
||||
"type_name": type_name,
|
||||
"func": processor_func,
|
||||
}
|
||||
)
|
||||
print(
|
||||
f" - Cargado '{type_name}' (Prio: {priority}) desde {module_name_rel}.py"
|
||||
)
|
||||
else:
|
||||
print(f" Advertencia: 'processor_func' para '{type_name}' en {full_module_name} no es callable.")
|
||||
print(
|
||||
f" Advertencia: 'processor_func' para '{type_name}' en {full_module_name} no es callable."
|
||||
)
|
||||
else:
|
||||
print(f" Advertencia: Entrada inválida en {full_module_name}: {info}")
|
||||
print(
|
||||
f" Advertencia: Entrada inválida en {full_module_name}: {info}"
|
||||
)
|
||||
else:
|
||||
print(f" Advertencia: Módulo {module_name_rel}.py no tiene 'get_processor_info'.")
|
||||
print(
|
||||
f" Advertencia: Módulo {module_name_rel}.py no tiene 'get_processor_info'."
|
||||
)
|
||||
|
||||
except ImportError as e:
|
||||
print(f"Error importando {full_module_name}: {e}")
|
||||
|
@ -207,162 +290,211 @@ def load_processors(processors_dir="processors"):
|
|||
traceback.print_exc()
|
||||
|
||||
# Ordenar la lista por prioridad (menor primero)
|
||||
processor_list_sorted = sorted(processor_list_unsorted, key=lambda x: x['priority'])
|
||||
processor_list_sorted = sorted(processor_list_unsorted, key=lambda x: x["priority"])
|
||||
|
||||
print(f"\nTotal de tipos de procesadores cargados: {len(processor_map)}")
|
||||
print(f"Orden de procesamiento por prioridad: {[item['type_name'] for item in processor_list_sorted]}")
|
||||
print(
|
||||
f"Orden de procesamiento por prioridad: {[item['type_name'] for item in processor_list_sorted]}"
|
||||
)
|
||||
|
||||
# Devolver el mapa (para lookup rápido si es necesario) y la lista ordenada
|
||||
return processor_map, processor_list_sorted
|
||||
|
||||
# --- Bucle Principal de Procesamiento (Modificado) ---
|
||||
|
||||
# --- Bucle Principal de Procesamiento (Modificado para STL) ---
|
||||
def process_json_to_scl(json_filepath):
|
||||
"""
|
||||
Lee el JSON simplificado, aplica los procesadores dinámicamente cargados
|
||||
siguiendo un orden de prioridad, y guarda el JSON procesado.
|
||||
Lee JSON simplificado, aplica procesadores dinámicos (ignorando redes STL y bloques DB),
|
||||
y guarda JSON procesado.
|
||||
"""
|
||||
global data # Necesario si process_group_ifs (definido fuera) accede a data globalmente.
|
||||
# Si process_group_ifs está definida DENTRO de process_json_to_scl,
|
||||
# no necesitarías global, ya que accedería a la 'data' local.
|
||||
# Lo más limpio es definir process_group_ifs fuera y pasarle 'data'
|
||||
# como argumento (como ya se hace). Así que 'global data' aquí es probablemente innecesario.
|
||||
# Eliminémoslo por ahora y aseguremos que data se pasa a process_group_ifs.
|
||||
global data
|
||||
|
||||
if not os.path.exists(json_filepath): print(f"Error: JSON no encontrado: {json_filepath}"); return
|
||||
if not os.path.exists(json_filepath):
|
||||
print(f"Error: JSON no encontrado: {json_filepath}")
|
||||
return
|
||||
print(f"Cargando JSON desde: {json_filepath}")
|
||||
try:
|
||||
with open(json_filepath, "r", encoding="utf-8") as f: data = json.load(f)
|
||||
except Exception as e: print(f"Error al cargar JSON: {e}"); traceback.print_exc(); return
|
||||
with open(json_filepath, "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
except Exception as e:
|
||||
print(f"Error al cargar JSON: {e}")
|
||||
traceback.print_exc()
|
||||
return
|
||||
|
||||
# --- Carga dinámica de procesadores (sin cambios) ---
|
||||
script_dir = os.path.dirname(__file__); processors_dir_path = os.path.join(script_dir, 'processors')
|
||||
# --- Obtener lenguaje del bloque principal ---
|
||||
block_language = data.get("language", "Unknown")
|
||||
block_type = data.get("block_type", "Unknown") # FC, FB, GlobalDB
|
||||
print(f"Procesando bloque tipo: {block_type}, Lenguaje principal: {block_language}")
|
||||
|
||||
# --- SI ES UN DB, SALTAR EL PROCESAMIENTO LÓGICO ---
|
||||
if block_language == "DB":
|
||||
print(
|
||||
"INFO: El bloque es un Data Block (DB). Saltando procesamiento lógico de x2."
|
||||
)
|
||||
# Simplemente guardamos una copia (o el mismo archivo si no se requiere sufijo)
|
||||
output_filename = json_filepath.replace(
|
||||
"_simplified.json", "_simplified_processed.json"
|
||||
)
|
||||
print(f"Guardando JSON de DB (sin cambios lógicos) en: {output_filename}")
|
||||
try:
|
||||
with open(output_filename, "w", encoding="utf-8") as f:
|
||||
json.dump(data, f, indent=4, ensure_ascii=False)
|
||||
print("Guardado de DB completado.")
|
||||
except Exception as e:
|
||||
print(f"Error Crítico al guardar JSON del DB: {e}")
|
||||
traceback.print_exc()
|
||||
return # <<< SALIR TEMPRANO PARA DBs
|
||||
|
||||
# --- SI NO ES DB, CONTINUAR CON EL PROCESAMIENTO LÓGICO (FC/FB) ---
|
||||
print("INFO: El bloque es FC/FB. Iniciando procesamiento lógico...")
|
||||
|
||||
script_dir = os.path.dirname(__file__)
|
||||
processors_dir_path = os.path.join(script_dir, "processors")
|
||||
processor_map, sorted_processors = load_processors(processors_dir_path)
|
||||
if not processor_map: print("Error crítico: No se cargaron procesadores. Abortando."); return
|
||||
if not processor_map:
|
||||
print("Error crítico: No se cargaron procesadores. Abortando.")
|
||||
return
|
||||
|
||||
# --- Crear mapas de acceso por red (sin cambios) ---
|
||||
network_access_maps = {}
|
||||
# ... (logic to populate network_access_maps remains the same) ...
|
||||
# Crear mapas de acceso por red (copiado/adaptado de versión anterior)
|
||||
for network in data.get("networks", []):
|
||||
net_id = network["id"]
|
||||
current_access_map = {}
|
||||
# Extraer todos los 'Access' usados en esta red
|
||||
for instr in network.get("logic", []):
|
||||
# Revisar Inputs
|
||||
for _, source in instr.get("inputs", {}).items():
|
||||
sources_to_check = (source if isinstance(source, list) else ([source] if isinstance(source, dict) else []))
|
||||
sources_to_check = (
|
||||
source
|
||||
if isinstance(source, list)
|
||||
else ([source] if isinstance(source, dict) else [])
|
||||
)
|
||||
for src in sources_to_check:
|
||||
if (isinstance(src, dict) and src.get("uid") and src.get("type") in ["variable", "constant"]):
|
||||
if (
|
||||
isinstance(src, dict)
|
||||
and src.get("uid")
|
||||
and src.get("type") in ["variable", "constant"]
|
||||
):
|
||||
current_access_map[src["uid"]] = src
|
||||
# Revisar Outputs
|
||||
for _, dest_list in instr.get("outputs", {}).items():
|
||||
if isinstance(dest_list, list):
|
||||
for dest in dest_list:
|
||||
if (isinstance(dest, dict) and dest.get("uid") and dest.get("type") in ["variable", "constant"]):
|
||||
if (
|
||||
isinstance(dest, dict)
|
||||
and dest.get("uid")
|
||||
and dest.get("type") in ["variable", "constant"]
|
||||
):
|
||||
current_access_map[dest["uid"]] = dest
|
||||
network_access_maps[net_id] = current_access_map
|
||||
|
||||
# --- Inicializar mapa SymPy y SymbolManager por red ---
|
||||
# Cada red puede tener su propio contexto de símbolos si es necesario,
|
||||
# pero un SymbolManager global suele ser suficiente si no hay colisiones graves.
|
||||
# Usaremos uno global por simplicidad ahora.
|
||||
symbol_manager = SymbolManager()
|
||||
sympy_map = {} # Mapa para resultados SymPy intermedios (expresiones)
|
||||
|
||||
sympy_map = {}
|
||||
max_passes = 30
|
||||
passes = 0
|
||||
processing_complete = False
|
||||
|
||||
print("\n--- Iniciando Bucle de Procesamiento Iterativo (con SymPy y prioridad) ---")
|
||||
print("\n--- Iniciando Bucle de Procesamiento Iterativo (FC/FB) ---")
|
||||
while passes < max_passes and not processing_complete:
|
||||
passes += 1
|
||||
made_change_in_base_pass = False # Renombrar: made_change_in_sympy_pass
|
||||
made_change_in_base_pass = False
|
||||
made_change_in_group_pass = False
|
||||
# made_change_in_simplify_pass = False # Ya no existe Fase 3
|
||||
print(f"\n--- Pase {passes} ---")
|
||||
num_processed_this_pass = 0 # Renombrar: num_sympy_processed_this_pass
|
||||
num_sympy_processed_this_pass = 0
|
||||
num_grouped_this_pass = 0
|
||||
# num_simplified_this_pass = 0 # Ya no existe Fase 3
|
||||
|
||||
# --- FASE 1: Procesadores Base (Ahora usan SymPy) ---
|
||||
# --- FASE 1: Procesadores Base (Ignorando STL) ---
|
||||
print(f" Fase 1 (SymPy Base - Orden por Prioridad):")
|
||||
num_sympy_processed_this_pass = 0 # Contador específico
|
||||
num_sympy_processed_this_pass = 0 # Resetear contador para el pase
|
||||
for processor_info in sorted_processors:
|
||||
current_type_name = processor_info['type_name']
|
||||
func_to_call = processor_info['func']
|
||||
|
||||
current_type_name = processor_info["type_name"]
|
||||
func_to_call = processor_info["func"]
|
||||
for network in data.get("networks", []):
|
||||
network_id = network["id"]
|
||||
network_lang = network.get("language", "LAD")
|
||||
if network_lang == "STL":
|
||||
continue # Saltar STL
|
||||
|
||||
access_map = network_access_maps.get(network_id, {})
|
||||
network_logic = network.get("logic", [])
|
||||
|
||||
for instruction in network_logic:
|
||||
instr_uid = instruction.get("instruction_uid")
|
||||
instr_type_original = instruction.get("type", "Unknown")
|
||||
|
||||
# Saltar si ya está procesado con el NUEVO método, es error, o agrupado
|
||||
if (instr_type_original.endswith(SCL_SUFFIX) # Check new suffix
|
||||
if (
|
||||
instr_type_original.endswith(SCL_SUFFIX)
|
||||
or "_error" in instr_type_original
|
||||
or instruction.get("grouped", False)):
|
||||
or instruction.get("grouped", False)
|
||||
or instr_type_original
|
||||
in ["RAW_STL_CHUNK", "RAW_SCL_CHUNK", "UNSUPPORTED_LANG"]
|
||||
):
|
||||
continue
|
||||
|
||||
# Determinar tipo efectivo (como antes)
|
||||
lookup_key = instr_type_original.lower()
|
||||
effective_type_name = lookup_key
|
||||
if instr_type_original == "Call": # ... (manejo Call FC/FB) ...
|
||||
if instr_type_original == "Call":
|
||||
block_type = instruction.get("block_type", "").upper()
|
||||
if block_type == "FC": effective_type_name = "call_fc"
|
||||
elif block_type == "FB": effective_type_name = "call_fb"
|
||||
if block_type == "FC":
|
||||
effective_type_name = "call_fc"
|
||||
elif block_type == "FB":
|
||||
effective_type_name = "call_fb"
|
||||
|
||||
if effective_type_name == current_type_name:
|
||||
try:
|
||||
# *** Llamar al procesador refactorizado ***
|
||||
# Pasa sympy_map y symbol_manager, no scl_map
|
||||
changed = func_to_call(instruction, network_id, sympy_map, symbol_manager, data) # Pasamos SymbolManager
|
||||
changed = func_to_call(
|
||||
instruction, network_id, sympy_map, symbol_manager, data
|
||||
)
|
||||
if changed:
|
||||
made_change_in_base_pass = True
|
||||
num_sympy_processed_this_pass += 1
|
||||
except Exception as e:
|
||||
print(f"ERROR(SymPy Base) al procesar {instr_type_original} UID {instr_uid}: {e}")
|
||||
print(
|
||||
f"ERROR(SymPy Base) al procesar {instr_type_original} UID {instr_uid}: {e}"
|
||||
)
|
||||
traceback.print_exc()
|
||||
instruction["scl"] = f"// ERROR en SymPy procesador base: {e}"
|
||||
instruction["scl"] = (
|
||||
f"// ERROR en SymPy procesador base: {e}"
|
||||
)
|
||||
instruction["type"] = instr_type_original + "_error"
|
||||
made_change_in_base_pass = True
|
||||
print(f" -> {num_sympy_processed_this_pass} instrucciones procesadas con SymPy.")
|
||||
print(
|
||||
f" -> {num_sympy_processed_this_pass} instrucciones (no STL) procesadas con SymPy."
|
||||
)
|
||||
|
||||
|
||||
# --- FASE 2: Agrupación IF (Ahora usa SymPy para simplificar) ---
|
||||
# Ejecutar si hubo cambios en base o es el primer pase
|
||||
if made_change_in_base_pass or passes == 1:
|
||||
# --- FASE 2: Agrupación IF (Ignorando STL) ---
|
||||
if (
|
||||
made_change_in_base_pass or passes == 1
|
||||
): # Ejecutar siempre en el primer pase
|
||||
print(f" Fase 2 (Agrupación IF con Simplificación):")
|
||||
num_grouped_this_pass = 0 # Reiniciar contador
|
||||
num_grouped_this_pass = 0 # Resetear contador para el pase
|
||||
for network in data.get("networks", []):
|
||||
network_id = network["id"]
|
||||
# access_map = network_access_maps.get(network_id, {}) # No usado directamente por group_ifs
|
||||
network_lang = network.get("language", "LAD")
|
||||
if network_lang == "STL":
|
||||
continue # Saltar STL
|
||||
network_logic = network.get("logic", [])
|
||||
# Iterar sobre instrucciones que *pueden* generar condiciones booleanas
|
||||
for instruction in network_logic:
|
||||
# process_group_ifs ahora verifica internamente si la instr. fue procesada
|
||||
try:
|
||||
# *** Llamar a process_group_ifs adaptado ***
|
||||
group_changed = process_group_ifs(instruction, network_id, sympy_map, symbol_manager, data)
|
||||
group_changed = process_group_ifs(
|
||||
instruction, network_id, sympy_map, symbol_manager, data
|
||||
)
|
||||
if group_changed:
|
||||
made_change_in_group_pass = True
|
||||
num_grouped_this_pass += 1
|
||||
except Exception as e:
|
||||
print(f"ERROR(GroupLoop) al intentar agrupar desde UID {instruction.get('instruction_uid')}: {e}")
|
||||
print(
|
||||
f"ERROR(GroupLoop) al intentar agrupar desde UID {instruction.get('instruction_uid')}: {e}"
|
||||
)
|
||||
traceback.print_exc()
|
||||
print(f" -> {num_grouped_this_pass} agrupaciones realizadas.")
|
||||
|
||||
# --- FASE 3 Eliminada ---
|
||||
print(
|
||||
f" -> {num_grouped_this_pass} agrupaciones realizadas (en redes no STL)."
|
||||
)
|
||||
|
||||
# --- Comprobar si se completó el procesamiento ---
|
||||
# Solo considera Fase 1 (SymPy Base) y Fase 2 (Grouping)
|
||||
if not made_change_in_base_pass and not made_change_in_group_pass:
|
||||
print(f"\n--- No se hicieron más cambios en el pase {passes}. Proceso iterativo completado. ---")
|
||||
print(
|
||||
f"\n--- No se hicieron más cambios en el pase {passes}. Proceso iterativo completado. ---"
|
||||
)
|
||||
processing_complete = True
|
||||
else:
|
||||
# Mensaje de fin de pase actualizado
|
||||
print(f"--- Fin Pase {passes}: {num_sympy_processed_this_pass} proc SymPy, {num_grouped_this_pass} agrup. Continuando...")
|
||||
print(
|
||||
f"--- Fin Pase {passes}: {num_sympy_processed_this_pass} proc SymPy, {num_grouped_this_pass} agrup. Continuando..."
|
||||
)
|
||||
|
||||
# --- Comprobar límite de pases ---
|
||||
if passes == max_passes and not processing_complete:
|
||||
|
@ -370,48 +502,52 @@ def process_json_to_scl(json_filepath):
|
|||
|
||||
# --- FIN BUCLE ITERATIVO ---
|
||||
|
||||
# --- Verificación Final ---
|
||||
# La lógica aquí podría necesitar ajustes si el sufijo cambió o si el SCL final
|
||||
# solo se genera en instrucciones terminales.
|
||||
print("\n--- Verificación Final de Instrucciones No Procesadas ---")
|
||||
# --- Verificación Final (Ajustada para RAW_STL_CHUNK) ---
|
||||
print("\n--- Verificación Final de Instrucciones No Procesadas (FC/FB) ---")
|
||||
unprocessed_count = 0
|
||||
unprocessed_details = []
|
||||
ignored_types = ['raw_scl_chunk', 'unsupported_lang']
|
||||
|
||||
ignored_types = [
|
||||
"raw_scl_chunk",
|
||||
"unsupported_lang",
|
||||
"raw_stl_chunk",
|
||||
] # Añadido raw_stl_chunk
|
||||
for network in data.get("networks", []):
|
||||
network_id = network.get("id", "Unknown ID")
|
||||
network_title = network.get("title", f"Network {network_id}")
|
||||
network_lang = network.get("language", "LAD")
|
||||
if network_lang == "STL":
|
||||
continue # No verificar redes STL
|
||||
for instruction in network.get("logic", []):
|
||||
instr_uid = instruction.get("instruction_uid", "Unknown UID")
|
||||
instr_type = instruction.get("type", "Unknown Type")
|
||||
is_grouped = instruction.get("grouped", False)
|
||||
has_final_scl = bool(instruction.get("scl", "").strip()) and not instruction.get("scl", "").strip().startswith("//")
|
||||
|
||||
# Condición revisada: No tiene el sufijo nuevo Y no es error Y no está agrupada Y no es tipo ignorado
|
||||
# Y ADEMÁS, ¿debería tener SCL final si es una instr. terminal?
|
||||
# Simplificación: si no tiene sufijo, no es error, no agrupada, no ignorada -> problema
|
||||
if (not instr_type.endswith(SCL_SUFFIX) and
|
||||
"_error" not in instr_type and
|
||||
not is_grouped and
|
||||
instr_type.lower() not in ignored_types):
|
||||
if (
|
||||
not instr_type.endswith(SCL_SUFFIX)
|
||||
and "_error" not in instr_type
|
||||
and not is_grouped
|
||||
and instr_type.lower() not in ignored_types
|
||||
):
|
||||
unprocessed_count += 1
|
||||
unprocessed_details.append(
|
||||
f" - Red '{network_title}' (ID: {network_id}), "
|
||||
f"Instrucción UID: {instr_uid}, Tipo Original: '{instr_type}'"
|
||||
f" - Red '{network_title}' (ID: {network_id}, Lang: {network_lang}), "
|
||||
f"Instrucción UID: {instr_uid}, Tipo: '{instr_type}'"
|
||||
)
|
||||
# Opcional: añadir si tiene SCL o no
|
||||
# unprocessed_details[-1] += f" (Tiene SCL final: {has_final_scl})"
|
||||
|
||||
|
||||
if unprocessed_count > 0:
|
||||
print(f"ADVERTENCIA: Se encontraron {unprocessed_count} instrucciones que no fueron procesadas:")
|
||||
for detail in unprocessed_details: print(detail)
|
||||
print(
|
||||
f"ADVERTENCIA: Se encontraron {unprocessed_count} instrucciones (no STL) que parecen no haber sido procesadas:"
|
||||
)
|
||||
for detail in unprocessed_details:
|
||||
print(detail)
|
||||
else:
|
||||
print("INFO: Todas las instrucciones relevantes parecen haber sido procesadas o agrupadas.")
|
||||
print(
|
||||
"INFO: Todas las instrucciones relevantes (no STL) parecen haber sido procesadas o agrupadas."
|
||||
)
|
||||
|
||||
# --- Guardar JSON Final (sin cambios) ---
|
||||
output_filename = json_filepath.replace("_simplified.json", "_simplified_processed.json")
|
||||
print(f"\nGuardando JSON procesado en: {output_filename}")
|
||||
# --- Guardar JSON Final ---
|
||||
output_filename = json_filepath.replace(
|
||||
"_simplified.json", "_simplified_processed.json"
|
||||
)
|
||||
print(f"\nGuardando JSON procesado (FC/FB) en: {output_filename}")
|
||||
try:
|
||||
with open(output_filename, "w", encoding="utf-8") as f:
|
||||
json.dump(data, f, indent=4, ensure_ascii=False)
|
||||
|
@ -421,27 +557,67 @@ def process_json_to_scl(json_filepath):
|
|||
traceback.print_exc()
|
||||
|
||||
|
||||
# --- Ejecución (igual que antes) ---
|
||||
# --- Ejecución (sin cambios) ---
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Process simplified JSON to embed SCL logic.")
|
||||
parser.add_argument(
|
||||
"source_xml_filepath",
|
||||
nargs="?",
|
||||
default="TestLAD.xml",
|
||||
help="Path to the original source XML file (used to derive JSON input name, default: TestLAD.xml)"
|
||||
# Imports necesarios solo para la ejecución como script principal
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
|
||||
# Configurar ArgumentParser para recibir la ruta del XML original obligatoria
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Process simplified JSON (_simplified.json) to embed SCL logic (SymPy version). Expects original XML filepath as argument."
|
||||
)
|
||||
args = parser.parse_args()
|
||||
parser.add_argument(
|
||||
"source_xml_filepath", # Argumento posicional obligatorio
|
||||
help="Path to the original source XML file (passed from x0_main.py, used to derive JSON input name).",
|
||||
)
|
||||
args = parser.parse_args() # Parsea los argumentos de sys.argv
|
||||
|
||||
xml_filename_base = os.path.splitext(os.path.basename(args.source_xml_filepath))[0]
|
||||
# Usar directorio del script actual si el XML no tiene ruta, o la ruta del XML si la tiene
|
||||
xml_dir = os.path.dirname(args.source_xml_filepath)
|
||||
input_dir = xml_dir if xml_dir else os.path.dirname(__file__) # Directorio de entrada/salida
|
||||
source_xml_file = args.source_xml_filepath # Obtiene la ruta del XML original
|
||||
|
||||
# Verificar si el archivo XML original existe (como referencia, útil para depuración)
|
||||
# No es estrictamente necesario para la lógica aquí, pero ayuda a confirmar
|
||||
if not os.path.exists(source_xml_file):
|
||||
print(
|
||||
f"Advertencia (x2): Archivo XML original no encontrado: '{source_xml_file}', pero se intentará encontrar el JSON correspondiente."
|
||||
)
|
||||
# No salir necesariamente, pero es bueno saberlo.
|
||||
|
||||
# Derivar nombre del archivo JSON de entrada (_simplified.json)
|
||||
xml_filename_base = os.path.splitext(os.path.basename(source_xml_file))[0]
|
||||
# Asumir que el JSON simplificado está en el mismo directorio que el XML original
|
||||
input_dir = os.path.dirname(source_xml_file) # Directorio del XML original
|
||||
input_json_file = os.path.join(input_dir, f"{xml_filename_base}_simplified.json")
|
||||
|
||||
# Determinar el nombre esperado del archivo JSON procesado de salida
|
||||
output_json_file = os.path.join(
|
||||
input_dir, f"{xml_filename_base}_simplified_processed.json"
|
||||
)
|
||||
|
||||
print(
|
||||
f"(x2) Procesando: '{os.path.relpath(input_json_file)}' -> '{os.path.relpath(output_json_file)}'"
|
||||
)
|
||||
|
||||
# Verificar si el archivo JSON de entrada (_simplified.json) EXISTE antes de procesar
|
||||
if not os.path.exists(input_json_file):
|
||||
print(f"Error Fatal: El archivo de entrada JSON simplificado no existe: '{input_json_file}'")
|
||||
print(f"Asegúrate de haber ejecutado 'x1_to_json.py' primero sobre '{args.source_xml_filepath}'.")
|
||||
sys.exit(1)
|
||||
print(
|
||||
f"Error Fatal (x2): El archivo de entrada JSON simplificado no existe: '{input_json_file}'"
|
||||
)
|
||||
print(
|
||||
f"Asegúrate de que 'x1_to_json.py' se ejecutó correctamente para '{os.path.relpath(source_xml_file)}'."
|
||||
)
|
||||
sys.exit(1) # Salir si el archivo necesario no está
|
||||
else:
|
||||
# Llamar a la función principal de procesamiento del script
|
||||
# Asumiendo que tu función principal se llama process_json_to_scl(input_json_path)
|
||||
try:
|
||||
process_json_to_scl(input_json_file)
|
||||
except Exception as e:
|
||||
print(
|
||||
f"Error Crítico (x2) durante el procesamiento de '{input_json_file}': {e}"
|
||||
)
|
||||
import traceback
|
||||
|
||||
traceback.print_exc()
|
||||
sys.exit(1) # Salir con error si la función principal falla
|
||||
|
|
|
@ -11,260 +11,475 @@ import traceback # Importar traceback para errores
|
|||
try:
|
||||
# Intenta importar desde el paquete de procesadores si está estructurado así
|
||||
from processors.processor_utils import format_variable_name
|
||||
|
||||
# Definir SCL_SUFFIX aquí o importarlo si está centralizado
|
||||
SCL_SUFFIX = "_sympy_processed" # Asegúrate que coincida con x2_process.py
|
||||
GROUPED_COMMENT = "// Logic included in grouped IF" # Opcional, si se usa para filtrar
|
||||
GROUPED_COMMENT = (
|
||||
"// Logic included in grouped IF" # Opcional, si se usa para filtrar
|
||||
)
|
||||
except ImportError:
|
||||
print("Advertencia: No se pudo importar 'format_variable_name' desde processors.processor_utils.")
|
||||
print("Usando una implementación local básica (¡PUEDE FALLAR CON NOMBRES COMPLEJOS!).")
|
||||
print(
|
||||
"Advertencia: No se pudo importar 'format_variable_name' desde processors.processor_utils."
|
||||
)
|
||||
print(
|
||||
"Usando una implementación local básica (¡PUEDE FALLAR CON NOMBRES COMPLEJOS!)."
|
||||
)
|
||||
|
||||
# Implementación local BÁSICA como fallback (MENOS RECOMENDADA)
|
||||
def format_variable_name(name):
|
||||
if not name: return "_INVALID_NAME_"
|
||||
if name.startswith('"') and name.endswith('"'): return name # Mantener comillas
|
||||
if not name:
|
||||
return "_INVALID_NAME_"
|
||||
if name.startswith('"') and name.endswith('"'):
|
||||
return name # Mantener comillas
|
||||
prefix = "#" if name.startswith("#") else ""
|
||||
if prefix: name = name[1:]
|
||||
if name and name[0].isdigit(): name = "_" + name
|
||||
if prefix:
|
||||
name = name[1:]
|
||||
if name and name[0].isdigit():
|
||||
name = "_" + name
|
||||
name = re.sub(r"[^a-zA-Z0-9_]", "_", name)
|
||||
return prefix + name
|
||||
|
||||
SCL_SUFFIX = "_sympy_processed"
|
||||
GROUPED_COMMENT = "// Logic included in grouped IF"
|
||||
|
||||
|
||||
# --- Función Principal de Generación SCL ---
|
||||
# para formatear valores iniciales
|
||||
def format_scl_start_value(value, datatype):
|
||||
"""Formatea un valor para la inicialización SCL según el tipo."""
|
||||
if value is None:
|
||||
return None
|
||||
datatype_lower = datatype.lower() if datatype else ""
|
||||
value_str = str(value)
|
||||
|
||||
if "bool" in datatype_lower:
|
||||
return "TRUE" if value_str.lower() == "true" else "FALSE"
|
||||
elif "string" in datatype_lower:
|
||||
escaped_value = value_str.replace("'", "''")
|
||||
if escaped_value.startswith("'") and escaped_value.endswith("'"):
|
||||
escaped_value = escaped_value[1:-1]
|
||||
return f"'{escaped_value}'"
|
||||
elif "char" in datatype_lower: # Añadido Char
|
||||
escaped_value = value_str.replace("'", "''")
|
||||
if escaped_value.startswith("'") and escaped_value.endswith("'"):
|
||||
escaped_value = escaped_value[1:-1]
|
||||
return f"'{escaped_value}'"
|
||||
elif any(
|
||||
t in datatype_lower
|
||||
for t in [
|
||||
"int",
|
||||
"byte",
|
||||
"word",
|
||||
"dint",
|
||||
"dword",
|
||||
"lint",
|
||||
"lword",
|
||||
"sint",
|
||||
"usint",
|
||||
"uint",
|
||||
"udint",
|
||||
"ulint",
|
||||
]
|
||||
): # Ampliado
|
||||
try:
|
||||
return str(int(value_str))
|
||||
except ValueError:
|
||||
if re.match(r"^[a-zA-Z_][a-zA-Z0-9_]*$", value_str):
|
||||
return value_str
|
||||
return f"'{value_str}'" # O como string si no es entero ni símbolo
|
||||
elif "real" in datatype_lower or "lreal" in datatype_lower:
|
||||
try:
|
||||
f_val = float(value_str)
|
||||
s_val = str(f_val)
|
||||
if "." not in s_val and "e" not in s_val.lower():
|
||||
s_val += ".0"
|
||||
return s_val
|
||||
except ValueError:
|
||||
if re.match(r"^[a-zA-Z_][a-zA-Z0-9_]*$", value_str):
|
||||
return value_str
|
||||
return f"'{value_str}'"
|
||||
elif "time" in datatype_lower: # Añadido Time, S5Time, LTime
|
||||
# Quitar T#, LT#, S5T# si existen
|
||||
prefix = ""
|
||||
if value_str.upper().startswith("T#"):
|
||||
prefix = "T#"
|
||||
value_str = value_str[2:]
|
||||
elif value_str.upper().startswith("LT#"):
|
||||
prefix = "LT#"
|
||||
value_str = value_str[3:]
|
||||
elif value_str.upper().startswith("S5T#"):
|
||||
prefix = "S5T#"
|
||||
value_str = value_str[4:]
|
||||
# Devolver con el prefijo correcto o T# por defecto si no había
|
||||
if prefix:
|
||||
return f"{prefix}{value_str}"
|
||||
elif "s5time" in datatype_lower:
|
||||
return f"S5T#{value_str}"
|
||||
elif "ltime" in datatype_lower:
|
||||
return f"LT#{value_str}"
|
||||
else:
|
||||
return f"T#{value_str}" # Default a TIME
|
||||
elif "date" in datatype_lower: # Añadido Date, DT, TOD
|
||||
if value_str.upper().startswith("D#"):
|
||||
return value_str
|
||||
elif "dt" in datatype_lower or "date_and_time" in datatype_lower:
|
||||
if value_str.upper().startswith("DT#"):
|
||||
return value_str
|
||||
else:
|
||||
return f"DT#{value_str}" # Añadir prefijo DT#
|
||||
elif "tod" in datatype_lower or "time_of_day" in datatype_lower:
|
||||
if value_str.upper().startswith("TOD#"):
|
||||
return value_str
|
||||
else:
|
||||
return f"TOD#{value_str}" # Añadir prefijo TOD#
|
||||
else:
|
||||
return f"D#{value_str}" # Default a Date
|
||||
# Fallback genérico
|
||||
else:
|
||||
if re.match(
|
||||
r'^[a-zA-Z_][a-zA-Z0-9_."#\[\]]+$', value_str
|
||||
): # Permitir más caracteres en símbolos/tipos
|
||||
# Si es un UDT o Struct complejo, podría venir con comillas, quitarlas
|
||||
if value_str.startswith('"') and value_str.endswith('"'):
|
||||
return value_str[1:-1]
|
||||
return value_str
|
||||
else:
|
||||
escaped_value = value_str.replace("'", "''")
|
||||
return f"'{escaped_value}'"
|
||||
|
||||
|
||||
# --- NUEVA FUNCIÓN RECURSIVA para generar declaraciones SCL (VAR/STRUCT/ARRAY) ---
|
||||
def generate_scl_declarations(variables, indent_level=1):
|
||||
"""Genera las líneas SCL para declarar variables, structs y arrays."""
|
||||
scl_lines = []
|
||||
indent = " " * indent_level
|
||||
for var in variables:
|
||||
var_name_scl = format_variable_name(var.get("name"))
|
||||
var_dtype_raw = var.get("datatype", "VARIANT")
|
||||
# Limpiar comillas de tipos de datos UDT ("MyType" -> MyType)
|
||||
var_dtype = (
|
||||
var_dtype_raw.strip('"')
|
||||
if var_dtype_raw.startswith('"') and var_dtype_raw.endswith('"')
|
||||
else var_dtype_raw
|
||||
)
|
||||
|
||||
var_comment = var.get("comment")
|
||||
start_value = var.get("start_value")
|
||||
children = var.get("children") # Para structs
|
||||
array_elements = var.get("array_elements") # Para arrays
|
||||
|
||||
# Manejar tipos de datos Array especiales
|
||||
array_match = re.match(r"(Array\[.*\]\s+of\s+)(.*)", var_dtype, re.IGNORECASE)
|
||||
base_type_for_init = var_dtype
|
||||
declaration_dtype = var_dtype
|
||||
if array_match:
|
||||
array_prefix = array_match.group(1)
|
||||
base_type_raw = array_match.group(2).strip()
|
||||
# Limpiar comillas del tipo base del array
|
||||
base_type_for_init = (
|
||||
base_type_raw.strip('"')
|
||||
if base_type_raw.startswith('"') and base_type_raw.endswith('"')
|
||||
else base_type_raw
|
||||
)
|
||||
declaration_dtype = (
|
||||
f'{array_prefix}"{base_type_for_init}"'
|
||||
if '"' not in base_type_raw
|
||||
else f"{array_prefix}{base_type_raw}"
|
||||
) # Reconstruir con comillas si es UDT
|
||||
|
||||
# Reconstruir declaración con comillas si es UDT y no array
|
||||
elif (
|
||||
not array_match and var_dtype != base_type_for_init
|
||||
): # Es un tipo que necesita comillas (UDT)
|
||||
declaration_dtype = f'"{var_dtype}"'
|
||||
|
||||
declaration_line = f"{indent}{var_name_scl} : {declaration_dtype}"
|
||||
init_value = None
|
||||
|
||||
# ---- Arrays ----
|
||||
if array_elements:
|
||||
# Ordenar índices (asumiendo que son numéricos)
|
||||
try:
|
||||
sorted_indices = sorted(array_elements.keys(), key=int)
|
||||
except ValueError:
|
||||
sorted_indices = sorted(
|
||||
array_elements.keys()
|
||||
) # Fallback a orden alfabético
|
||||
|
||||
init_values = [
|
||||
format_scl_start_value(array_elements[idx], base_type_for_init)
|
||||
for idx in sorted_indices
|
||||
]
|
||||
valid_inits = [v for v in init_values if v is not None]
|
||||
if valid_inits:
|
||||
init_value = f"[{', '.join(valid_inits)}]"
|
||||
|
||||
# ---- Structs ----
|
||||
elif children:
|
||||
# No añadir comentario // Struct aquí, es redundante
|
||||
scl_lines.append(declaration_line) # Añadir línea de declaración base
|
||||
scl_lines.append(f"{indent}STRUCT")
|
||||
scl_lines.extend(generate_scl_declarations(children, indent_level + 1))
|
||||
scl_lines.append(f"{indent}END_STRUCT;")
|
||||
if var_comment:
|
||||
scl_lines.append(f"{indent}// {var_comment}")
|
||||
scl_lines.append("") # Línea extra
|
||||
continue # Saltar resto para Struct
|
||||
|
||||
# ---- Tipos Simples ----
|
||||
else:
|
||||
if start_value is not None:
|
||||
init_value = format_scl_start_value(start_value, var_dtype)
|
||||
|
||||
# Añadir inicialización si existe
|
||||
if init_value:
|
||||
declaration_line += f" := {init_value}"
|
||||
declaration_line += ";"
|
||||
if var_comment:
|
||||
declaration_line += f" // {var_comment}"
|
||||
scl_lines.append(declaration_line)
|
||||
|
||||
return scl_lines
|
||||
|
||||
|
||||
# --- Función Principal de Generación SCL ---
|
||||
def generate_scl(processed_json_filepath, output_scl_filepath):
|
||||
"""Genera un archivo SCL a partir del JSON procesado por x2_process (versión SymPy)."""
|
||||
"""Genera un archivo SCL a partir del JSON procesado (FC/FB o DB)."""
|
||||
|
||||
if not os.path.exists(processed_json_filepath):
|
||||
print(f"Error: Archivo JSON procesado no encontrado en '{processed_json_filepath}'")
|
||||
print(
|
||||
f"Error: Archivo JSON procesado no encontrado en '{processed_json_filepath}'"
|
||||
)
|
||||
return
|
||||
|
||||
print(f"Cargando JSON procesado desde: {processed_json_filepath}")
|
||||
try:
|
||||
with open(processed_json_filepath, 'r', encoding='utf-8') as f:
|
||||
with open(processed_json_filepath, "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
except Exception as e:
|
||||
print(f"Error al cargar o parsear JSON: {e}")
|
||||
traceback.print_exc()
|
||||
return
|
||||
|
||||
# --- Extracción de Información del Bloque ---
|
||||
block_name = data.get('block_name', 'UnknownBlock')
|
||||
block_number = data.get('block_number')
|
||||
block_lang_original = data.get('language', 'LAD') # Lenguaje original
|
||||
# Determinar tipo de bloque SCL (Asumir FB si no se especifica)
|
||||
# Idealmente, x1_to_json.py guardaría esto en data['block_type_scl'] = 'FC' o 'FB'
|
||||
block_type_scl = data.get('block_type_scl', 'FUNCTION_BLOCK')
|
||||
block_comment = data.get('block_comment', '')
|
||||
|
||||
# Usar format_variable_name para el nombre del bloque en SCL
|
||||
scl_block_name = format_variable_name(block_name)
|
||||
print(f"Generando SCL para {block_type_scl}: {scl_block_name} (Original: {block_name})")
|
||||
|
||||
# --- Identificación de Variables Temporales y Estáticas ---
|
||||
# La detección basada en regex sobre el SCL final debería seguir funcionando
|
||||
temp_vars = set()
|
||||
stat_vars = set()
|
||||
# Regex mejorado para capturar variables temporales que empiezan con # o _temp_
|
||||
# y estáticas (si usas un prefijo como 'stat_' o para bits de memoria de flanco)
|
||||
temp_pattern = re.compile(r'"?#(_temp_[a-zA-Z0-9_]+)"?|"?(_temp_[a-zA-Z0-9_]+)"?') # Captura con o sin #
|
||||
stat_pattern = re.compile(r'"?(stat_[a-zA-Z0-9_]+)"?') # Para memorias de flanco si usan prefijo 'stat_'
|
||||
|
||||
edge_memory_bits = set() # Para detectar bits de memoria de flanco por nombre
|
||||
|
||||
for network in data.get('networks', []):
|
||||
for instruction in network.get('logic', []):
|
||||
scl_code = instruction.get('scl', '')
|
||||
# Buscar también en _edge_mem_update_scl si existe
|
||||
edge_update_code = instruction.get('_edge_mem_update_scl','')
|
||||
code_to_scan = (scl_code if scl_code else '') + '\n' + (edge_update_code if edge_update_code else '')
|
||||
|
||||
if code_to_scan:
|
||||
# Buscar #_temp_... o _temp_...
|
||||
found_temps = temp_pattern.findall(code_to_scan)
|
||||
for temp_tuple in found_temps:
|
||||
# findall devuelve tuplas por los grupos de captura, tomar el no vacío
|
||||
temp_name = next((t for t in temp_tuple if t), None)
|
||||
if temp_name:
|
||||
temp_vars.add("#"+temp_name if not temp_name.startswith("#") else temp_name) # Asegurar que empiece con #
|
||||
|
||||
# Buscar estáticas (ej: stat_...)
|
||||
found_stats = stat_pattern.findall(code_to_scan)
|
||||
stat_vars.update(found_stats)
|
||||
|
||||
# Identificar explícitamente bits de memoria usados por PBox/NBox
|
||||
# Asumiendo que el nombre se guarda en el JSON (requiere ajuste en x1/x2)
|
||||
# if instruction.get("type","").startswith(("PBox", "NBox")):
|
||||
# mem_bit_info = instruction.get("inputs", {}).get("bit")
|
||||
# if mem_bit_info and mem_bit_info.get("type") == "variable":
|
||||
# edge_memory_bits.add(format_variable_name(mem_bit_info.get("name")))
|
||||
|
||||
|
||||
print(f"Variables temporales (#_temp_...) detectadas: {len(temp_vars)}")
|
||||
# Si se detectan memorias de flanco, añadirlas a stat_vars si no tienen prefijo 'stat_'
|
||||
# stat_vars.update(edge_memory_bits - stat_vars) # Añadir solo las nuevas
|
||||
print(f"Variables estáticas (stat_...) detectadas: {len(stat_vars)}")
|
||||
|
||||
# --- Construcción del String SCL ---
|
||||
# --- Extracción de Información del Bloque (Común) ---
|
||||
block_name = data.get("block_name", "UnknownBlock")
|
||||
block_number = data.get("block_number")
|
||||
block_lang_original = data.get("language", "Unknown") # Será "DB" para Data Blocks
|
||||
block_type = data.get("block_type", "Unknown") # FC, FB, GlobalDB
|
||||
block_comment = data.get("block_comment", "")
|
||||
scl_block_name = format_variable_name(block_name) # Nombre SCL seguro
|
||||
print(
|
||||
f"Generando SCL para: {block_type} '{scl_block_name}' (Original: {block_name}, Lang: {block_lang_original})"
|
||||
)
|
||||
scl_output = []
|
||||
|
||||
# Cabecera del Bloque
|
||||
# --- GENERACIÓN PARA DATA BLOCK (DB) ---
|
||||
if block_lang_original == "DB":
|
||||
print("Modo de generación: DATA_BLOCK")
|
||||
scl_output.append(f"// Block Type: {block_type}")
|
||||
scl_output.append(f"// Block Name (Original): {block_name}")
|
||||
if block_number: scl_output.append(f"// Block Number: {block_number}")
|
||||
scl_output.append(f"// Original Language: {block_lang_original}")
|
||||
if block_comment: scl_output.append(f"// Block Comment: {block_comment}")
|
||||
if block_number:
|
||||
scl_output.append(f"// Block Number: {block_number}")
|
||||
if block_comment:
|
||||
scl_output.append(f"// Block Comment: {block_comment}")
|
||||
scl_output.append("")
|
||||
scl_output.append(f"{block_type_scl} \"{scl_block_name}\"")
|
||||
scl_output.append(f'DATA_BLOCK "{scl_block_name}"')
|
||||
scl_output.append("{ S7_Optimized_Access := 'TRUE' }") # Asumir optimizado
|
||||
scl_output.append("VERSION : 0.1")
|
||||
scl_output.append("")
|
||||
interface_data = data.get("interface", {})
|
||||
static_vars = interface_data.get("Static", [])
|
||||
if static_vars:
|
||||
scl_output.append("VAR")
|
||||
scl_output.extend(generate_scl_declarations(static_vars, indent_level=1))
|
||||
scl_output.append("END_VAR")
|
||||
scl_output.append("")
|
||||
else:
|
||||
print(
|
||||
"Advertencia: No se encontró sección 'Static' o está vacía en la interfaz del DB."
|
||||
)
|
||||
scl_output.append("VAR")
|
||||
scl_output.append("END_VAR")
|
||||
scl_output.append("")
|
||||
scl_output.append("BEGIN")
|
||||
scl_output.append("")
|
||||
scl_output.append("END_DATA_BLOCK")
|
||||
|
||||
# --- GENERACIÓN PARA FUNCTION BLOCK / FUNCTION (FC/FB) ---
|
||||
else:
|
||||
print("Modo de generación: FUNCTION_BLOCK / FUNCTION")
|
||||
scl_block_keyword = "FUNCTION_BLOCK" if block_type == "FB" else "FUNCTION"
|
||||
# Cabecera del Bloque
|
||||
scl_output.append(f"// Block Type: {block_type}")
|
||||
scl_output.append(f"// Block Name (Original): {block_name}")
|
||||
if block_number:
|
||||
scl_output.append(f"// Block Number: {block_number}")
|
||||
scl_output.append(f"// Original Language: {block_lang_original}")
|
||||
if block_comment:
|
||||
scl_output.append(f"// Block Comment: {block_comment}")
|
||||
scl_output.append("")
|
||||
# Manejar tipo de retorno para FUNCTION
|
||||
return_type = "Void" # Default
|
||||
interface_data = data.get("interface", {})
|
||||
if scl_block_keyword == "FUNCTION" and interface_data.get("Return"):
|
||||
return_member = interface_data["Return"][
|
||||
0
|
||||
] # Asumir un solo valor de retorno
|
||||
return_type_raw = return_member.get("datatype", "Void")
|
||||
return_type = (
|
||||
return_type_raw.strip('"')
|
||||
if return_type_raw.startswith('"') and return_type_raw.endswith('"')
|
||||
else return_type_raw
|
||||
)
|
||||
# Añadir comillas si es UDT
|
||||
if return_type != return_type_raw:
|
||||
return_type = f'"{return_type}"'
|
||||
|
||||
scl_output.append(
|
||||
f'{scl_block_keyword} "{scl_block_name}" : {return_type}'
|
||||
if scl_block_keyword == "FUNCTION"
|
||||
else f'{scl_block_keyword} "{scl_block_name}"'
|
||||
)
|
||||
scl_output.append("{ S7_Optimized_Access := 'TRUE' }")
|
||||
scl_output.append("VERSION : 0.1")
|
||||
scl_output.append("")
|
||||
|
||||
# Declaraciones de Interfaz (Implementación básica)
|
||||
interface_sections = ["Input", "Output", "InOut", "Static", "Temp", "Constant", "Return"]
|
||||
interface_data = data.get('interface', {})
|
||||
|
||||
for section_name in interface_sections:
|
||||
scl_section_name = section_name
|
||||
# Ajustar nombres de sección para SCL (Static -> STAT, Temp -> TEMP)
|
||||
if section_name == "Static": scl_section_name = "STAT"
|
||||
if section_name == "Temp": scl_section_name = "TEMP" # Usar VAR_TEMP para variables #temp
|
||||
|
||||
vars_in_section = interface_data.get(section_name, [])
|
||||
# No declarar VAR_TEMP aquí, se hará después con las detectadas/originales
|
||||
if section_name == "Temp": continue
|
||||
|
||||
# No declarar VAR_STAT aquí si ya lo hacemos abajo con las detectadas
|
||||
if section_name == "Static" and stat_vars: continue
|
||||
|
||||
|
||||
if vars_in_section or (section_name == "Static" and stat_vars): # Incluir STAT si hay detectadas
|
||||
# Usar VAR para Input/Output/InOut/Constant/Return
|
||||
var_keyword = "VAR" if section_name != "Static" else "VAR_STAT"
|
||||
scl_output.append(f"{var_keyword}_{section_name.upper()}")
|
||||
|
||||
for var in vars_in_section:
|
||||
var_name = var.get('name')
|
||||
var_dtype = var.get('datatype', 'VARIANT') # Default a VARIANT
|
||||
if var_name:
|
||||
# Usar format_variable_name CORRECTO
|
||||
scl_name = format_variable_name(var_name)
|
||||
scl_output.append(f" {scl_name} : {var_dtype};")
|
||||
|
||||
# Declarar stat_vars detectadas si esta es la sección STAT
|
||||
if section_name == "Static" and stat_vars:
|
||||
for var_name in sorted(list(stat_vars)):
|
||||
# Asumir Bool para stat_, podría necesitar inferencia
|
||||
scl_output.append(f" {format_variable_name(var_name)} : Bool; // Auto-detected STAT")
|
||||
|
||||
scl_output.append("END_VAR")
|
||||
scl_output.append("")
|
||||
|
||||
# Declaraciones Estáticas (Si no estaban en la interfaz y se detectaron)
|
||||
# Esto es redundante si la sección VAR_STAT ya se generó arriba
|
||||
# if stat_vars and not interface_data.get("Static"):
|
||||
# scl_output.append("VAR_STAT")
|
||||
# for var_name in sorted(list(stat_vars)):
|
||||
# scl_output.append(f" {format_variable_name(var_name)} : Bool; // Auto-detected STAT")
|
||||
# scl_output.append("END_VAR")
|
||||
# scl_output.append("")
|
||||
|
||||
|
||||
# Declaraciones Temporales (Interfaz Temp + _temp_ detectadas)
|
||||
scl_output.append("VAR_TEMP")
|
||||
# Declaraciones de Interfaz FC/FB
|
||||
section_order = [
|
||||
"Input",
|
||||
"Output",
|
||||
"InOut",
|
||||
"Static",
|
||||
"Temp",
|
||||
"Constant",
|
||||
] # Return ya está en cabecera
|
||||
declared_temps = set()
|
||||
interface_temps = interface_data.get('Temp', [])
|
||||
if interface_temps:
|
||||
for var in interface_temps:
|
||||
var_name = var.get('name')
|
||||
var_dtype = var.get('datatype', 'VARIANT')
|
||||
if var_name:
|
||||
scl_name = format_variable_name(var_name)
|
||||
scl_output.append(f" {scl_name} : {var_dtype};")
|
||||
declared_temps.add(scl_name) # Marcar como declarada
|
||||
|
||||
# Declarar las _temp_ generadas si no estaban ya en la interfaz Temp
|
||||
if temp_vars:
|
||||
for var_name in sorted(list(temp_vars)):
|
||||
scl_name = format_variable_name(var_name) # #_temp_...
|
||||
if scl_name not in declared_temps:
|
||||
# Inferencia básica de tipo
|
||||
inferred_type = "Bool" # Asumir Bool para la mayoría de temps de lógica
|
||||
# Se podría mejorar si los procesadores añadieran info de tipo
|
||||
scl_output.append(f" {scl_name} : {inferred_type}; // Auto-generated temporary")
|
||||
declared_temps.add(scl_name)
|
||||
for section_name in section_order:
|
||||
vars_in_section = interface_data.get(section_name, [])
|
||||
if vars_in_section:
|
||||
scl_section_keyword = f"VAR_{section_name.upper()}"
|
||||
if section_name == "Static":
|
||||
scl_section_keyword = "VAR_STAT"
|
||||
if section_name == "Temp":
|
||||
scl_section_keyword = "VAR_TEMP"
|
||||
if section_name == "Constant":
|
||||
scl_section_keyword = "CONSTANT"
|
||||
scl_output.append(scl_section_keyword)
|
||||
scl_output.extend(
|
||||
generate_scl_declarations(vars_in_section, indent_level=1)
|
||||
)
|
||||
if section_name == "Temp":
|
||||
declared_temps.update(
|
||||
format_variable_name(v.get("name"))
|
||||
for v in vars_in_section
|
||||
if v.get("name")
|
||||
)
|
||||
scl_output.append("END_VAR")
|
||||
scl_output.append("")
|
||||
|
||||
# Cuerpo del Bloque
|
||||
# Declaraciones VAR_TEMP adicionales detectadas
|
||||
temp_vars = set()
|
||||
temp_pattern = re.compile(
|
||||
r'"?#(_temp_[a-zA-Z0-9_]+)"?|"?(_temp_[a-zA-Z0-9_]+)"?'
|
||||
)
|
||||
for network in data.get("networks", []):
|
||||
for instruction in network.get("logic", []):
|
||||
scl_code = instruction.get("scl", "")
|
||||
edge_update_code = instruction.get("_edge_mem_update_scl", "")
|
||||
code_to_scan = (
|
||||
(scl_code if scl_code else "")
|
||||
+ "\n"
|
||||
+ (edge_update_code if edge_update_code else "")
|
||||
)
|
||||
if code_to_scan:
|
||||
found_temps = temp_pattern.findall(code_to_scan)
|
||||
for temp_tuple in found_temps:
|
||||
temp_name = next((t for t in temp_tuple if t), None)
|
||||
if temp_name:
|
||||
temp_vars.add(
|
||||
"#" + temp_name
|
||||
if not temp_name.startswith("#")
|
||||
else temp_name
|
||||
)
|
||||
additional_temps = sorted(list(temp_vars - declared_temps))
|
||||
if additional_temps:
|
||||
if not interface_data.get("Temp"):
|
||||
scl_output.append("VAR_TEMP")
|
||||
for var_name in additional_temps:
|
||||
scl_name = format_variable_name(var_name)
|
||||
inferred_type = "Bool" # Asumir Bool
|
||||
scl_output.append(
|
||||
f" {scl_name} : {inferred_type}; // Auto-generated temporary"
|
||||
)
|
||||
if not interface_data.get("Temp"):
|
||||
scl_output.append("END_VAR")
|
||||
scl_output.append("")
|
||||
|
||||
# Cuerpo del Bloque FC/FB
|
||||
scl_output.append("BEGIN")
|
||||
scl_output.append("")
|
||||
|
||||
# Iterar por redes y lógica
|
||||
for i, network in enumerate(data.get('networks', [])):
|
||||
network_title = network.get('title', f'Network {network.get("id")}')
|
||||
network_comment = network.get('comment', '')
|
||||
network_lang = network.get('language', 'LAD') # O el lenguaje original
|
||||
|
||||
scl_output.append(f" // Network {i+1}: {network_title} (Original Language: {network_lang})")
|
||||
# Iterar por redes y lógica (como antes, incluyendo manejo STL Markdown)
|
||||
for i, network in enumerate(data.get("networks", [])):
|
||||
network_title = network.get("title", f'Network {network.get("id")}')
|
||||
network_comment = network.get("comment", "")
|
||||
network_lang = network.get("language", "LAD")
|
||||
scl_output.append(
|
||||
f" // Network {i+1}: {network_title} (Original Language: {network_lang})"
|
||||
)
|
||||
if network_comment:
|
||||
for line in network_comment.splitlines():
|
||||
scl_output.append(f" // {line}")
|
||||
scl_output.append("")
|
||||
|
||||
network_has_code = False
|
||||
# Iterar sobre la 'logica' de la red
|
||||
for instruction in network.get('logic', []):
|
||||
if network_lang == "STL":
|
||||
network_has_code = True
|
||||
if (
|
||||
network.get("logic")
|
||||
and network["logic"][0].get("type") == "RAW_STL_CHUNK"
|
||||
):
|
||||
raw_stl_code = network["logic"][0].get(
|
||||
"stl", "// ERROR: STL code missing"
|
||||
)
|
||||
scl_output.append(f" {'//'} ```STL")
|
||||
for stl_line in raw_stl_code.splitlines():
|
||||
scl_output.append(f" {stl_line}")
|
||||
scl_output.append(f" {'//'} ```")
|
||||
else:
|
||||
scl_output.append(" // ERROR: Contenido STL inesperado.")
|
||||
else: # LAD, FBD, SCL, etc.
|
||||
for instruction in network.get("logic", []):
|
||||
instruction_type = instruction.get("type", "")
|
||||
scl_code = instruction.get('scl', "") # Obtener SCL generado por x2
|
||||
|
||||
# Saltar instrucciones agrupadas
|
||||
if instruction.get("grouped", False):
|
||||
scl_code = instruction.get("scl", "")
|
||||
is_grouped = instruction.get("grouped", False)
|
||||
if is_grouped:
|
||||
continue
|
||||
|
||||
# Escribir SCL si es un tipo procesado y tiene código relevante
|
||||
# (Ignorar comentarios de depuración de SymPy)
|
||||
if instruction_type.endswith(SCL_SUFFIX) and scl_code:
|
||||
is_internal_sympy_comment_only = scl_code.strip().startswith("// SymPy") or \
|
||||
scl_code.strip().startswith("// PBox SymPy processed") or \
|
||||
scl_code.strip().startswith("// NBox SymPy processed")
|
||||
# O podría ser más genérico: ignorar cualquier línea que solo sea comentario SCL
|
||||
is_only_comment = all(line.strip().startswith("//") for line in scl_code.splitlines())
|
||||
|
||||
|
||||
# Escribir solo si NO es un comentario interno de SymPy O si es un bloque IF (que sí debe escribirse)
|
||||
if not is_only_comment or scl_code.strip().startswith("IF"):
|
||||
if (
|
||||
instruction_type.endswith(SCL_SUFFIX)
|
||||
or instruction_type in ["RAW_SCL_CHUNK", "UNSUPPORTED_LANG"]
|
||||
) and scl_code:
|
||||
is_only_comment = all(
|
||||
line.strip().startswith("//")
|
||||
for line in scl_code.splitlines()
|
||||
if line.strip()
|
||||
)
|
||||
is_if_block = scl_code.strip().startswith("IF")
|
||||
if not is_only_comment or is_if_block:
|
||||
network_has_code = True
|
||||
for line in scl_code.splitlines():
|
||||
# Añadir indentación estándar
|
||||
scl_output.append(f" {line}")
|
||||
|
||||
# Incluir también tipos especiales directamente
|
||||
elif instruction_type in ["RAW_SCL_CHUNK", "UNSUPPORTED_LANG"] and scl_code:
|
||||
network_has_code = True
|
||||
for line in scl_code.splitlines():
|
||||
scl_output.append(f" {line}") # Indentar
|
||||
|
||||
# Podríamos añadir comentarios para errores si se desea
|
||||
# elif "_error" in instruction_type:
|
||||
# network_has_code = True
|
||||
# scl_output.append(f" // ERROR processing instruction UID {instruction.get('instruction_uid')}: {instruction.get('scl', 'No details')}")
|
||||
|
||||
|
||||
if network_has_code:
|
||||
scl_output.append("") # Línea en blanco después del código de la red
|
||||
scl_output.append("")
|
||||
else:
|
||||
scl_output.append(f" // Network did not produce printable SCL code.")
|
||||
scl_output.append("")
|
||||
# Fin del bloque FC/FB
|
||||
scl_output.append(f"END_{scl_block_keyword}")
|
||||
|
||||
# Fin del bloque
|
||||
scl_output.append("END_FUNCTION_BLOCK") # O END_FUNCTION si es FC
|
||||
|
||||
# --- Escritura del Archivo SCL ---
|
||||
# --- Escritura del Archivo SCL (Común) ---
|
||||
print(f"Escribiendo archivo SCL en: {output_scl_filepath}")
|
||||
try:
|
||||
with open(output_scl_filepath, 'w', encoding='utf-8') as f:
|
||||
with open(output_scl_filepath, "w", encoding="utf-8") as f:
|
||||
for line in scl_output:
|
||||
f.write(line + '\n')
|
||||
f.write(line + "\n")
|
||||
print("Generación de SCL completada.")
|
||||
except Exception as e:
|
||||
print(f"Error al escribir el archivo SCL: {e}")
|
||||
|
@ -273,26 +488,65 @@ def generate_scl(processed_json_filepath, output_scl_filepath):
|
|||
|
||||
# --- Ejecución ---
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Generate final SCL file from processed JSON (SymPy version).")
|
||||
parser.add_argument(
|
||||
"source_xml_filepath",
|
||||
nargs="?",
|
||||
default="TestLAD.xml",
|
||||
help="Path to the original source XML file (used to derive input/output names, default: TestLAD.xml)"
|
||||
# Imports necesarios solo para la ejecución como script principal
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
import traceback # Asegurarse que traceback está importado si se usa en generate_scl
|
||||
|
||||
# Configurar ArgumentParser para recibir la ruta del XML original obligatoria
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Generate final SCL file from processed JSON (_simplified_processed.json). Expects original XML filepath as argument."
|
||||
)
|
||||
args = parser.parse_args()
|
||||
parser.add_argument(
|
||||
"source_xml_filepath", # Argumento posicional obligatorio
|
||||
help="Path to the original source XML file (passed from x0_main.py, used to derive input/output names).",
|
||||
)
|
||||
args = parser.parse_args() # Parsea los argumentos de sys.argv
|
||||
|
||||
xml_filename_base = os.path.splitext(os.path.basename(args.source_xml_filepath))[0]
|
||||
# Usar directorio del script si no hay ruta, o la ruta del XML si la tiene
|
||||
xml_dir = os.path.dirname(args.source_xml_filepath)
|
||||
base_dir = xml_dir if xml_dir else os.path.dirname(__file__)
|
||||
source_xml_file = args.source_xml_filepath # Obtiene la ruta del XML original
|
||||
|
||||
input_json_file = os.path.join(base_dir, f"{xml_filename_base}_simplified_processed.json")
|
||||
output_scl_file = os.path.join(base_dir, f"{xml_filename_base}_simplified_processed.scl")
|
||||
# Verificar si el archivo XML original existe (como referencia)
|
||||
if not os.path.exists(source_xml_file):
|
||||
print(
|
||||
f"Advertencia (x3): Archivo XML original no encontrado: '{source_xml_file}', pero se intentará encontrar el JSON procesado."
|
||||
)
|
||||
# No salir necesariamente.
|
||||
|
||||
# Derivar nombres de archivos de entrada (JSON procesado) y salida (SCL)
|
||||
xml_filename_base = os.path.splitext(os.path.basename(source_xml_file))[0]
|
||||
# Asumir que los archivos están en el mismo directorio que el XML original
|
||||
base_dir = os.path.dirname(source_xml_file) # Directorio del XML original
|
||||
|
||||
input_json_file = os.path.join(
|
||||
base_dir, f"{xml_filename_base}_simplified_processed.json"
|
||||
)
|
||||
output_scl_file = os.path.join(
|
||||
base_dir, f"{xml_filename_base}_simplified_processed.scl"
|
||||
)
|
||||
|
||||
print(
|
||||
f"(x3) Generando SCL: '{os.path.relpath(input_json_file)}' -> '{os.path.relpath(output_scl_file)}'"
|
||||
)
|
||||
|
||||
# Verificar si el archivo JSON procesado de entrada EXISTE
|
||||
if not os.path.exists(input_json_file):
|
||||
print(f"Error: Processed JSON file not found: '{input_json_file}'")
|
||||
print(f"Ensure 'x2_process.py' ran successfully for '{args.source_xml_filepath}'.")
|
||||
sys.exit(1)
|
||||
print(
|
||||
f"Error Fatal (x3): Archivo JSON procesado no encontrado: '{input_json_file}'"
|
||||
)
|
||||
print(
|
||||
f"Asegúrate de que 'x2_process.py' se ejecutó correctamente para '{os.path.relpath(source_xml_file)}'."
|
||||
)
|
||||
sys.exit(1) # Salir si el archivo necesario no está
|
||||
else:
|
||||
# Llamar a la función principal de generación SCL del script
|
||||
# Asumiendo que tu función principal se llama generate_scl(input_json_path, output_scl_path)
|
||||
try:
|
||||
generate_scl(input_json_file, output_scl_file)
|
||||
except Exception as e:
|
||||
print(
|
||||
f"Error Crítico (x3) durante la generación de SCL desde '{input_json_file}': {e}"
|
||||
)
|
||||
# traceback ya debería estar importado si generate_scl lo necesita
|
||||
traceback.print_exc()
|
||||
sys.exit(1) # Salir con error si la función principal falla
|
||||
|
|
220
x0_main.py
220
x0_main.py
|
@ -3,143 +3,163 @@ import subprocess
|
|||
import os
|
||||
import sys
|
||||
import locale
|
||||
import glob # <--- Importar glob para buscar archivos
|
||||
import glob
|
||||
|
||||
# (Función get_console_encoding y variable CONSOLE_ENCODING como en la respuesta anterior)
|
||||
# (Función get_console_encoding y variable CONSOLE_ENCODING como antes)
|
||||
def get_console_encoding():
|
||||
"""Obtiene la codificación preferida de la consola, con fallback."""
|
||||
try:
|
||||
return locale.getpreferredencoding(False)
|
||||
except Exception:
|
||||
return 'cp1252'
|
||||
# Fallback común en Windows si falla getpreferredencoding
|
||||
return "cp1252" # O prueba con 'utf-8' si cp1252 da problemas
|
||||
|
||||
CONSOLE_ENCODING = get_console_encoding()
|
||||
# Descomenta la siguiente línea si quieres ver la codificación detectada:
|
||||
# print(f"Detected console encoding: {CONSOLE_ENCODING}")
|
||||
|
||||
# (Función run_script como en la respuesta anterior, usando CONSOLE_ENCODING)
|
||||
# (Función run_script como antes, usando CONSOLE_ENCODING)
|
||||
def run_script(script_name, xml_arg):
|
||||
"""Runs a given script with the specified XML file argument."""
|
||||
script_path = os.path.join(os.path.dirname(__file__), script_name)
|
||||
command = [sys.executable, script_path, xml_arg]
|
||||
# Asegurarse que la ruta al script sea absoluta o relativa al script actual
|
||||
script_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), script_name)
|
||||
# Usar la ruta absoluta al ejecutable de Python actual
|
||||
python_executable = sys.executable
|
||||
command = [python_executable, script_path, xml_arg] # Usar la ruta absoluta de python
|
||||
print(f"\n--- Running {script_name} with argument: {xml_arg} ---")
|
||||
try:
|
||||
result = subprocess.run(command,
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
encoding=CONSOLE_ENCODING,
|
||||
errors='replace') # 'replace' para evitar errores
|
||||
# Ejecutar el proceso hijo
|
||||
result = subprocess.run(
|
||||
command,
|
||||
check=True, # Lanza excepción si el script falla (return code != 0)
|
||||
capture_output=True,# Captura stdout y stderr
|
||||
text=True, # Decodifica stdout/stderr como texto
|
||||
encoding=CONSOLE_ENCODING, # Usa la codificación detectada
|
||||
errors='replace' # Reemplaza caracteres no decodificables
|
||||
)
|
||||
|
||||
# Imprimir stdout y stderr si no están vacíos
|
||||
stdout_clean = result.stdout.strip() if result.stdout else ""
|
||||
stderr_clean = result.stderr.strip() if result.stderr else ""
|
||||
|
||||
# Imprimir stdout y stderr
|
||||
# Eliminar saltos de línea extra al final si existen
|
||||
stdout_clean = result.stdout.strip()
|
||||
stderr_clean = result.stderr.strip()
|
||||
if stdout_clean:
|
||||
print(stdout_clean)
|
||||
if stderr_clean:
|
||||
print("--- Stderr ---")
|
||||
print(stderr_clean)
|
||||
print("--------------")
|
||||
# Imprimir stderr claramente para errores del script hijo
|
||||
print(f"--- Stderr ({script_name}) ---", file=sys.stderr) # Imprimir en stderr
|
||||
print(stderr_clean, file=sys.stderr)
|
||||
print("--------------------------", file=sys.stderr)
|
||||
|
||||
print(f"--- {script_name} finished successfully ---")
|
||||
return True
|
||||
return True # Indicar éxito
|
||||
|
||||
except FileNotFoundError:
|
||||
print(f"Error: Script '{script_path}' not found.")
|
||||
# Error si el script python o el ejecutable no se encuentran
|
||||
print(f"Error: Script '{script_path}' or Python executable '{python_executable}' not found.", file=sys.stderr)
|
||||
return False
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Error running {script_name}:")
|
||||
print(f"Return code: {e.returncode}")
|
||||
stdout_decoded = e.stdout.decode(CONSOLE_ENCODING, errors='replace').strip() if isinstance(e.stdout, bytes) else (e.stdout or "").strip()
|
||||
stderr_decoded = e.stderr.decode(CONSOLE_ENCODING, errors='replace').strip() if isinstance(e.stderr, bytes) else (e.stderr or "").strip()
|
||||
# Error si el script hijo devuelve un código de error (ej., sys.exit(1))
|
||||
print(f"Error running {script_name}: Script returned non-zero exit code {e.returncode}.", file=sys.stderr)
|
||||
|
||||
# Decodificar e imprimir stdout/stderr del proceso fallido
|
||||
stdout_decoded = e.stdout.strip() if e.stdout else ""
|
||||
stderr_decoded = e.stderr.strip() if e.stderr else ""
|
||||
|
||||
if stdout_decoded:
|
||||
print("--- Stdout ---")
|
||||
print(stdout_decoded)
|
||||
print(f"--- Stdout ({script_name}) ---", file=sys.stderr)
|
||||
print(stdout_decoded, file=sys.stderr)
|
||||
if stderr_decoded:
|
||||
print("--- Stderr ---")
|
||||
print(stderr_decoded)
|
||||
print("--------------")
|
||||
return False
|
||||
print(f"--- Stderr ({script_name}) ---", file=sys.stderr)
|
||||
print(stderr_decoded, file=sys.stderr)
|
||||
print("--------------------------", file=sys.stderr)
|
||||
return False # Indicar fallo
|
||||
except Exception as e:
|
||||
print(f"An unexpected error occurred while running {script_name}: {e}")
|
||||
return False
|
||||
# Otros errores inesperados
|
||||
print(f"An unexpected error occurred while running {script_name}: {e}", file=sys.stderr)
|
||||
# Imprimir traceback para depuración
|
||||
import traceback
|
||||
traceback.print_exc(file=sys.stderr)
|
||||
return False # Indicar fallo
|
||||
|
||||
# --- NUEVA FUNCIÓN PARA SELECCIONAR ARCHIVO ---
|
||||
def select_xml_file():
|
||||
"""Busca archivos .xml, los lista y pide al usuario que elija uno."""
|
||||
print("No XML file specified. Searching for XML files in current directory...")
|
||||
# Buscar archivos .xml en el directorio actual (.)
|
||||
xml_files = sorted(glob.glob('*.xml')) # sorted para orden alfabético
|
||||
|
||||
if not xml_files:
|
||||
print("Error: No .xml files found in the current directory.")
|
||||
sys.exit(1)
|
||||
|
||||
print("\nAvailable XML files:")
|
||||
for i, filename in enumerate(xml_files, start=1):
|
||||
print(f" {i}: {filename}")
|
||||
|
||||
while True:
|
||||
try:
|
||||
choice = input(f"Enter the number of the file to process (1-{len(xml_files)}): ")
|
||||
choice_num = int(choice)
|
||||
if 1 <= choice_num <= len(xml_files):
|
||||
selected_file = xml_files[choice_num - 1]
|
||||
print(f"Selected: {selected_file}")
|
||||
return selected_file
|
||||
else:
|
||||
print("Invalid choice. Please enter a number from the list.")
|
||||
except ValueError:
|
||||
print("Invalid input. Please enter a number.")
|
||||
except EOFError: # Manejar si la entrada se cierra inesperadamente
|
||||
print("\nSelection cancelled.")
|
||||
sys.exit(1)
|
||||
# --- FIN NUEVA FUNCIÓN ---
|
||||
|
||||
# --- NO SE NECESITA select_xml_file() si procesamos todos ---
|
||||
|
||||
if __name__ == "__main__":
|
||||
xml_filename = None
|
||||
# --- PARTE 1: BUSCAR ARCHIVOS ---
|
||||
# Directorio base donde buscar los archivos XML (relativo al script)
|
||||
base_search_dir = "XML Project"
|
||||
# Obtener la ruta absoluta del directorio donde está x0_main.py
|
||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
xml_project_dir = os.path.join(script_dir, base_search_dir)
|
||||
|
||||
# Comprobar si se pasó un argumento de línea de comandos
|
||||
# sys.argv[0] es el nombre del script, sys.argv[1] sería el primer argumento
|
||||
if len(sys.argv) > 1:
|
||||
# Si hay argumentos, usar argparse para parsearlo (permite -h, etc.)
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Run the Simatic XML processing pipeline."
|
||||
)
|
||||
parser.add_argument(
|
||||
"xml_file",
|
||||
# Ya no necesitamos nargs='?' ni default aquí porque sabemos que hay un argumento
|
||||
help="Path to the XML file to process.",
|
||||
)
|
||||
# Parsear solo los argumentos conocidos, ignorar extras si los hubiera
|
||||
args, unknown = parser.parse_known_args()
|
||||
xml_filename = args.xml_file
|
||||
print(f"XML file specified via argument: {xml_filename}")
|
||||
else:
|
||||
# Si no hay argumentos, llamar a la función interactiva
|
||||
xml_filename = select_xml_file()
|
||||
print(f"Buscando archivos XML recursivamente en: '{xml_project_dir}'")
|
||||
|
||||
# --- El resto del script continúa igual, usando xml_filename ---
|
||||
# Verificar si el directorio 'XML Project' existe
|
||||
if not os.path.isdir(xml_project_dir):
|
||||
print(f"Error: El directorio '{xml_project_dir}' no existe o no es un directorio.", file=sys.stderr)
|
||||
print("Por favor, crea el directorio 'XML Project' en la misma carpeta que este script y coloca tus archivos XML dentro.")
|
||||
sys.exit(1) # Salir con error
|
||||
|
||||
# Verificar si el archivo XML de entrada (seleccionado o pasado) existe
|
||||
if not os.path.exists(xml_filename):
|
||||
print(f"Error: Selected or specified XML file not found: {xml_filename}")
|
||||
sys.exit(1)
|
||||
# Buscar todos los archivos .xml recursivamente
|
||||
search_pattern = os.path.join(xml_project_dir, "**", "*.xml")
|
||||
xml_files_found = glob.glob(search_pattern, recursive=True)
|
||||
|
||||
print(f"\nStarting pipeline for: {xml_filename}")
|
||||
if not xml_files_found:
|
||||
print(f"No se encontraron archivos XML en '{xml_project_dir}' o sus subdirectorios.")
|
||||
sys.exit(0) # Salir limpiamente si no hay archivos
|
||||
|
||||
# Run scripts sequentially (asegúrate que los nombres son correctos)
|
||||
print(f"Se encontraron {len(xml_files_found)} archivos XML para procesar:")
|
||||
xml_files_found.sort() # Ordenar para consistencia
|
||||
for xml_file in xml_files_found:
|
||||
print(f" - {os.path.relpath(xml_file, script_dir)}")
|
||||
|
||||
# --- PARTE 2: PROCESAR CADA ARCHIVO ---
|
||||
# Scripts a ejecutar en secuencia
|
||||
script1 = "x1_to_json.py"
|
||||
script2 = "x2_process.py"
|
||||
script3 = "x3_generate_scl.py"
|
||||
|
||||
if run_script(script1, xml_filename):
|
||||
if run_script(script2, xml_filename):
|
||||
if run_script(script3, xml_filename):
|
||||
print("\nPipeline completed successfully.")
|
||||
processed_count = 0
|
||||
failed_count = 0
|
||||
|
||||
# Procesar cada archivo encontrado en el bucle
|
||||
for xml_filepath in xml_files_found:
|
||||
relative_path = os.path.relpath(xml_filepath, script_dir)
|
||||
print(f"\n--- Iniciando pipeline para: {relative_path} ---")
|
||||
|
||||
# Usar la ruta absoluta para los scripts hijos
|
||||
absolute_xml_filepath = os.path.abspath(xml_filepath)
|
||||
|
||||
# Ejecutar los scripts en secuencia
|
||||
success = True
|
||||
if not run_script(script1, absolute_xml_filepath):
|
||||
print(f"\nPipeline falló en el script '{script1}' para el archivo: {relative_path}", file=sys.stderr)
|
||||
success = False
|
||||
elif not run_script(script2, absolute_xml_filepath):
|
||||
print(f"\nPipeline falló en el script '{script2}' para el archivo: {relative_path}", file=sys.stderr)
|
||||
success = False
|
||||
elif not run_script(script3, absolute_xml_filepath):
|
||||
print(f"\nPipeline falló en el script '{script3}' para el archivo: {relative_path}", file=sys.stderr)
|
||||
success = False
|
||||
|
||||
# Actualizar contadores y mostrar estado
|
||||
if success:
|
||||
print(f"--- Pipeline completado exitosamente para: {relative_path} ---")
|
||||
processed_count += 1
|
||||
else:
|
||||
print("\nPipeline failed at script:", script3)
|
||||
failed_count += 1
|
||||
print(f"--- Pipeline falló para: {relative_path} ---", file=sys.stderr) # Indicar fallo
|
||||
|
||||
# --- PARTE 3: RESUMEN FINAL ---
|
||||
print("\n--- Resumen Final del Procesamiento ---")
|
||||
print(f"Total de archivos XML encontrados: {len(xml_files_found)}")
|
||||
print(f"Archivos procesados exitosamente por el pipeline completo: {processed_count}")
|
||||
print(f"Archivos que fallaron en algún punto del pipeline: {failed_count}")
|
||||
print("---------------------------------------")
|
||||
|
||||
# Salir con código 0 si todo fue bien, 1 si hubo fallos
|
||||
if failed_count > 0:
|
||||
sys.exit(1)
|
||||
else:
|
||||
print("\nPipeline failed at script:", script2)
|
||||
else:
|
||||
print("\nPipeline failed at script:", script1)
|
||||
sys.exit(0)
|
||||
|
||||
# --- FIN: Se elimina la lógica redundante que venía después del bucle ---
|
800
x1_to_json.py
800
x1_to_json.py
File diff suppressed because it is too large
Load Diff
505
x2_process.py
505
x2_process.py
|
@ -18,16 +18,14 @@ from processors.processor_utils import (
|
|||
from processors.symbol_manager import SymbolManager # Import the manager
|
||||
|
||||
# --- Constantes y Configuración ---
|
||||
# SCL_SUFFIX = "_scl" # Old suffix
|
||||
SCL_SUFFIX = "_sympy_processed" # New suffix to indicate processing method
|
||||
GROUPED_COMMENT = "// Logic included in grouped IF"
|
||||
SIMPLIFIED_IF_COMMENT = "// Simplified IF condition by script" # May still be useful
|
||||
|
||||
# Global data dictionary (consider passing 'data' as argument if needed elsewhere)
|
||||
# It's currently used by process_group_ifs implicitly via the outer scope,
|
||||
# which works but passing it explicitly might be cleaner.
|
||||
# Global data dictionary
|
||||
data = {}
|
||||
|
||||
# --- (Incluye aquí las funciones process_group_ifs y load_processors SIN CAMBIOS) ---
|
||||
def process_group_ifs(instruction, network_id, sympy_map, symbol_manager, data):
|
||||
"""
|
||||
Busca condiciones (ya procesadas -> tienen expr SymPy en sympy_map)
|
||||
|
@ -37,24 +35,45 @@ def process_group_ifs(instruction, network_id, sympy_map, symbol_manager, data):
|
|||
(Esta es la implementación de la función como la tenías en el archivo original)
|
||||
"""
|
||||
instr_uid = instruction["instruction_uid"]
|
||||
instr_type_original = instruction.get("type", "").replace(SCL_SUFFIX, "").replace("_error", "")
|
||||
instr_type_original = (
|
||||
instruction.get("type", "").replace(SCL_SUFFIX, "").replace("_error", "")
|
||||
)
|
||||
made_change = False
|
||||
|
||||
# Check if this instruction *could* generate a condition suitable for grouping
|
||||
# It must have been processed by the new SymPy method
|
||||
if (
|
||||
not instruction.get("type", "").endswith(SCL_SUFFIX) # Check if processed by new method
|
||||
not instruction.get("type", "").endswith(
|
||||
SCL_SUFFIX
|
||||
) # Check if processed by new method
|
||||
or "_error" in instruction.get("type", "")
|
||||
or instruction.get("grouped", False)
|
||||
or instr_type_original not in [ # Original types that produce boolean results
|
||||
"Contact", "O", "Eq", "Ne", "Gt", "Lt", "Ge", "Le", "PBox", "NBox", "And", "Xor", "Not" # Add others like comparison
|
||||
or instr_type_original
|
||||
not in [ # Original types that produce boolean results
|
||||
"Contact",
|
||||
"O",
|
||||
"Eq",
|
||||
"Ne",
|
||||
"Gt",
|
||||
"Lt",
|
||||
"Ge",
|
||||
"Le",
|
||||
"PBox",
|
||||
"NBox",
|
||||
"And",
|
||||
"Xor",
|
||||
"Not", # Add others like comparison
|
||||
]
|
||||
):
|
||||
return False
|
||||
|
||||
# Avoid reagruping if SCL already contains a complex IF (less likely now)
|
||||
current_scl = instruction.get("scl", "")
|
||||
if current_scl.strip().startswith("IF") and "END_IF;" in current_scl and GROUPED_COMMENT not in current_scl:
|
||||
if (
|
||||
current_scl.strip().startswith("IF")
|
||||
and "END_IF;" in current_scl
|
||||
and GROUPED_COMMENT not in current_scl
|
||||
):
|
||||
return False
|
||||
|
||||
# *** Get the SymPy expression for the condition ***
|
||||
|
@ -62,20 +81,37 @@ def process_group_ifs(instruction, network_id, sympy_map, symbol_manager, data):
|
|||
sympy_condition_expr = sympy_map.get(map_key_out)
|
||||
|
||||
# No SymPy expression found or trivial conditions
|
||||
if sympy_condition_expr is None or sympy_condition_expr in [sympy.true, sympy.false]:
|
||||
if sympy_condition_expr is None or sympy_condition_expr in [
|
||||
sympy.true,
|
||||
sympy.false,
|
||||
]:
|
||||
return False
|
||||
|
||||
# --- Find consumer instructions (logic similar to before) ---
|
||||
grouped_instructions_cores = []
|
||||
consumer_instr_list = []
|
||||
network_logic = next((net["logic"] for net in data["networks"] if net["id"] == network_id), [])
|
||||
if not network_logic: return False
|
||||
network_logic = next(
|
||||
(net["logic"] for net in data["networks"] if net["id"] == network_id), []
|
||||
)
|
||||
if not network_logic:
|
||||
return False
|
||||
|
||||
groupable_types = [ # Types whose *final SCL* we want to group
|
||||
"Move", "Add", "Sub", "Mul", "Div", "Mod", "Convert",
|
||||
"Call_FC", "Call_FB", # Assuming these generate final SCL in their processors now
|
||||
"Move",
|
||||
"Add",
|
||||
"Sub",
|
||||
"Mul",
|
||||
"Div",
|
||||
"Mod",
|
||||
"Convert",
|
||||
"Call_FC",
|
||||
"Call_FB", # Assuming these generate final SCL in their processors now
|
||||
# SCoil/RCoil might also be groupable if their SCL is final assignment
|
||||
"SCoil", "RCoil"
|
||||
"SCoil",
|
||||
"RCoil",
|
||||
"BLKMOV", # Added BLKMOV
|
||||
"TON", "TOF", "TP", "Se", "Sd", # Added timers
|
||||
"CTU", "CTD", "CTUD", # Added counters
|
||||
]
|
||||
|
||||
for consumer_instr in network_logic:
|
||||
|
@ -85,29 +121,43 @@ def process_group_ifs(instruction, network_id, sympy_map, symbol_manager, data):
|
|||
|
||||
consumer_en = consumer_instr.get("inputs", {}).get("en")
|
||||
consumer_type = consumer_instr.get("type", "") # Current type suffix matters
|
||||
consumer_type_original = consumer_type.replace(SCL_SUFFIX, "").replace("_error", "")
|
||||
consumer_type_original = consumer_type.replace(SCL_SUFFIX, "").replace(
|
||||
"_error", ""
|
||||
)
|
||||
|
||||
is_enabled_by_us = False
|
||||
if ( isinstance(consumer_en, dict) and consumer_en.get("type") == "connection" and
|
||||
consumer_en.get("source_instruction_uid") == instr_uid and
|
||||
consumer_en.get("source_pin") == "out"):
|
||||
if (
|
||||
isinstance(consumer_en, dict)
|
||||
and consumer_en.get("type") == "connection"
|
||||
and consumer_en.get("source_instruction_uid") == instr_uid
|
||||
and consumer_en.get("source_pin") == "out"
|
||||
):
|
||||
is_enabled_by_us = True
|
||||
|
||||
# Check if consumer is groupable AND has its final SCL generated
|
||||
# The suffix check needs adjustment based on how terminating processors set it.
|
||||
# Assuming processors like Move, Add, Call, SCoil, RCoil NOW generate final SCL and add a suffix.
|
||||
if ( is_enabled_by_us and consumer_type.endswith(SCL_SUFFIX) and # Or a specific "final_scl" suffix
|
||||
consumer_type_original in groupable_types ):
|
||||
if (
|
||||
is_enabled_by_us
|
||||
and consumer_type.endswith(SCL_SUFFIX) # Check if processed
|
||||
and consumer_type_original in groupable_types
|
||||
):
|
||||
|
||||
consumer_scl = consumer_instr.get("scl", "")
|
||||
# Extract core SCL (logic is similar, maybe simpler if SCL is cleaner now)
|
||||
# Extract core SCL
|
||||
core_scl = None
|
||||
if consumer_scl:
|
||||
# If consumer SCL itself is an IF generated by EN, take the body
|
||||
if consumer_scl.strip().startswith("IF"):
|
||||
match = re.search(r"THEN\s*(.*?)\s*END_IF;", consumer_scl, re.DOTALL | re.IGNORECASE)
|
||||
match = re.search(
|
||||
r"IF\s+.*?THEN\s*(.*?)\s*END_IF;", # More robust regex
|
||||
consumer_scl,
|
||||
re.DOTALL | re.IGNORECASE,
|
||||
)
|
||||
core_scl = match.group(1).strip() if match else None
|
||||
elif not consumer_scl.strip().startswith("//"): # Otherwise, take the whole line if not comment
|
||||
# If body contains another IF, maybe don't group? (optional complexity)
|
||||
# if core_scl and core_scl.strip().startswith("IF"): core_scl = None
|
||||
elif not consumer_scl.strip().startswith(
|
||||
"//"
|
||||
): # Otherwise, take the whole line if not comment
|
||||
core_scl = consumer_scl.strip()
|
||||
|
||||
if core_scl:
|
||||
|
@ -116,12 +166,16 @@ def process_group_ifs(instruction, network_id, sympy_map, symbol_manager, data):
|
|||
|
||||
# --- If groupable consumers found ---
|
||||
if len(grouped_instructions_cores) > 1:
|
||||
print(f"INFO: Agrupando {len(grouped_instructions_cores)} instr. bajo condición de {instr_type_original} UID {instr_uid}")
|
||||
print(
|
||||
f"INFO: Agrupando {len(grouped_instructions_cores)} instr. bajo condición de {instr_type_original} UID {instr_uid}"
|
||||
)
|
||||
|
||||
# *** Simplify the SymPy condition ***
|
||||
try:
|
||||
# simplified_expr = sympy.simplify_logic(sympy_condition_expr, force=True)
|
||||
simplified_expr = sympy.logic.boolalg.to_dnf(sympy_condition_expr, simplify=True)
|
||||
simplified_expr = sympy.logic.boolalg.to_dnf(
|
||||
sympy_condition_expr, simplify=True
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Error simplifying condition for grouping UID {instr_uid}: {e}")
|
||||
simplified_expr = sympy_condition_expr # Fallback
|
||||
|
@ -132,7 +186,9 @@ def process_group_ifs(instruction, network_id, sympy_map, symbol_manager, data):
|
|||
# *** Build the grouped IF SCL ***
|
||||
scl_grouped_lines = [f"IF {condition_scl_simplified} THEN"]
|
||||
for core_line in grouped_instructions_cores:
|
||||
indented_core = "\n".join([f" {line.strip()}" for line in core_line.splitlines()])
|
||||
indented_core = "\n".join(
|
||||
[f" {line.strip()}" for line in core_line.splitlines()]
|
||||
)
|
||||
scl_grouped_lines.append(indented_core)
|
||||
scl_grouped_lines.append("END_IF;")
|
||||
final_grouped_scl = "\n".join(scl_grouped_lines)
|
||||
|
@ -147,6 +203,7 @@ def process_group_ifs(instruction, network_id, sympy_map, symbol_manager, data):
|
|||
|
||||
return made_change
|
||||
|
||||
|
||||
def load_processors(processors_dir="processors"):
|
||||
"""
|
||||
Escanea el directorio, importa módulos, construye el mapa y una lista
|
||||
|
@ -170,7 +227,9 @@ def load_processors(processors_dir="processors"):
|
|||
try:
|
||||
module = importlib.import_module(full_module_name)
|
||||
|
||||
if hasattr(module, 'get_processor_info') and callable(module.get_processor_info):
|
||||
if hasattr(module, "get_processor_info") and callable(
|
||||
module.get_processor_info
|
||||
):
|
||||
processor_info = module.get_processor_info()
|
||||
info_list = []
|
||||
if isinstance(processor_info, dict):
|
||||
|
@ -178,29 +237,51 @@ def load_processors(processors_dir="processors"):
|
|||
elif isinstance(processor_info, list):
|
||||
info_list = processor_info
|
||||
else:
|
||||
print(f" Advertencia: get_processor_info en {full_module_name} devolvió tipo inesperado. Se ignora.")
|
||||
print(
|
||||
f" Advertencia: get_processor_info en {full_module_name} devolvió tipo inesperado. Se ignora."
|
||||
)
|
||||
continue
|
||||
|
||||
for info in info_list:
|
||||
if isinstance(info, dict) and 'type_name' in info and 'processor_func' in info:
|
||||
type_name = info['type_name'].lower()
|
||||
processor_func = info['processor_func']
|
||||
if (
|
||||
isinstance(info, dict)
|
||||
and "type_name" in info
|
||||
and "processor_func" in info
|
||||
):
|
||||
type_name = info["type_name"].lower()
|
||||
processor_func = info["processor_func"]
|
||||
# Obtener prioridad, usar default si no existe
|
||||
priority = info.get('priority', default_priority)
|
||||
priority = info.get("priority", default_priority)
|
||||
|
||||
if callable(processor_func):
|
||||
if type_name in processor_map:
|
||||
print(f" Advertencia: '{type_name}' en {full_module_name} sobrescribe definición anterior.")
|
||||
print(
|
||||
f" Advertencia: '{type_name}' en {full_module_name} sobrescribe definición anterior."
|
||||
)
|
||||
processor_map[type_name] = processor_func
|
||||
# Añadir a la lista para ordenar
|
||||
processor_list_unsorted.append({'priority': priority, 'type_name': type_name, 'func': processor_func})
|
||||
print(f" - Cargado '{type_name}' (Prio: {priority}) desde {module_name_rel}.py")
|
||||
processor_list_unsorted.append(
|
||||
{
|
||||
"priority": priority,
|
||||
"type_name": type_name,
|
||||
"func": processor_func,
|
||||
}
|
||||
)
|
||||
print(
|
||||
f" - Cargado '{type_name}' (Prio: {priority}) desde {module_name_rel}.py"
|
||||
)
|
||||
else:
|
||||
print(f" Advertencia: 'processor_func' para '{type_name}' en {full_module_name} no es callable.")
|
||||
print(
|
||||
f" Advertencia: 'processor_func' para '{type_name}' en {full_module_name} no es callable."
|
||||
)
|
||||
else:
|
||||
print(f" Advertencia: Entrada inválida en {full_module_name}: {info}")
|
||||
print(
|
||||
f" Advertencia: Entrada inválida en {full_module_name}: {info}"
|
||||
)
|
||||
else:
|
||||
print(f" Advertencia: Módulo {module_name_rel}.py no tiene 'get_processor_info'.")
|
||||
print(
|
||||
f" Advertencia: Módulo {module_name_rel}.py no tiene 'get_processor_info'."
|
||||
)
|
||||
|
||||
except ImportError as e:
|
||||
print(f"Error importando {full_module_name}: {e}")
|
||||
|
@ -209,22 +290,23 @@ def load_processors(processors_dir="processors"):
|
|||
traceback.print_exc()
|
||||
|
||||
# Ordenar la lista por prioridad (menor primero)
|
||||
processor_list_sorted = sorted(processor_list_unsorted, key=lambda x: x['priority'])
|
||||
processor_list_sorted = sorted(processor_list_unsorted, key=lambda x: x["priority"])
|
||||
|
||||
print(f"\nTotal de tipos de procesadores cargados: {len(processor_map)}")
|
||||
print(f"Orden de procesamiento por prioridad: {[item['type_name'] for item in processor_list_sorted]}")
|
||||
print(
|
||||
f"Orden de procesamiento por prioridad: {[item['type_name'] for item in processor_list_sorted]}"
|
||||
)
|
||||
|
||||
# Devolver el mapa (para lookup rápido si es necesario) y la lista ordenada
|
||||
return processor_map, processor_list_sorted
|
||||
|
||||
# --- Bucle Principal de Procesamiento (Modificado para STL) ---
|
||||
# --- Bucle Principal de Procesamiento (Modificado para STL y tipo de bloque) ---
|
||||
def process_json_to_scl(json_filepath):
|
||||
"""
|
||||
Lee el JSON simplificado, aplica los procesadores dinámicamente cargados
|
||||
siguiendo un orden de prioridad (ignorando redes STL), y guarda el JSON procesado.
|
||||
Lee JSON simplificado, aplica procesadores dinámicos (ignorando redes STL y bloques DB),
|
||||
y guarda JSON procesado.
|
||||
"""
|
||||
global data # Necesario para que load_processors y process_group_ifs (definidas fuera) puedan acceder a ella.
|
||||
# Considerar pasar 'data' como argumento si es posible refactorizar.
|
||||
global data
|
||||
|
||||
if not os.path.exists(json_filepath):
|
||||
print(f"Error: JSON no encontrado: {json_filepath}")
|
||||
|
@ -232,48 +314,82 @@ def process_json_to_scl(json_filepath):
|
|||
print(f"Cargando JSON desde: {json_filepath}")
|
||||
try:
|
||||
with open(json_filepath, "r", encoding="utf-8") as f:
|
||||
data = json.load(f) # Carga en 'data' global
|
||||
data = json.load(f)
|
||||
except Exception as e:
|
||||
print(f"Error al cargar JSON: {e}")
|
||||
traceback.print_exc()
|
||||
return
|
||||
|
||||
# --- Carga dinámica de procesadores ---
|
||||
# --- MODIFICADO: Obtener tipo de bloque (FC, FB, GlobalDB, OB) ---
|
||||
block_type = data.get("block_type", "Unknown") # FC, FB, GlobalDB, OB
|
||||
print(f"Procesando bloque tipo: {block_type}, Lenguaje principal: {data.get('language', 'Unknown')}")
|
||||
|
||||
# --- MODIFICADO: SI ES UN GlobalDB, SALTAR EL PROCESAMIENTO LÓGICO ---
|
||||
if block_type == "GlobalDB": # <-- Comprobar tipo de bloque
|
||||
print(
|
||||
"INFO: El bloque es un Data Block (GlobalDB). Saltando procesamiento lógico de x2."
|
||||
)
|
||||
# Simplemente guardamos una copia (o el mismo archivo si no se requiere sufijo)
|
||||
output_filename = json_filepath.replace(
|
||||
"_simplified.json", "_simplified_processed.json"
|
||||
)
|
||||
print(f"Guardando JSON de DB (sin cambios lógicos) en: {output_filename}")
|
||||
try:
|
||||
with open(output_filename, "w", encoding="utf-8") as f:
|
||||
json.dump(data, f, indent=4, ensure_ascii=False)
|
||||
print("Guardado de DB completado.")
|
||||
except Exception as e:
|
||||
print(f"Error Crítico al guardar JSON del DB: {e}")
|
||||
traceback.print_exc()
|
||||
return # <<< SALIR TEMPRANO PARA DBs
|
||||
|
||||
# --- SI NO ES DB (FC, FB, OB), CONTINUAR CON EL PROCESAMIENTO LÓGICO ---
|
||||
print(f"INFO: El bloque es {block_type}. Iniciando procesamiento lógico...") # <-- Mensaje actualizado
|
||||
|
||||
script_dir = os.path.dirname(__file__)
|
||||
processors_dir_path = os.path.join(script_dir, 'processors')
|
||||
processors_dir_path = os.path.join(script_dir, "processors")
|
||||
processor_map, sorted_processors = load_processors(processors_dir_path)
|
||||
if not processor_map:
|
||||
print("Error crítico: No se cargaron procesadores. Abortando.")
|
||||
return
|
||||
|
||||
# --- Crear mapas de acceso por red ---
|
||||
network_access_maps = {}
|
||||
# (La lógica para llenar network_access_maps no cambia, puedes copiarla de tu original)
|
||||
# Crear mapas de acceso por red (copiado/adaptado de versión anterior)
|
||||
for network in data.get("networks", []):
|
||||
net_id = network["id"]
|
||||
current_access_map = {}
|
||||
for instr in network.get("logic", []):
|
||||
for _, source in instr.get("inputs", {}).items():
|
||||
sources_to_check = (source if isinstance(source, list) else ([source] if isinstance(source, dict) else []))
|
||||
sources_to_check = (
|
||||
source
|
||||
if isinstance(source, list)
|
||||
else ([source] if isinstance(source, dict) else [])
|
||||
)
|
||||
for src in sources_to_check:
|
||||
if (isinstance(src, dict) and src.get("uid") and src.get("type") in ["variable", "constant"]):
|
||||
if (
|
||||
isinstance(src, dict)
|
||||
and src.get("uid")
|
||||
and src.get("type") in ["variable", "constant"]
|
||||
):
|
||||
current_access_map[src["uid"]] = src
|
||||
for _, dest_list in instr.get("outputs", {}).items():
|
||||
if isinstance(dest_list, list):
|
||||
for dest in dest_list:
|
||||
if (isinstance(dest, dict) and dest.get("uid") and dest.get("type") in ["variable", "constant"]):
|
||||
if (
|
||||
isinstance(dest, dict)
|
||||
and dest.get("uid")
|
||||
and dest.get("type") in ["variable", "constant"]
|
||||
):
|
||||
current_access_map[dest["uid"]] = dest
|
||||
network_access_maps[net_id] = current_access_map
|
||||
|
||||
# --- Inicializar mapa SymPy y SymbolManager ---
|
||||
symbol_manager = SymbolManager()
|
||||
sympy_map = {}
|
||||
|
||||
max_passes = 30
|
||||
passes = 0
|
||||
processing_complete = False
|
||||
|
||||
print("\n--- Iniciando Bucle de Procesamiento Iterativo (con SymPy y prioridad) ---")
|
||||
print(f"\n--- Iniciando Bucle de Procesamiento Iterativo ({block_type}) ---") # <-- Mensaje actualizado
|
||||
while passes < max_passes and not processing_complete:
|
||||
passes += 1
|
||||
made_change_in_base_pass = False
|
||||
|
@ -284,90 +400,122 @@ def process_json_to_scl(json_filepath):
|
|||
|
||||
# --- FASE 1: Procesadores Base (Ignorando STL) ---
|
||||
print(f" Fase 1 (SymPy Base - Orden por Prioridad):")
|
||||
num_sympy_processed_this_pass = 0
|
||||
num_sympy_processed_this_pass = 0 # Resetear contador para el pase
|
||||
for processor_info in sorted_processors:
|
||||
current_type_name = processor_info['type_name']
|
||||
func_to_call = processor_info['func']
|
||||
|
||||
current_type_name = processor_info["type_name"]
|
||||
func_to_call = processor_info["func"]
|
||||
for network in data.get("networks", []):
|
||||
network_id = network["id"]
|
||||
network_lang = network.get("language", "LAD") # Obtener lenguaje de la red
|
||||
|
||||
# *** IGNORAR REDES STL EN ESTA FASE ***
|
||||
if network_lang == "STL":
|
||||
continue # Saltar al siguiente network
|
||||
network_lang = network.get("language", "LAD") # Lenguaje de la red
|
||||
if network_lang == "STL": # Saltar redes STL
|
||||
continue
|
||||
|
||||
access_map = network_access_maps.get(network_id, {})
|
||||
network_logic = network.get("logic", [])
|
||||
|
||||
for instruction in network_logic:
|
||||
instr_uid = instruction.get("instruction_uid")
|
||||
instr_type_original = instruction.get("type", "Unknown")
|
||||
# Usar el tipo *actual* de la instrucción para el lookup
|
||||
instr_type_current = instruction.get("type", "Unknown")
|
||||
|
||||
# Saltar si ya procesado, error, agrupado o es chunk STL/SCL/Unsupported
|
||||
if (instr_type_original.endswith(SCL_SUFFIX)
|
||||
or "_error" in instr_type_original
|
||||
# Saltar si ya está procesado, es error, agrupado, o tipo crudo
|
||||
if (
|
||||
instr_type_current.endswith(SCL_SUFFIX)
|
||||
or "_error" in instr_type_current
|
||||
or instruction.get("grouped", False)
|
||||
or instr_type_original in ["RAW_STL_CHUNK", "RAW_SCL_CHUNK", "UNSUPPORTED_LANG"]):
|
||||
or instr_type_current
|
||||
in ["RAW_STL_CHUNK", "RAW_SCL_CHUNK", "UNSUPPORTED_LANG", "UNSUPPORTED_CONTENT", "PARSING_ERROR"]
|
||||
):
|
||||
continue
|
||||
|
||||
# Determinar tipo efectivo (como antes)
|
||||
lookup_key = instr_type_original.lower()
|
||||
# El lookup usa el tipo actual (que aún no tiene el sufijo)
|
||||
lookup_key = instr_type_current.lower()
|
||||
effective_type_name = lookup_key
|
||||
if instr_type_original == "Call":
|
||||
block_type = instruction.get("block_type", "").upper()
|
||||
if block_type == "FC": effective_type_name = "call_fc"
|
||||
elif block_type == "FB": effective_type_name = "call_fb"
|
||||
|
||||
# Llamar al procesador si coincide el tipo
|
||||
# Mapeo especial para llamadas FC/FB
|
||||
if instr_type_current == "Call":
|
||||
call_block_type = instruction.get("block_type", "").upper()
|
||||
if call_block_type == "FC":
|
||||
effective_type_name = "call_fc"
|
||||
elif call_block_type == "FB":
|
||||
effective_type_name = "call_fb"
|
||||
# Añadir otros tipos de llamada si es necesario
|
||||
|
||||
# Si el tipo efectivo coincide con el procesador actual
|
||||
if effective_type_name == current_type_name:
|
||||
try:
|
||||
# Pasa sympy_map, symbol_manager y data
|
||||
changed = func_to_call(instruction, network_id, sympy_map, symbol_manager, data)
|
||||
# Pasar 'data' a la función del procesador
|
||||
changed = func_to_call(
|
||||
instruction, network_id, sympy_map, symbol_manager, data
|
||||
)
|
||||
if changed:
|
||||
made_change_in_base_pass = True
|
||||
num_sympy_processed_this_pass += 1
|
||||
except Exception as e:
|
||||
print(f"ERROR(SymPy Base) al procesar {instr_type_original} UID {instr_uid}: {e}")
|
||||
print(
|
||||
f"ERROR(SymPy Base) al procesar {instr_type_current} UID {instr_uid}: {e}"
|
||||
)
|
||||
traceback.print_exc()
|
||||
instruction["scl"] = f"// ERROR en SymPy procesador base: {e}"
|
||||
instruction["type"] = instr_type_original + "_error"
|
||||
made_change_in_base_pass = True # Marcar cambio aunque sea error
|
||||
print(f" -> {num_sympy_processed_this_pass} instrucciones (no STL) procesadas con SymPy.")
|
||||
instruction["scl"] = (
|
||||
f"// ERROR en SymPy procesador base: {e}"
|
||||
)
|
||||
# Añadir sufijo de error al tipo actual
|
||||
instruction["type"] = instr_type_current + "_error"
|
||||
made_change_in_base_pass = True # Se hizo un cambio (marcar como error)
|
||||
print(
|
||||
f" -> {num_sympy_processed_this_pass} instrucciones (no STL) procesadas con SymPy."
|
||||
)
|
||||
|
||||
|
||||
# --- FASE 2: Agrupación IF (Ignorando STL) ---
|
||||
if made_change_in_base_pass or passes == 1:
|
||||
if (
|
||||
made_change_in_base_pass or passes == 1
|
||||
): # Ejecutar siempre en el primer pase o si hubo cambios
|
||||
print(f" Fase 2 (Agrupación IF con Simplificación):")
|
||||
num_grouped_this_pass = 0
|
||||
num_grouped_this_pass = 0 # Resetear contador para el pase
|
||||
for network in data.get("networks", []):
|
||||
network_id = network["id"]
|
||||
network_lang = network.get("language", "LAD") # Obtener lenguaje
|
||||
|
||||
# *** IGNORAR REDES STL EN ESTA FASE ***
|
||||
network_lang = network.get("language", "LAD")
|
||||
if network_lang == "STL":
|
||||
continue # Saltar red STL
|
||||
|
||||
continue # Saltar STL
|
||||
network_logic = network.get("logic", [])
|
||||
for instruction in network_logic:
|
||||
# Iterar en orden por UID puede ser más estable para agrupación
|
||||
uids_in_network = sorted([instr.get("instruction_uid", "Z") for instr in network_logic if instr.get("instruction_uid")])
|
||||
for uid_to_process in uids_in_network:
|
||||
instruction = next((instr for instr in network_logic if instr.get("instruction_uid") == uid_to_process), None)
|
||||
if not instruction: continue
|
||||
|
||||
# Saltar si ya está agrupada, es error, etc.
|
||||
if instruction.get("grouped") or "_error" in instruction.get("type", ""):
|
||||
continue
|
||||
# La agrupación sólo aplica a instrucciones que generan condiciones booleanas
|
||||
# y que ya fueron procesadas (tienen el sufijo)
|
||||
if instruction.get("type", "").endswith(SCL_SUFFIX):
|
||||
try:
|
||||
# Llama a process_group_ifs (que necesita acceso a 'data' global o pasado)
|
||||
group_changed = process_group_ifs(instruction, network_id, sympy_map, symbol_manager, data)
|
||||
group_changed = process_group_ifs(
|
||||
instruction, network_id, sympy_map, symbol_manager, data
|
||||
)
|
||||
if group_changed:
|
||||
made_change_in_group_pass = True
|
||||
num_grouped_this_pass += 1
|
||||
except Exception as e:
|
||||
print(f"ERROR(GroupLoop) al intentar agrupar desde UID {instruction.get('instruction_uid')}: {e}")
|
||||
print(
|
||||
f"ERROR(GroupLoop) al intentar agrupar desde UID {instruction.get('instruction_uid')}: {e}"
|
||||
)
|
||||
traceback.print_exc()
|
||||
print(f" -> {num_grouped_this_pass} agrupaciones realizadas (en redes no STL).")
|
||||
|
||||
print(
|
||||
f" -> {num_grouped_this_pass} agrupaciones realizadas (en redes no STL)."
|
||||
)
|
||||
|
||||
# --- Comprobar si se completó el procesamiento ---
|
||||
if not made_change_in_base_pass and not made_change_in_group_pass:
|
||||
print(f"\n--- No se hicieron más cambios en el pase {passes}. Proceso iterativo completado. ---")
|
||||
print(
|
||||
f"\n--- No se hicieron más cambios en el pase {passes}. Proceso iterativo completado. ---"
|
||||
)
|
||||
processing_complete = True
|
||||
else:
|
||||
print(f"--- Fin Pase {passes}: {num_sympy_processed_this_pass} proc SymPy, {num_grouped_this_pass} agrup. Continuando...")
|
||||
print(
|
||||
f"--- Fin Pase {passes}: {num_sympy_processed_this_pass} proc SymPy, {num_grouped_this_pass} agrup. Continuando..."
|
||||
)
|
||||
|
||||
# --- Comprobar límite de pases ---
|
||||
if passes == max_passes and not processing_complete:
|
||||
|
@ -376,46 +524,53 @@ def process_json_to_scl(json_filepath):
|
|||
# --- FIN BUCLE ITERATIVO ---
|
||||
|
||||
# --- Verificación Final (Ajustada para RAW_STL_CHUNK) ---
|
||||
print("\n--- Verificación Final de Instrucciones No Procesadas ---")
|
||||
print(f"\n--- Verificación Final de Instrucciones No Procesadas ({block_type}) ---") # <-- Mensaje actualizado
|
||||
unprocessed_count = 0
|
||||
unprocessed_details = []
|
||||
# Añadir RAW_STL_CHUNK a los tipos ignorados
|
||||
ignored_types = ['raw_scl_chunk', 'unsupported_lang', 'raw_stl_chunk'] # Añadido raw_stl_chunk
|
||||
|
||||
ignored_types = [
|
||||
"raw_scl_chunk",
|
||||
"unsupported_lang",
|
||||
"raw_stl_chunk",
|
||||
"unsupported_content", # Añadido de x1
|
||||
"parsing_error", # Añadido de x1
|
||||
]
|
||||
for network in data.get("networks", []):
|
||||
network_id = network.get("id", "Unknown ID")
|
||||
network_title = network.get("title", f"Network {network_id}")
|
||||
network_lang = network.get("language", "LAD") # Obtener lenguaje
|
||||
|
||||
# No verificar instrucciones dentro de redes STL, ya que no se procesan
|
||||
network_lang = network.get("language", "LAD")
|
||||
if network_lang == "STL":
|
||||
continue
|
||||
|
||||
continue # No verificar redes STL
|
||||
for instruction in network.get("logic", []):
|
||||
instr_uid = instruction.get("instruction_uid", "Unknown UID")
|
||||
instr_type = instruction.get("type", "Unknown Type")
|
||||
is_grouped = instruction.get("grouped", False)
|
||||
|
||||
# Condición revisada para ignorar los chunks crudos
|
||||
if (not instr_type.endswith(SCL_SUFFIX) and
|
||||
"_error" not in instr_type and
|
||||
not is_grouped and
|
||||
instr_type.lower() not in ignored_types): # Verifica contra lista actualizada
|
||||
if (
|
||||
not instr_type.endswith(SCL_SUFFIX)
|
||||
and "_error" not in instr_type
|
||||
and not is_grouped
|
||||
and instr_type.lower() not in ignored_types
|
||||
):
|
||||
unprocessed_count += 1
|
||||
unprocessed_details.append(
|
||||
f" - Red '{network_title}' (ID: {network_id}, Lang: {network_lang}), "
|
||||
f"Instrucción UID: {instr_uid}, Tipo: '{instr_type}'"
|
||||
)
|
||||
|
||||
if unprocessed_count > 0:
|
||||
print(f"ADVERTENCIA: Se encontraron {unprocessed_count} instrucciones (no STL) que parecen no haber sido procesadas:")
|
||||
for detail in unprocessed_details: print(detail)
|
||||
print(
|
||||
f"ADVERTENCIA: Se encontraron {unprocessed_count} instrucciones (no STL) que parecen no haber sido procesadas:"
|
||||
)
|
||||
for detail in unprocessed_details:
|
||||
print(detail)
|
||||
else:
|
||||
print("INFO: Todas las instrucciones relevantes (no STL) parecen haber sido procesadas o agrupadas.")
|
||||
print(
|
||||
"INFO: Todas las instrucciones relevantes (no STL) parecen haber sido procesadas o agrupadas."
|
||||
)
|
||||
|
||||
# --- Guardar JSON Final ---
|
||||
output_filename = json_filepath.replace("_simplified.json", "_simplified_processed.json")
|
||||
print(f"\nGuardando JSON procesado en: {output_filename}")
|
||||
output_filename = json_filepath.replace(
|
||||
"_simplified.json", "_simplified_processed.json"
|
||||
)
|
||||
print(f"\nGuardando JSON procesado ({block_type}) en: {output_filename}") # <-- Mensaje actualizado
|
||||
try:
|
||||
with open(output_filename, "w", encoding="utf-8") as f:
|
||||
json.dump(data, f, indent=4, ensure_ascii=False)
|
||||
|
@ -424,69 +579,65 @@ def process_json_to_scl(json_filepath):
|
|||
print(f"Error Crítico al guardar JSON procesado: {e}")
|
||||
traceback.print_exc()
|
||||
|
||||
# --- Ejecución (sin cambios) ---
|
||||
|
||||
# --- Ejecución (sin cambios en esta parte) ---
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Process simplified JSON to embed SCL logic.")
|
||||
parser.add_argument(
|
||||
"source_xml_filepath",
|
||||
nargs="?",
|
||||
default="TestLAD.xml",
|
||||
help="Path to the original source XML file (used to derive JSON input name, default: TestLAD.xml)"
|
||||
# Imports necesarios solo para la ejecución como script principal
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
|
||||
# Configurar ArgumentParser para recibir la ruta del XML original obligatoria
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Process simplified JSON (_simplified.json) to embed SCL logic (SymPy version). Expects original XML filepath as argument."
|
||||
)
|
||||
args = parser.parse_args()
|
||||
parser.add_argument(
|
||||
"source_xml_filepath", # Argumento posicional obligatorio
|
||||
help="Path to the original source XML file (passed from x0_main.py, used to derive JSON input name).",
|
||||
)
|
||||
args = parser.parse_args() # Parsea los argumentos de sys.argv
|
||||
|
||||
xml_filename_base = os.path.splitext(os.path.basename(args.source_xml_filepath))[0]
|
||||
xml_dir = os.path.dirname(args.source_xml_filepath)
|
||||
input_dir = xml_dir if xml_dir else os.path.dirname(__file__)
|
||||
source_xml_file = args.source_xml_filepath # Obtiene la ruta del XML original
|
||||
|
||||
# Verificar si el archivo XML original existe (como referencia, útil para depuración)
|
||||
if not os.path.exists(source_xml_file):
|
||||
print(
|
||||
f"Advertencia (x2): Archivo XML original no encontrado: '{source_xml_file}', pero se intentará encontrar el JSON correspondiente."
|
||||
)
|
||||
|
||||
# Derivar nombre del archivo JSON de entrada (_simplified.json)
|
||||
xml_filename_base = os.path.splitext(os.path.basename(source_xml_file))[0]
|
||||
# Asumir que el JSON simplificado está en el mismo directorio que el XML original
|
||||
input_dir = os.path.dirname(source_xml_file) # Directorio del XML original
|
||||
input_json_file = os.path.join(input_dir, f"{xml_filename_base}_simplified.json")
|
||||
|
||||
if not os.path.exists(input_json_file):
|
||||
print(f"Error Fatal: El archivo de entrada JSON simplificado no existe: '{input_json_file}'")
|
||||
print(f"Asegúrate de haber ejecutado 'x1_to_json.py' primero sobre '{args.source_xml_filepath}'.")
|
||||
sys.exit(1)
|
||||
else:
|
||||
process_json_to_scl(input_json_file)
|
||||
parser = argparse.ArgumentParser(description="Process simplified JSON to embed SCL logic.")
|
||||
parser.add_argument(
|
||||
"source_xml_filepath",
|
||||
nargs="?",
|
||||
default="TestLAD.xml",
|
||||
help="Path to the original source XML file (used to derive JSON input name, default: TestLAD.xml)"
|
||||
# Determinar el nombre esperado del archivo JSON procesado de salida
|
||||
output_json_file = os.path.join(
|
||||
input_dir, f"{xml_filename_base}_simplified_processed.json"
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
xml_filename_base = os.path.splitext(os.path.basename(args.source_xml_filepath))[0]
|
||||
xml_dir = os.path.dirname(args.source_xml_filepath)
|
||||
input_dir = xml_dir if xml_dir else os.path.dirname(__file__)
|
||||
|
||||
input_json_file = os.path.join(input_dir, f"{xml_filename_base}_simplified.json")
|
||||
|
||||
if not os.path.exists(input_json_file):
|
||||
print(f"Error Fatal: El archivo de entrada JSON simplificado no existe: '{input_json_file}'")
|
||||
print(f"Asegúrate de haber ejecutado 'x1_to_json.py' primero sobre '{args.source_xml_filepath}'.")
|
||||
sys.exit(1)
|
||||
else:
|
||||
process_json_to_scl(input_json_file)
|
||||
parser = argparse.ArgumentParser(description="Process simplified JSON to embed SCL logic.")
|
||||
parser.add_argument(
|
||||
"source_xml_filepath",
|
||||
nargs="?",
|
||||
default="TestLAD.xml",
|
||||
help="Path to the original source XML file (used to derive JSON input name, default: TestLAD.xml)"
|
||||
print(
|
||||
f"(x2) Procesando: '{os.path.relpath(input_json_file)}' -> '{os.path.relpath(output_json_file)}'"
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
xml_filename_base = os.path.splitext(os.path.basename(args.source_xml_filepath))[0]
|
||||
# Usar directorio del script actual si el XML no tiene ruta, o la ruta del XML si la tiene
|
||||
xml_dir = os.path.dirname(args.source_xml_filepath)
|
||||
input_dir = xml_dir if xml_dir else os.path.dirname(__file__) # Directorio de entrada/salida
|
||||
|
||||
input_json_file = os.path.join(input_dir, f"{xml_filename_base}_simplified.json")
|
||||
|
||||
# Verificar si el archivo JSON de entrada (_simplified.json) EXISTE antes de procesar
|
||||
if not os.path.exists(input_json_file):
|
||||
print(f"Error Fatal: El archivo de entrada JSON simplificado no existe: '{input_json_file}'")
|
||||
print(f"Asegúrate de haber ejecutado 'x1_to_json.py' primero sobre '{args.source_xml_filepath}'.")
|
||||
sys.exit(1)
|
||||
print(
|
||||
f"Error Fatal (x2): El archivo de entrada JSON simplificado no existe: '{input_json_file}'"
|
||||
)
|
||||
print(
|
||||
f"Asegúrate de que 'x1_to_json.py' se ejecutó correctamente para '{os.path.relpath(source_xml_file)}'."
|
||||
)
|
||||
sys.exit(1) # Salir si el archivo necesario no está
|
||||
else:
|
||||
# Llamar a la función principal de procesamiento del script
|
||||
try:
|
||||
process_json_to_scl(input_json_file)
|
||||
except Exception as e:
|
||||
print(
|
||||
f"Error Crítico (x2) durante el procesamiento de '{input_json_file}': {e}"
|
||||
)
|
||||
import traceback # Asegurar que traceback está importado
|
||||
|
||||
traceback.print_exc()
|
||||
sys.exit(1) # Salir con error si la función principal falla
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue