Version Funcionante
This commit is contained in:
parent
26bc892243
commit
b74db36cf9
|
@ -0,0 +1,204 @@
|
||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[codz]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
*.scl
|
||||||
|
*.exp
|
||||||
|
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
share/python-wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.nox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
*.py.cover
|
||||||
|
.hypothesis/
|
||||||
|
.pytest_cache/
|
||||||
|
cover/
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
local_settings.py
|
||||||
|
db.sqlite3
|
||||||
|
db.sqlite3-journal
|
||||||
|
|
||||||
|
# Flask stuff:
|
||||||
|
instance/
|
||||||
|
.webassets-cache
|
||||||
|
|
||||||
|
# Scrapy stuff:
|
||||||
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
.pybuilder/
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# IPython
|
||||||
|
profile_default/
|
||||||
|
ipython_config.py
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
# For a library or package, you might want to ignore these files since the code is
|
||||||
|
# intended to run in multiple environments; otherwise, check them in:
|
||||||
|
# .python-version
|
||||||
|
|
||||||
|
# pipenv
|
||||||
|
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||||
|
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||||
|
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||||
|
# install all needed dependencies.
|
||||||
|
#Pipfile.lock
|
||||||
|
|
||||||
|
# UV
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
||||||
|
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||||
|
# commonly ignored for libraries.
|
||||||
|
#uv.lock
|
||||||
|
|
||||||
|
# poetry
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||||
|
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||||
|
# commonly ignored for libraries.
|
||||||
|
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||||
|
#poetry.lock
|
||||||
|
#poetry.toml
|
||||||
|
|
||||||
|
# pdm
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||||
|
#pdm.lock
|
||||||
|
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||||
|
# in version control.
|
||||||
|
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
|
||||||
|
.pdm.toml
|
||||||
|
.pdm-python
|
||||||
|
.pdm-build/
|
||||||
|
|
||||||
|
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||||
|
__pypackages__/
|
||||||
|
|
||||||
|
# Celery stuff
|
||||||
|
celerybeat-schedule
|
||||||
|
celerybeat.pid
|
||||||
|
|
||||||
|
# SageMath parsed files
|
||||||
|
*.sage.py
|
||||||
|
|
||||||
|
# Environments
|
||||||
|
.env
|
||||||
|
.envrc
|
||||||
|
.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
.spyproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
|
||||||
|
# mkdocs documentation
|
||||||
|
/site
|
||||||
|
|
||||||
|
# mypy
|
||||||
|
.mypy_cache/
|
||||||
|
.dmypy.json
|
||||||
|
dmypy.json
|
||||||
|
|
||||||
|
# Pyre type checker
|
||||||
|
.pyre/
|
||||||
|
|
||||||
|
# pytype static type analyzer
|
||||||
|
.pytype/
|
||||||
|
|
||||||
|
# Cython debug symbols
|
||||||
|
cython_debug/
|
||||||
|
|
||||||
|
# PyCharm
|
||||||
|
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||||
|
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||||
|
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||||
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||||
|
#.idea/
|
||||||
|
|
||||||
|
# Abstra
|
||||||
|
# Abstra is an AI-powered process automation framework.
|
||||||
|
# Ignore directories containing user credentials, local state, and settings.
|
||||||
|
# Learn more at https://abstra.io/docs
|
||||||
|
.abstra/
|
||||||
|
|
||||||
|
# Visual Studio Code
|
||||||
|
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
||||||
|
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
||||||
|
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
||||||
|
# you could uncomment the following to ignore the entire vscode folder
|
||||||
|
# .vscode/
|
||||||
|
|
||||||
|
# Ruff stuff:
|
||||||
|
.ruff_cache/
|
||||||
|
|
||||||
|
# PyPI configuration file
|
||||||
|
.pypirc
|
||||||
|
|
||||||
|
# Cursor
|
||||||
|
# Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
|
||||||
|
# exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
|
||||||
|
# refer to https://docs.cursor.com/context/ignore-files
|
||||||
|
.cursorignore
|
||||||
|
.cursorindexingignore
|
||||||
|
|
||||||
|
# Marimo
|
||||||
|
marimo/_static/
|
||||||
|
marimo/_lsp/
|
||||||
|
__marimo__/
|
|
@ -1,141 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
|
|
||||||
# Agregar el directorio padre al path
|
|
||||||
sys.path.append('.')
|
|
||||||
|
|
||||||
# Importar el convertidor
|
|
||||||
from x1_lad_converter import SimpleLadConverter
|
|
||||||
|
|
||||||
def test_arraytoreal():
|
|
||||||
"""Probar específicamente ARRAYTOREAL.EXP para verificar preservación de indentación"""
|
|
||||||
print("=== TEST: ARRAYTOREAL.EXP - Preservación de indentación ST ===")
|
|
||||||
print("-" * 60)
|
|
||||||
|
|
||||||
# Buscar el archivo
|
|
||||||
possible_paths = [
|
|
||||||
"ExportTwinCat/ARRAYTOREAL.EXP",
|
|
||||||
"../ExportTwinCat/ARRAYTOREAL.EXP",
|
|
||||||
"../../ExportTwinCat/ARRAYTOREAL.EXP",
|
|
||||||
"C:/Trabajo/SIDEL/13 - E5.007560 - Modifica O&U - SAE235/Reporte/ExportTwinCat/ARRAYTOREAL.EXP"
|
|
||||||
]
|
|
||||||
|
|
||||||
test_file = None
|
|
||||||
for path in possible_paths:
|
|
||||||
if os.path.exists(path):
|
|
||||||
test_file = path
|
|
||||||
break
|
|
||||||
|
|
||||||
if test_file is None:
|
|
||||||
print(f"❌ Error: No se encontró ARRAYTOREAL.EXP")
|
|
||||||
return
|
|
||||||
|
|
||||||
print(f"✓ Archivo encontrado: {test_file}")
|
|
||||||
print("-" * 60)
|
|
||||||
|
|
||||||
# Leer archivo original para mostrar indentación
|
|
||||||
print("📄 CÓDIGO ORIGINAL:")
|
|
||||||
with open(test_file, 'r', encoding='utf-8', errors='ignore') as f:
|
|
||||||
original_lines = f.readlines()
|
|
||||||
|
|
||||||
# Mostrar solo las líneas de código ST (después de (* @END_DECLARATION := '0' *))
|
|
||||||
st_start = False
|
|
||||||
for i, line in enumerate(original_lines):
|
|
||||||
if "@END_DECLARATION" in line:
|
|
||||||
st_start = True
|
|
||||||
continue
|
|
||||||
if st_start and line.strip() and not line.strip().startswith("END_FUNCTION"):
|
|
||||||
print(f" {i+1:2d}: '{line.rstrip()}'")
|
|
||||||
|
|
||||||
print("-" * 60)
|
|
||||||
|
|
||||||
# Crear convertidor
|
|
||||||
converter = SimpleLadConverter()
|
|
||||||
|
|
||||||
# Parsear archivo
|
|
||||||
print("🔍 PARSEANDO ARCHIVO...")
|
|
||||||
converter.parse_file(test_file)
|
|
||||||
|
|
||||||
print(f"\n📊 INFORMACIÓN DETECTADA:")
|
|
||||||
print(f" ✓ Tipo: {getattr(converter, 'program_type', 'PROGRAM')}")
|
|
||||||
print(f" ✓ Nombre: {converter.program_name}")
|
|
||||||
print(f" ✓ Path: {converter.program_path}")
|
|
||||||
print(f" ✓ Variables: {list(converter.var_sections.keys())}")
|
|
||||||
print(f" ✓ Código ST: {'Sí' if converter.st_main_code else 'No'}")
|
|
||||||
|
|
||||||
if converter.st_main_code:
|
|
||||||
print(f"\n📝 CÓDIGO ST EXTRAÍDO ({len(converter.st_main_code)} caracteres):")
|
|
||||||
for i, line in enumerate(converter.st_main_code.split('\n')[:10], 1):
|
|
||||||
print(f" {i:2d}: '{line}'")
|
|
||||||
|
|
||||||
# Generar código SCL
|
|
||||||
print(f"\n📝 GENERANDO CÓDIGO SCL...")
|
|
||||||
scl_code = converter.convert_to_structured()
|
|
||||||
|
|
||||||
# Guardar archivo de prueba
|
|
||||||
output_file = "test_arraytoreal_indent.scl"
|
|
||||||
with open(output_file, 'w', encoding='utf-8') as f:
|
|
||||||
f.write(scl_code)
|
|
||||||
|
|
||||||
print(f" ✓ Guardado en: {output_file}")
|
|
||||||
|
|
||||||
# Mostrar código SCL generado
|
|
||||||
print(f"\n📄 CÓDIGO SCL GENERADO:")
|
|
||||||
lines = scl_code.split('\n')
|
|
||||||
|
|
||||||
# Encontrar línea donde empieza el código ST
|
|
||||||
st_start_line = -1
|
|
||||||
for i, line in enumerate(lines):
|
|
||||||
if "Código ST original" in line:
|
|
||||||
st_start_line = i
|
|
||||||
break
|
|
||||||
|
|
||||||
if st_start_line > -1:
|
|
||||||
# Mostrar desde el código ST hasta el final de la función
|
|
||||||
for i in range(st_start_line, min(st_start_line + 20, len(lines))):
|
|
||||||
if i < len(lines):
|
|
||||||
line = lines[i]
|
|
||||||
if line.strip() and ("END_FUNCTION" in line or "END_PROGRAM" in line):
|
|
||||||
print(f" {i+1:2d}: {line}")
|
|
||||||
break
|
|
||||||
print(f" {i+1:2d}: {line}")
|
|
||||||
|
|
||||||
# Verificar preservación de indentación
|
|
||||||
print(f"\n🔍 VERIFICANDO PRESERVACIÓN DE INDENTACIÓN:")
|
|
||||||
|
|
||||||
if converter.st_main_code:
|
|
||||||
original_lines = converter.st_main_code.split('\n')
|
|
||||||
scl_lines = scl_code.split('\n')
|
|
||||||
|
|
||||||
# Encontrar líneas con indentación en el original
|
|
||||||
original_indented = []
|
|
||||||
for line in original_lines:
|
|
||||||
if line.startswith('\t') or line.startswith(' '):
|
|
||||||
original_indented.append(line)
|
|
||||||
|
|
||||||
# Verificar que se preserven en el SCL
|
|
||||||
if original_indented:
|
|
||||||
print(f" 📋 Líneas con indentación original: {len(original_indented)}")
|
|
||||||
print(f" Ejemplo: '{original_indented[0]}'" if original_indented else "")
|
|
||||||
|
|
||||||
# Verificar si aparecen en el SCL preservadas
|
|
||||||
preserved_count = 0
|
|
||||||
for orig_line in original_indented:
|
|
||||||
for scl_line in scl_lines:
|
|
||||||
if orig_line.strip() in scl_line and orig_line.startswith(('\t', ' ')):
|
|
||||||
preserved_count += 1
|
|
||||||
break
|
|
||||||
|
|
||||||
print(f" ✅ Indentación preservada: {preserved_count}/{len(original_indented)} líneas")
|
|
||||||
else:
|
|
||||||
print(f" ℹ No se encontraron líneas con indentación específica")
|
|
||||||
else:
|
|
||||||
print(f" ⚠ No hay código ST para verificar")
|
|
||||||
|
|
||||||
return scl_code
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
test_arraytoreal()
|
|
|
@ -1,37 +0,0 @@
|
||||||
(* Código SCL generado desde LAD TwinCAT *)
|
|
||||||
(* Convertidor mejorado con SymPy - Estructura DNF preferida *)
|
|
||||||
(* Path original: \/Functions_Collection *)
|
|
||||||
|
|
||||||
FUNCTION ArrayToReal : REAL
|
|
||||||
VAR_INPUT
|
|
||||||
mIn_Value : POINTER TO BYTE;
|
|
||||||
END_VAR
|
|
||||||
|
|
||||||
VAR
|
|
||||||
i : INT;
|
|
||||||
p : UDINT;
|
|
||||||
p1 : UDINT;
|
|
||||||
mPoint : POINTER TO BYTE;
|
|
||||||
mPoint1 : POINTER TO BYTE;
|
|
||||||
mTemp : REAL;
|
|
||||||
END_VAR
|
|
||||||
|
|
||||||
|
|
||||||
(* === CÓDIGO PRINCIPAL === *)
|
|
||||||
|
|
||||||
(* Código ST original *)
|
|
||||||
(* @END_DECLARATION := '0' *)
|
|
||||||
mPoint := ADR(mTemp);
|
|
||||||
FOR i := 3 TO 0 BY -1
|
|
||||||
DO
|
|
||||||
p1 := mIn_Value;
|
|
||||||
mPoint1 := p1 + i;
|
|
||||||
mPoint^ := mPoint1^;
|
|
||||||
p := mPoint ;
|
|
||||||
p := p + 1 ;
|
|
||||||
mPoint := p ;
|
|
||||||
END_FOR
|
|
||||||
ArrayToReal := mTemp;
|
|
||||||
|
|
||||||
END_FUNCTION
|
|
||||||
END_FUNCTION
|
|
|
@ -1,294 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
|
||||||
Script de prueba para verificar la conversión de ACTIONs LAD
|
|
||||||
"""
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
|
|
||||||
# Agregar el directorio padre al path
|
|
||||||
sys.path.append('..')
|
|
||||||
|
|
||||||
# Importar el convertidor
|
|
||||||
from x1_lad_converter import SimpleLadConverter
|
|
||||||
|
|
||||||
def test_pattern_detection():
|
|
||||||
"""Probar la detección de patrones ??? vs Function Blocks directos"""
|
|
||||||
print("=== TEST: Detección de patrones ??? vs Function Blocks ===")
|
|
||||||
print("Basado en tu observación sobre los patrones LAD de TwinCAT")
|
|
||||||
print("-" * 60)
|
|
||||||
|
|
||||||
# Crear archivo de ejemplo que simule los patrones que identificaste
|
|
||||||
test_content = """(* @PATH := '/TASK1_PID/PID_Controllers/Test_Program' *)
|
|
||||||
PROGRAM Test_Pattern_Program
|
|
||||||
VAR
|
|
||||||
mDummy : BOOL;
|
|
||||||
mFillerEstSlew : SlewLimit;
|
|
||||||
mFillingHead_PID : FB41_PIDController;
|
|
||||||
END_VAR
|
|
||||||
|
|
||||||
_LD_BODY
|
|
||||||
_NETWORKS : 4
|
|
||||||
_NETWORK
|
|
||||||
_COMMENT
|
|
||||||
Patrón 1: ACTION call con ???
|
|
||||||
_END_COMMENT
|
|
||||||
_LD_ASSIGN
|
|
||||||
_EMPTY
|
|
||||||
_EXPRESSION
|
|
||||||
_POSITIV
|
|
||||||
|
|
||||||
ENABLELIST : 1
|
|
||||||
_ASSIGN
|
|
||||||
_FUNCTIONBLOCK
|
|
||||||
???
|
|
||||||
_BOX_EXPR : 0
|
|
||||||
_ENABLED
|
|
||||||
_EXPRESSION
|
|
||||||
_POSITIV
|
|
||||||
Test_Pattern_Program.Read_Analog
|
|
||||||
_OUTPUTS : 0
|
|
||||||
_EXPRESSION
|
|
||||||
_POSITIV
|
|
||||||
_OUTPUTS : 1
|
|
||||||
_OUTPUT
|
|
||||||
_POSITIV
|
|
||||||
_NO_SET
|
|
||||||
mDummy
|
|
||||||
ENABLELIST_END
|
|
||||||
_OUTPUTS : 0
|
|
||||||
|
|
||||||
_NETWORK
|
|
||||||
_COMMENT
|
|
||||||
Patrón 2: Function Block directo
|
|
||||||
_END_COMMENT
|
|
||||||
_LD_ASSIGN
|
|
||||||
_EMPTY
|
|
||||||
_EXPRESSION
|
|
||||||
_POSITIV
|
|
||||||
|
|
||||||
ENABLELIST : 1
|
|
||||||
_ASSIGN
|
|
||||||
_FUNCTIONBLOCK
|
|
||||||
mFillerEstSlew
|
|
||||||
_BOX_EXPR : 4
|
|
||||||
_ENABLED
|
|
||||||
_OPERAND
|
|
||||||
_EXPRESSION
|
|
||||||
_POSITIV
|
|
||||||
gInputValue
|
|
||||||
_OPERAND
|
|
||||||
_EXPRESSION
|
|
||||||
_POSITIV
|
|
||||||
gSlewMax
|
|
||||||
_OPERAND
|
|
||||||
_EXPRESSION
|
|
||||||
_POSITIV
|
|
||||||
gCycle
|
|
||||||
_EXPRESSION
|
|
||||||
_POSITIV
|
|
||||||
SlewLimit
|
|
||||||
_OUTPUTS : 1
|
|
||||||
_OUTPUT
|
|
||||||
_POSITIV
|
|
||||||
_NO_SET
|
|
||||||
mDummy
|
|
||||||
ENABLELIST_END
|
|
||||||
_OUTPUTS : 0
|
|
||||||
|
|
||||||
_NETWORK
|
|
||||||
_COMMENT
|
|
||||||
Patrón 3: Otra ACTION call con ???
|
|
||||||
_END_COMMENT
|
|
||||||
_LD_ASSIGN
|
|
||||||
_EMPTY
|
|
||||||
_EXPRESSION
|
|
||||||
_POSITIV
|
|
||||||
|
|
||||||
ENABLELIST : 1
|
|
||||||
_ASSIGN
|
|
||||||
_FUNCTIONBLOCK
|
|
||||||
???
|
|
||||||
_BOX_EXPR : 0
|
|
||||||
_ENABLED
|
|
||||||
_EXPRESSION
|
|
||||||
_POSITIV
|
|
||||||
Test_Pattern_Program.Calculations
|
|
||||||
_OUTPUTS : 0
|
|
||||||
_EXPRESSION
|
|
||||||
_POSITIV
|
|
||||||
_OUTPUTS : 1
|
|
||||||
_OUTPUT
|
|
||||||
_POSITIV
|
|
||||||
_NO_SET
|
|
||||||
mDummy
|
|
||||||
ENABLELIST_END
|
|
||||||
_OUTPUTS : 0
|
|
||||||
|
|
||||||
_NETWORK
|
|
||||||
_COMMENT
|
|
||||||
Patrón 4: Function Block PID directo
|
|
||||||
_END_COMMENT
|
|
||||||
_LD_ASSIGN
|
|
||||||
_EMPTY
|
|
||||||
_EXPRESSION
|
|
||||||
_POSITIV
|
|
||||||
|
|
||||||
ENABLELIST : 1
|
|
||||||
_ASSIGN
|
|
||||||
_FUNCTIONBLOCK
|
|
||||||
mFillingHead_PID
|
|
||||||
_BOX_EXPR : 20
|
|
||||||
_ENABLED
|
|
||||||
_OPERAND
|
|
||||||
_EXPRESSION
|
|
||||||
_POSITIV
|
|
||||||
gSetpoint
|
|
||||||
_OPERAND
|
|
||||||
_EXPRESSION
|
|
||||||
_POSITIV
|
|
||||||
gProcessValue
|
|
||||||
_EXPRESSION
|
|
||||||
_POSITIV
|
|
||||||
FB41_PIDController
|
|
||||||
_OUTPUTS : 1
|
|
||||||
_OUTPUT
|
|
||||||
_POSITIV
|
|
||||||
_NO_SET
|
|
||||||
mPIDOutput
|
|
||||||
ENABLELIST_END
|
|
||||||
_OUTPUTS : 0
|
|
||||||
|
|
||||||
END_PROGRAM
|
|
||||||
|
|
||||||
ACTION Read_Analog:
|
|
||||||
_LD_BODY
|
|
||||||
_NETWORKS : 1
|
|
||||||
_NETWORK
|
|
||||||
_COMMENT
|
|
||||||
ACTION de ejemplo
|
|
||||||
_END_COMMENT
|
|
||||||
_LD_ASSIGN
|
|
||||||
_LD_CONTACT
|
|
||||||
gAnalogEnable
|
|
||||||
_EXPRESSION
|
|
||||||
_POSITIV
|
|
||||||
_EXPRESSION
|
|
||||||
_POSITIV
|
|
||||||
|
|
||||||
ENABLELIST : 1
|
|
||||||
_ASSIGN
|
|
||||||
_FUNCTION
|
|
||||||
ReadAnalogIn
|
|
||||||
_OUTPUTS : 1
|
|
||||||
_OUTPUT
|
|
||||||
_POSITIV
|
|
||||||
_NO_SET
|
|
||||||
gAnalogValue
|
|
||||||
ENABLELIST_END
|
|
||||||
_OUTPUTS : 0
|
|
||||||
END_ACTION
|
|
||||||
|
|
||||||
ACTION Calculations:
|
|
||||||
gCalculatedValue := gInputA + gInputB * 2.5;
|
|
||||||
mDummy := TRUE;
|
|
||||||
END_ACTION
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Escribir archivo de prueba
|
|
||||||
test_file = "test_pattern_example.exp"
|
|
||||||
with open(test_file, 'w', encoding='utf-8') as f:
|
|
||||||
f.write(test_content)
|
|
||||||
|
|
||||||
print(f"✓ Archivo de prueba creado: {test_file}")
|
|
||||||
print("-" * 60)
|
|
||||||
|
|
||||||
# Crear convertidor
|
|
||||||
converter = SimpleLadConverter()
|
|
||||||
|
|
||||||
# Parsear archivo
|
|
||||||
print("🔍 PARSEANDO ARCHIVO...")
|
|
||||||
converter.parse_file(test_file)
|
|
||||||
|
|
||||||
print(f"\n📊 RESUMEN:")
|
|
||||||
print(f" ✓ Programa: {converter.program_name}")
|
|
||||||
print(f" ✓ Redes encontradas: {len(converter.networks)}")
|
|
||||||
print(f" ✓ ACTIONs encontradas: {list(converter.actions.keys())}")
|
|
||||||
|
|
||||||
# Analizar tipos de llamadas encontradas
|
|
||||||
action_calls = []
|
|
||||||
function_blocks = []
|
|
||||||
|
|
||||||
print(f"\n📋 ANÁLISIS DETALLADO DE REDES:")
|
|
||||||
for network in converter.networks:
|
|
||||||
print(f" Red {network['id']}: {network['comment']}")
|
|
||||||
if network['logic']:
|
|
||||||
logic_type = network['logic']['type']
|
|
||||||
logic_name = network['logic'].get('name', 'Sin nombre')
|
|
||||||
|
|
||||||
if logic_type == 'ACTION_CALL':
|
|
||||||
action_calls.append(logic_name)
|
|
||||||
print(f" ✓ PATRÓN ???: ACTION call → {logic_name}")
|
|
||||||
elif logic_type == 'FUNCTION_BLOCK':
|
|
||||||
function_blocks.append(logic_name)
|
|
||||||
print(f" ✓ PATRÓN DIRECTO: Function Block → {logic_name}")
|
|
||||||
else:
|
|
||||||
print(f" ℹ Otro tipo: {logic_type} → {logic_name}")
|
|
||||||
else:
|
|
||||||
print(f" ⚠ Sin lógica detectada")
|
|
||||||
|
|
||||||
print(f"\n🔍 LLAMADAS DETECTADAS:")
|
|
||||||
print(f" 📞 ACTION calls (patrón ???): {len(action_calls)}")
|
|
||||||
for call in action_calls:
|
|
||||||
print(f" • {call}")
|
|
||||||
|
|
||||||
print(f" 🔧 Function Blocks (directos): {len(function_blocks)}")
|
|
||||||
for fb in function_blocks:
|
|
||||||
print(f" • {fb}")
|
|
||||||
|
|
||||||
# Generar código SCL para verificar
|
|
||||||
print(f"\n📝 GENERANDO CÓDIGO SCL...")
|
|
||||||
scl_code = converter.convert_to_structured()
|
|
||||||
|
|
||||||
# Guardar archivo de prueba
|
|
||||||
output_file = "test_pattern_output.scl"
|
|
||||||
with open(output_file, 'w', encoding='utf-8') as f:
|
|
||||||
f.write(scl_code)
|
|
||||||
|
|
||||||
print(f" ✓ Guardado en: {output_file}")
|
|
||||||
|
|
||||||
# Mostrar sección relevante del código generado
|
|
||||||
lines = scl_code.split('\n')
|
|
||||||
print(f"\n📄 CÓDIGO SCL GENERADO (sección principal):")
|
|
||||||
|
|
||||||
# Buscar sección principal
|
|
||||||
main_start = -1
|
|
||||||
main_end = -1
|
|
||||||
for i, line in enumerate(lines):
|
|
||||||
if "CÓDIGO PRINCIPAL" in line:
|
|
||||||
main_start = i
|
|
||||||
elif main_start > -1 and "END_PROGRAM" in line:
|
|
||||||
main_end = i + 1
|
|
||||||
break
|
|
||||||
|
|
||||||
if main_start > -1:
|
|
||||||
section_lines = lines[main_start:main_end] if main_end > -1 else lines[main_start:main_start+20]
|
|
||||||
for i, line in enumerate(section_lines, main_start+1):
|
|
||||||
print(f" {i:2d}: {line}")
|
|
||||||
|
|
||||||
# Limpiar archivos temporales
|
|
||||||
try:
|
|
||||||
os.remove(test_file)
|
|
||||||
print(f"\n🧹 Archivo temporal eliminado: {test_file}")
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
print(f"\n✅ CONCLUSIÓN:")
|
|
||||||
print(f" Tu observación es CORRECTA:")
|
|
||||||
print(f" • _FUNCTIONBLOCK + ??? = ACTION call")
|
|
||||||
print(f" • _FUNCTIONBLOCK + nombre_directo = Function Block")
|
|
||||||
print(f" • El parser ahora detecta ambos patrones correctamente!")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
test_pattern_detection()
|
|
|
@ -1,329 +0,0 @@
|
||||||
(* Código SCL generado desde LAD TwinCAT *)
|
|
||||||
(* Convertidor mejorado con SymPy - Estructura DNF preferida *)
|
|
||||||
(* Path original: \/TASK1_PID\/PID_Controllers\/Filling_Valve_PID *)
|
|
||||||
|
|
||||||
PROGRAM _Filling_Head_PID_Ctrl
|
|
||||||
VAR_OUTPUT
|
|
||||||
EN_Out : BOOL ;
|
|
||||||
END_VAR
|
|
||||||
|
|
||||||
VAR
|
|
||||||
mFillerProdSlew : REAL ;
|
|
||||||
mFillerEstSlew : SlewLimit ;
|
|
||||||
mKp_Loss : REAL ;
|
|
||||||
mR_KP : REAL ;
|
|
||||||
mR_TI : REAL ;
|
|
||||||
mR_TD : REAL ;
|
|
||||||
_Hold_int_PID : BOOL ;
|
|
||||||
_Init_int_PID : BOOL ;
|
|
||||||
mManual_Value : REAL ;
|
|
||||||
mReal_FF_value : REAL ;
|
|
||||||
mReal_Max_FF : REAL ;
|
|
||||||
mLMN_FAC : REAL ;
|
|
||||||
mDeadBand : REAL ;
|
|
||||||
mInit_Int_PID : REAL ;
|
|
||||||
mHr_Hs : REAL ;
|
|
||||||
mFillingHead_PID : FB41_PIDController;
|
|
||||||
mI_Sel_FillHead : BOOL ;
|
|
||||||
mP_Sel_FillHead : BOOL ;
|
|
||||||
mD_Sel_FillHead : BOOL ;
|
|
||||||
mPID_FillHead_OUT : REAL ;
|
|
||||||
mPIDFillHeadProp : REAL ;
|
|
||||||
mPIDFillHeadInt : REAL ;
|
|
||||||
mPIDFillHeadDer : REAL ;
|
|
||||||
mP3_Freq_Flted : LowPassFilter ;
|
|
||||||
mDiffTransducer_Flted : LowPassFilter ;
|
|
||||||
mFillValve1Press_Flted : LowPassFilter ;
|
|
||||||
mFillingHead_KP_PID : FB41_PIDController;
|
|
||||||
mFillHead_PID_En : BOOL ;
|
|
||||||
mI_Sel_FillHead_KP : BOOL ;
|
|
||||||
mP_Sel_FillHead_KP : BOOL ;
|
|
||||||
mD_Sel_FillHead_KP : BOOL ;
|
|
||||||
mPID_FillHead_KP_OUT : REAL ;
|
|
||||||
mPIDFillHead_KP_Prop : REAL ;
|
|
||||||
mPIDFillHead_KP_Int : REAL ;
|
|
||||||
mPIDFillHead_KP_Der : REAL ;
|
|
||||||
_Hold_int_KP_PID : BOOL ;
|
|
||||||
_Init_int_KP_PID : BOOL ;
|
|
||||||
mManual_KP_Value : REAL ;
|
|
||||||
mReal_KP_FF_value : REAL ;
|
|
||||||
mDead_KP_Band : REAL ;
|
|
||||||
mInit_Int_KP_PID : REAL ;
|
|
||||||
mFillingHeadPIDStat : StatisticalAnalisys ;
|
|
||||||
mHeadKP_SlewLimit : SlewLimit ;
|
|
||||||
mHead_KP_Temp : REAL ;
|
|
||||||
mOutWordToVFC : WORD ;
|
|
||||||
mRealTemp : REAL ;
|
|
||||||
mAnalogInTemp : Peripherial ;
|
|
||||||
mReset_Int_ONS : R_TRIG ;
|
|
||||||
mReset_Int : BOOL ;
|
|
||||||
mEn_ProdPressLoss : TON ;
|
|
||||||
mStartFillTON : TON ;
|
|
||||||
mStopFillTP : TP ;
|
|
||||||
mStopFillingN_ONS : F_TRIG ;
|
|
||||||
mFillerFilling : BOOL ;
|
|
||||||
mStopFilling : BOOL;
|
|
||||||
mDummy : BOOL ;
|
|
||||||
mDiffSensFaultEn: TON;
|
|
||||||
END_VAR
|
|
||||||
|
|
||||||
|
|
||||||
(* === CÓDIGO PRINCIPAL === *)
|
|
||||||
|
|
||||||
(* Código LAD convertido *)
|
|
||||||
// Red 2
|
|
||||||
// Llamada a función: _Filling_Head_PID_Ctrl.Read_Analog
|
|
||||||
CALL _Filling_Head_PID_Ctrl.Read_Analog();
|
|
||||||
mDummy := TRUE; // ACTION ejecutada
|
|
||||||
|
|
||||||
// Red 3
|
|
||||||
// Llamada a función: _Filling_Head_PID_Ctrl._KP_PID_Ctrl
|
|
||||||
CALL _Filling_Head_PID_Ctrl._KP_PID_Ctrl();
|
|
||||||
mDummy := TRUE; // ACTION ejecutada
|
|
||||||
|
|
||||||
// Red 4
|
|
||||||
// Llamada a función: _Filling_Head_PID_Ctrl.Calcolous
|
|
||||||
CALL _Filling_Head_PID_Ctrl.Calcolous();
|
|
||||||
mDummy := TRUE; // ACTION ejecutada
|
|
||||||
|
|
||||||
// Red 5
|
|
||||||
// Llamada a función: gProd_Flow
|
|
||||||
mDummy := gProd_Flow();
|
|
||||||
|
|
||||||
// Red 6
|
|
||||||
// Llamada a función: mFillerEstSlew
|
|
||||||
// Sin optimización SymPy
|
|
||||||
IF mFillerEstSlew(_POSITIV) THEN
|
|
||||||
mDummy := TRUE;
|
|
||||||
ELSE
|
|
||||||
mDummy := FALSE;
|
|
||||||
END_IF;
|
|
||||||
|
|
||||||
// Red 7
|
|
||||||
// Llamada a función: mStopFillTP
|
|
||||||
// Sin optimización SymPy
|
|
||||||
IF mStopFillTP() THEN
|
|
||||||
mDummy := TRUE;
|
|
||||||
ELSE
|
|
||||||
mDummy := FALSE;
|
|
||||||
END_IF;
|
|
||||||
|
|
||||||
// Red 1
|
|
||||||
// Sin optimización SymPy
|
|
||||||
IF NOT gAlwaysOff THEN
|
|
||||||
mP_Sel_FillHead := TRUE;
|
|
||||||
ELSE
|
|
||||||
mP_Sel_FillHead := FALSE;
|
|
||||||
END_IF;
|
|
||||||
|
|
||||||
// Red 8
|
|
||||||
// Sin optimización SymPy
|
|
||||||
IF NOT gAlwaysOff THEN
|
|
||||||
mI_Sel_FillHead := TRUE;
|
|
||||||
ELSE
|
|
||||||
mI_Sel_FillHead := FALSE;
|
|
||||||
END_IF;
|
|
||||||
|
|
||||||
// Red 9
|
|
||||||
// Sin optimización SymPy
|
|
||||||
IF NOT gAlwaysOff THEN
|
|
||||||
mD_Sel_FillHead := TRUE;
|
|
||||||
ELSE
|
|
||||||
mD_Sel_FillHead := FALSE;
|
|
||||||
END_IF;
|
|
||||||
|
|
||||||
// Red 10
|
|
||||||
// Sin optimización SymPy
|
|
||||||
IF (gBlenderCIPMode OR gBlenderRinseMode) THEN
|
|
||||||
g_Head_CIP_Rinse := TRUE;
|
|
||||||
ELSE
|
|
||||||
g_Head_CIP_Rinse := FALSE;
|
|
||||||
END_IF;
|
|
||||||
|
|
||||||
// Red 11
|
|
||||||
// Sin optimización SymPy
|
|
||||||
IF ((NOT gH_P3_ProductPump_Auto AND gH_P3_ProductPump_Manual) OR g_Head_Drain OR (gH_EV62_Status AND g_Head_CIP_Rinse) OR gP_PID_Head_Manual) THEN
|
|
||||||
g_MAN_Head := TRUE;
|
|
||||||
ELSE
|
|
||||||
g_MAN_Head := FALSE;
|
|
||||||
END_IF;
|
|
||||||
|
|
||||||
// Red 12
|
|
||||||
// Sin optimización SymPy
|
|
||||||
IF ((((gP_PID_Head_Enable OR (NOT gProdPipeRunOut_Done AND gBlendFillStartUp_Done)) AND gInFillerEV46Enable AND NOT gFlrCO2ValveEV46Pos_Fault AND gInFillerEV62Enable AND NOT gProdValveEV62Pos_Fault AND NOT gDiffSensor_Analog_Fault) OR (g_Head_CIP_Rinse AND gBlenderRun_Latch) OR g_MAN_Head OR gP_PID_Head_Manual) AND gH_Blender_OPT_BlendFillSystem) THEN
|
|
||||||
g_Head_PID_Enable := TRUE;
|
|
||||||
ELSE
|
|
||||||
g_Head_PID_Enable := FALSE;
|
|
||||||
END_IF;
|
|
||||||
|
|
||||||
// Red 14
|
|
||||||
// Llamada a función: gHead_PID_Max_Freq
|
|
||||||
mDummy := gHead_PID_Max_Freq();
|
|
||||||
|
|
||||||
// Red 15
|
|
||||||
// Llamada a función: gH_ProcessSetup_FillerDiameter
|
|
||||||
mDummy := gH_ProcessSetup_FillerDiameter();
|
|
||||||
|
|
||||||
// Red 16
|
|
||||||
// Llamada a función: mReal_FF_value
|
|
||||||
mDummy := mReal_FF_value();
|
|
||||||
|
|
||||||
// Red 17
|
|
||||||
// Llamada a función: mManual_Value
|
|
||||||
mDummy := mManual_Value();
|
|
||||||
|
|
||||||
// Red 18
|
|
||||||
// Llamada a función: _Filling_Head_PID_Ctrl.Write_Analog
|
|
||||||
CALL _Filling_Head_PID_Ctrl.Write_Analog();
|
|
||||||
mDummy := TRUE; // ACTION ejecutada
|
|
||||||
|
|
||||||
// Red 13
|
|
||||||
CALL _Filling_Head_PID_Ctrl.Write_Analog();
|
|
||||||
mDummy := TRUE; // ACTION ejecutada
|
|
||||||
|
|
||||||
END_PROGRAM
|
|
||||||
|
|
||||||
(* === SUBFUNCIONES (ACTIONs convertidas) === *)
|
|
||||||
|
|
||||||
PROCEDURE _Filling_Head_PID_Ctrl__KP_PID_Ctrl
|
|
||||||
(* Convertida desde ACTION *)
|
|
||||||
|
|
||||||
(* Código LAD convertido a SCL *)
|
|
||||||
// Red 1
|
|
||||||
IF NOT gAlwaysOff THEN
|
|
||||||
mI_Sel_FillHead_KP := TRUE;
|
|
||||||
ELSE
|
|
||||||
mI_Sel_FillHead_KP := FALSE;
|
|
||||||
END_IF;
|
|
||||||
|
|
||||||
// Red 2
|
|
||||||
IF NOT gAlwaysOff THEN
|
|
||||||
mP_Sel_FillHead_KP := TRUE;
|
|
||||||
ELSE
|
|
||||||
mP_Sel_FillHead_KP := FALSE;
|
|
||||||
END_IF;
|
|
||||||
|
|
||||||
// Red 3
|
|
||||||
IF NOT gAlwaysOff THEN
|
|
||||||
mD_Sel_FillHead_KP := TRUE;
|
|
||||||
ELSE
|
|
||||||
mD_Sel_FillHead_KP := FALSE;
|
|
||||||
END_IF;
|
|
||||||
|
|
||||||
// Red 4
|
|
||||||
IF mFillHead_PID_En THEN
|
|
||||||
mR_KP := TRUE;
|
|
||||||
ELSE
|
|
||||||
mR_KP := FALSE;
|
|
||||||
END_IF;
|
|
||||||
|
|
||||||
|
|
||||||
END_PROCEDURE
|
|
||||||
|
|
||||||
PROCEDURE _Filling_Head_PID_Ctrl_Calcolous
|
|
||||||
(* Convertida desde ACTION *)
|
|
||||||
|
|
||||||
(* Código ST original *)
|
|
||||||
gHead_PID_Cycle := gPID_Cycle_Time ;
|
|
||||||
mLMN_FAC := 1.0 ;
|
|
||||||
mDeadBand := 0.0 ;
|
|
||||||
|
|
||||||
mKp_Loss := gH_ProcessSetup_KProdLoss ;
|
|
||||||
|
|
||||||
IF gH_ProcessSetup_BPFillingValvePID<>0 THEN
|
|
||||||
(* IF gHeadPIDCtrlOk THEN*)
|
|
||||||
mHead_KP_Temp := 100 / gH_ProcessSetup_BPFillingValvePID ;
|
|
||||||
(* ELSE
|
|
||||||
mHead_KP_Temp := 50 / gH_ProcessSetup_BPFillingValvePID ;
|
|
||||||
END_IF*)
|
|
||||||
END_IF
|
|
||||||
mHeadKP_SlewLimit(i_InValue:=mHead_KP_Temp, i_SlewMax:=0.01, i_Cycle:=gHead_PID_Cycle, out:=mR_KP) ;
|
|
||||||
|
|
||||||
mR_TI := gH_ProcessSetup_TIFillingValvePID ;
|
|
||||||
mR_TD := gH_ProcessSetup_TDFillingValvePID ;
|
|
||||||
|
|
||||||
mManual_Value := 0.0 ;
|
|
||||||
IF NOT gH_P3_ProductPump_Auto AND gH_P3_ProductPump_Manual THEN
|
|
||||||
mManual_Value := gH_P3_ProductPumpFC_Manual ;
|
|
||||||
mLMN_FAC := 1.0 ;
|
|
||||||
ELSIF g_MAN_Head AND NOT g_Head_CIP_Rinse THEN
|
|
||||||
mManual_Value := gHead_PID_Manual_Value ;
|
|
||||||
mLMN_FAC := 1.0 ;
|
|
||||||
ELSIF g_Head_Drain THEN
|
|
||||||
mManual_Value := 0.0 ;
|
|
||||||
mLMN_FAC := 1.0 ;
|
|
||||||
ELSIF g_Head_CIP_Rinse AND gBlenderRinseMode THEN
|
|
||||||
mManual_Value :=gH_ProcessSetup_RinseProdPumpFreq ;
|
|
||||||
mLMN_FAC := 1.0 ;
|
|
||||||
ELSIF g_Head_CIP_Rinse THEN
|
|
||||||
mManual_Value :=gH_ProcessSetup_CIPProdPumpFreq ;
|
|
||||||
mLMN_FAC := 1.0 ;
|
|
||||||
ELSIF g_Head_PID_Enable AND gH_P3_ProductPump_Auto THEN
|
|
||||||
gH_P3_ProductPumpFC_Manual := mmH2O_TO_Freq(mPID_FillHead_OUT,gH_ProcessSetup_KProdPump) ;
|
|
||||||
mManual_Value := 0.0 ;
|
|
||||||
mLMN_FAC := 1.0 ;
|
|
||||||
ELSE
|
|
||||||
mManual_Value := 0.0 ;
|
|
||||||
mLMN_FAC := 0.0 ;
|
|
||||||
END_IF
|
|
||||||
|
|
||||||
END_PROCEDURE
|
|
||||||
|
|
||||||
PROCEDURE _Filling_Head_PID_Ctrl_PID_Monitor
|
|
||||||
(* Convertida desde ACTION *)
|
|
||||||
|
|
||||||
(* Código LAD convertido a SCL *)
|
|
||||||
// Red 2
|
|
||||||
// Llamada a función: mFillingHeadPIDStat
|
|
||||||
IF mFillingHeadPIDStat(_POSITIV) THEN
|
|
||||||
mDummy := TRUE;
|
|
||||||
ELSE
|
|
||||||
mDummy := FALSE;
|
|
||||||
END_IF;
|
|
||||||
|
|
||||||
// Red 1
|
|
||||||
IF gHeadPIDCtrlOk THEN
|
|
||||||
gHeadPIDCtrlOk := TRUE;
|
|
||||||
ELSE
|
|
||||||
gHeadPIDCtrlOk := FALSE;
|
|
||||||
END_IF;
|
|
||||||
|
|
||||||
|
|
||||||
END_PROCEDURE
|
|
||||||
|
|
||||||
PROCEDURE _Filling_Head_PID_Ctrl_Read_Analog
|
|
||||||
(* Convertida desde ACTION *)
|
|
||||||
|
|
||||||
(* Código LAD convertido a SCL *)
|
|
||||||
// Red 1
|
|
||||||
IF NOT gH_Blender_OPT_Simulation THEN
|
|
||||||
gDiffSensor_Analog_Fault := TRUE;
|
|
||||||
ELSE
|
|
||||||
gDiffSensor_Analog_Fault := FALSE;
|
|
||||||
END_IF;
|
|
||||||
|
|
||||||
|
|
||||||
END_PROCEDURE
|
|
||||||
|
|
||||||
PROCEDURE _Filling_Head_PID_Ctrl_Reset_Integral
|
|
||||||
(* Convertida desde ACTION *)
|
|
||||||
|
|
||||||
(* Código ST original *)
|
|
||||||
mInit_Int_PID := 0.0 ;
|
|
||||||
_Init_int_PID := TRUE ;
|
|
||||||
|
|
||||||
END_PROCEDURE
|
|
||||||
|
|
||||||
PROCEDURE _Filling_Head_PID_Ctrl_Write_Analog
|
|
||||||
(* Convertida desde ACTION *)
|
|
||||||
|
|
||||||
(* Código LAD convertido a SCL *)
|
|
||||||
// Red 1
|
|
||||||
IF NOT gH_Blender_OPT_Simulation THEN
|
|
||||||
gProduct_VFC_MainRefValue := TRUE;
|
|
||||||
ELSE
|
|
||||||
gProduct_VFC_MainRefValue := FALSE;
|
|
||||||
END_IF;
|
|
||||||
|
|
||||||
|
|
||||||
END_PROCEDURE
|
|
|
@ -1,76 +0,0 @@
|
||||||
(* Código SCL generado desde LAD TwinCAT *)
|
|
||||||
(* Convertidor mejorado con SymPy - Estructura DNF preferida *)
|
|
||||||
(* Path original: \/TASK2_ControlMain\/CIP *)
|
|
||||||
|
|
||||||
PROGRAM CentralCIP_Ctrl
|
|
||||||
VAR_OUTPUT
|
|
||||||
EN_Out : BOOL ;
|
|
||||||
END_VAR
|
|
||||||
|
|
||||||
VAR
|
|
||||||
mReadCIP_Block : ADSREAD ;
|
|
||||||
mReadCIP_Busy : BOOL ;
|
|
||||||
mReadCIP_Read : BOOL ;
|
|
||||||
mReadCIP_Error : BOOL ;
|
|
||||||
mReadCIP_ErrorCode : UDINT ;
|
|
||||||
mDummy : BOOL ;
|
|
||||||
mCIPCommFault : TON;
|
|
||||||
END_VAR
|
|
||||||
|
|
||||||
|
|
||||||
(* === CÓDIGO PRINCIPAL === *)
|
|
||||||
|
|
||||||
(* Código LAD convertido *)
|
|
||||||
// Red 1
|
|
||||||
|
|
||||||
// Red 2
|
|
||||||
|
|
||||||
// Red 4
|
|
||||||
// Llamada a función: ???
|
|
||||||
// Sin optimización SymPy
|
|
||||||
IF ???() THEN
|
|
||||||
mDummy := TRUE;
|
|
||||||
ELSE
|
|
||||||
mDummy := FALSE;
|
|
||||||
END_IF;
|
|
||||||
|
|
||||||
// Red 3
|
|
||||||
// Sin optimización SymPy
|
|
||||||
IF (gH_Blender_OPT_CIPSignalExchange AND gBlenderCIPMode AND NOT gCIPReceiveData.AliveBit AND mCIPCommFault(_POSITIV)) THEN
|
|
||||||
gCIPCommFault := TRUE;
|
|
||||||
ELSE
|
|
||||||
gCIPCommFault := FALSE;
|
|
||||||
END_IF;
|
|
||||||
|
|
||||||
END_PROGRAM
|
|
||||||
|
|
||||||
(* === SUBFUNCIONES (ACTIONs convertidas) === *)
|
|
||||||
|
|
||||||
PROCEDURE CentralCIP_Ctrl_SignalsInterchange
|
|
||||||
(* Convertida desde ACTION *)
|
|
||||||
|
|
||||||
(* Código LAD convertido a SCL *)
|
|
||||||
// Red 1
|
|
||||||
IF (NOT mReadCIP_Read AND NOT mReadCIP_Busy) THEN
|
|
||||||
mReadCIP_Read := TRUE;
|
|
||||||
ELSE
|
|
||||||
mReadCIP_Read := FALSE;
|
|
||||||
END_IF;
|
|
||||||
|
|
||||||
// Red 3
|
|
||||||
// Llamada a función: mReadCIP_Block
|
|
||||||
IF mReadCIP_Block(_POSITIV) THEN
|
|
||||||
mDummy := TRUE;
|
|
||||||
ELSE
|
|
||||||
mDummy := FALSE;
|
|
||||||
END_IF;
|
|
||||||
|
|
||||||
// Red 2
|
|
||||||
IF mReadCIP_Block(_POSITIV) THEN
|
|
||||||
mReadCIP_Busy := TRUE;
|
|
||||||
ELSE
|
|
||||||
mReadCIP_Busy := FALSE;
|
|
||||||
END_IF;
|
|
||||||
|
|
||||||
|
|
||||||
END_PROCEDURE
|
|
|
@ -1,98 +0,0 @@
|
||||||
(* Código SCL generado desde LAD TwinCAT *)
|
|
||||||
(* Convertidor mejorado con SymPy - Estructura DNF preferida *)
|
|
||||||
(* Path original: /TASK1_PID/PID_Controllers/Test_Program *)
|
|
||||||
|
|
||||||
PROGRAM Test_Pattern_Program
|
|
||||||
VAR
|
|
||||||
mDummy : BOOL;
|
|
||||||
mFillerEstSlew : SlewLimit;
|
|
||||||
mFillingHead_PID : FB41_PIDController;
|
|
||||||
END_VAR
|
|
||||||
|
|
||||||
|
|
||||||
(* === CÓDIGO PRINCIPAL === *)
|
|
||||||
|
|
||||||
(* Código LAD convertido *)
|
|
||||||
// Red 2
|
|
||||||
// Llamada a función: Test_Pattern_Program.Read_Analog
|
|
||||||
CALL Test_Pattern_Program.Read_Analog();
|
|
||||||
mDummy := TRUE; // ACTION ejecutada
|
|
||||||
|
|
||||||
// Red 1
|
|
||||||
// Patrón 1: ACTION call con ???
|
|
||||||
CALL Test_Pattern_Program.Read_Analog();
|
|
||||||
mDummy := TRUE; // ACTION ejecutada
|
|
||||||
|
|
||||||
// Red 4
|
|
||||||
// Llamada a función: mFillerEstSlew
|
|
||||||
// Sin optimización SymPy
|
|
||||||
IF mFillerEstSlew(_POSITIV) THEN
|
|
||||||
mDummy := TRUE;
|
|
||||||
ELSE
|
|
||||||
mDummy := FALSE;
|
|
||||||
END_IF;
|
|
||||||
|
|
||||||
// Red 3
|
|
||||||
// Patrón 2: Function Block directo
|
|
||||||
// Sin optimización SymPy
|
|
||||||
IF mFillerEstSlew(_POSITIV) THEN
|
|
||||||
mDummy := TRUE;
|
|
||||||
ELSE
|
|
||||||
mDummy := FALSE;
|
|
||||||
END_IF;
|
|
||||||
|
|
||||||
// Red 6
|
|
||||||
// Llamada a función: Test_Pattern_Program.Calculations
|
|
||||||
CALL Test_Pattern_Program.Calculations();
|
|
||||||
mDummy := TRUE; // ACTION ejecutada
|
|
||||||
|
|
||||||
// Red 5
|
|
||||||
// Patrón 3: Otra ACTION call con ???
|
|
||||||
CALL Test_Pattern_Program.Calculations();
|
|
||||||
mDummy := TRUE; // ACTION ejecutada
|
|
||||||
|
|
||||||
// Red 8
|
|
||||||
// Llamada a función: mFillingHead_PID
|
|
||||||
// Sin optimización SymPy
|
|
||||||
IF mFillingHead_PID(_POSITIV) THEN
|
|
||||||
mDummy := TRUE;
|
|
||||||
ELSE
|
|
||||||
mDummy := FALSE;
|
|
||||||
END_IF;
|
|
||||||
|
|
||||||
// Red 7
|
|
||||||
// Patrón 4: Function Block PID directo
|
|
||||||
// Sin optimización SymPy
|
|
||||||
IF mFillingHead_PID(_POSITIV) THEN
|
|
||||||
mPIDOutput := TRUE;
|
|
||||||
ELSE
|
|
||||||
mPIDOutput := FALSE;
|
|
||||||
END_IF;
|
|
||||||
|
|
||||||
END_PROGRAM
|
|
||||||
|
|
||||||
(* === SUBFUNCIONES (ACTIONs convertidas) === *)
|
|
||||||
|
|
||||||
PROCEDURE Test_Pattern_Program_Read_Analog
|
|
||||||
(* Convertida desde ACTION *)
|
|
||||||
|
|
||||||
(* Código LAD convertido a SCL *)
|
|
||||||
// Red 1
|
|
||||||
// ACTION de ejemplo
|
|
||||||
IF gAnalogEnable THEN
|
|
||||||
gAnalogValue := TRUE;
|
|
||||||
ELSE
|
|
||||||
gAnalogValue := FALSE;
|
|
||||||
END_IF;
|
|
||||||
|
|
||||||
|
|
||||||
END_PROCEDURE
|
|
||||||
|
|
||||||
PROCEDURE Test_Pattern_Program_Calculations
|
|
||||||
(* Convertida desde ACTION *)
|
|
||||||
|
|
||||||
(* Código ST original *)
|
|
||||||
gCalculatedValue := gInputA + gInputB * 2.5;
|
|
||||||
mDummy := TRUE;
|
|
||||||
|
|
||||||
END_PROCEDURE
|
|
|
@ -1,139 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
|
|
||||||
# Agregar el directorio padre al path
|
|
||||||
sys.path.append('.')
|
|
||||||
|
|
||||||
# Importar el convertidor
|
|
||||||
from x1_lad_converter import SimpleLadConverter
|
|
||||||
|
|
||||||
def test_filling_head_pid():
|
|
||||||
"""Probar específicamente _FILLING_HEAD_PID_CTRL.EXP con parser mejorado"""
|
|
||||||
print("=== TEST: _FILLING_HEAD_PID_CTRL.EXP con parser mejorado ===")
|
|
||||||
print("Verificando detección de patrones ??? para ACTION calls")
|
|
||||||
print("-" * 60)
|
|
||||||
|
|
||||||
# Buscar el archivo
|
|
||||||
possible_paths = [
|
|
||||||
"ExportTwinCat/_FILLING_HEAD_PID_CTRL.EXP",
|
|
||||||
"../ExportTwinCat/_FILLING_HEAD_PID_CTRL.EXP",
|
|
||||||
"../../ExportTwinCat/_FILLING_HEAD_PID_CTRL.EXP",
|
|
||||||
"C:/Trabajo/SIDEL/13 - E5.007560 - Modifica O&U - SAE235/Reporte/ExportTwinCat/_FILLING_HEAD_PID_CTRL.EXP"
|
|
||||||
]
|
|
||||||
|
|
||||||
test_file = None
|
|
||||||
for path in possible_paths:
|
|
||||||
if os.path.exists(path):
|
|
||||||
test_file = path
|
|
||||||
break
|
|
||||||
|
|
||||||
if test_file is None:
|
|
||||||
print(f"❌ Error: No se encontró _FILLING_HEAD_PID_CTRL.EXP")
|
|
||||||
return
|
|
||||||
|
|
||||||
print(f"✓ Archivo encontrado: {test_file}")
|
|
||||||
print("-" * 60)
|
|
||||||
|
|
||||||
# Crear convertidor
|
|
||||||
converter = SimpleLadConverter()
|
|
||||||
|
|
||||||
# Parsear archivo
|
|
||||||
print("🔍 PARSEANDO ARCHIVO CON PARSER MEJORADO...")
|
|
||||||
converter.parse_file(test_file)
|
|
||||||
|
|
||||||
print(f"\n📊 RESUMEN:")
|
|
||||||
print(f" ✓ Programa: {converter.program_name}")
|
|
||||||
print(f" ✓ Redes encontradas: {len(converter.networks)}")
|
|
||||||
print(f" ✓ ACTIONs encontradas: {list(converter.actions.keys())}")
|
|
||||||
|
|
||||||
# Analizar tipos de llamadas encontradas
|
|
||||||
action_calls = []
|
|
||||||
function_blocks = []
|
|
||||||
unresolved_calls = []
|
|
||||||
|
|
||||||
print(f"\n🔍 ANÁLISIS DE REDES:")
|
|
||||||
for i, network in enumerate(converter.networks):
|
|
||||||
if network['logic']:
|
|
||||||
logic_type = network['logic']['type']
|
|
||||||
logic_name = network['logic'].get('name', 'Sin nombre')
|
|
||||||
|
|
||||||
if logic_type == 'ACTION_CALL':
|
|
||||||
action_calls.append(logic_name)
|
|
||||||
if logic_name == '???':
|
|
||||||
unresolved_calls.append(f"Red {network['id']}")
|
|
||||||
print(f" ❌ Red {network['id']}: ACTION call SIN RESOLVER → {logic_name}")
|
|
||||||
else:
|
|
||||||
print(f" ✅ Red {network['id']}: ACTION call RESUELTO → {logic_name}")
|
|
||||||
elif logic_type == 'FUNCTION_BLOCK':
|
|
||||||
function_blocks.append(logic_name)
|
|
||||||
print(f" 🔧 Red {network['id']}: Function Block → {logic_name}")
|
|
||||||
else:
|
|
||||||
print(f" ℹ Red {network['id']}: {logic_type} → {logic_name}")
|
|
||||||
|
|
||||||
print(f"\n📈 ESTADÍSTICAS:")
|
|
||||||
print(f" 📞 ACTION calls encontradas: {len(action_calls)}")
|
|
||||||
print(f" ✅ Resueltas: {len([x for x in action_calls if x != '???'])}")
|
|
||||||
print(f" ❌ Sin resolver: {len([x for x in action_calls if x == '???'])}")
|
|
||||||
print(f" 🔧 Function Blocks: {len(function_blocks)}")
|
|
||||||
|
|
||||||
if unresolved_calls:
|
|
||||||
print(f"\n⚠ REDES CON PROBLEMAS:")
|
|
||||||
for call in unresolved_calls:
|
|
||||||
print(f" • {call}")
|
|
||||||
|
|
||||||
# Generar código SCL para verificar
|
|
||||||
print(f"\n📝 GENERANDO CÓDIGO SCL...")
|
|
||||||
scl_code = converter.convert_to_structured()
|
|
||||||
|
|
||||||
# Guardar archivo de prueba
|
|
||||||
output_file = "test_filling_head_debug.scl"
|
|
||||||
with open(output_file, 'w', encoding='utf-8') as f:
|
|
||||||
f.write(scl_code)
|
|
||||||
|
|
||||||
print(f" ✓ Guardado en: {output_file}")
|
|
||||||
|
|
||||||
# Buscar problemas en el código generado
|
|
||||||
lines = scl_code.split('\n')
|
|
||||||
problem_lines = []
|
|
||||||
for i, line in enumerate(lines, 1):
|
|
||||||
if '???' in line:
|
|
||||||
problem_lines.append(f"Línea {i}: {line.strip()}")
|
|
||||||
|
|
||||||
if problem_lines:
|
|
||||||
print(f"\n⚠ PROBLEMAS EN CÓDIGO SCL GENERADO:")
|
|
||||||
for problem in problem_lines:
|
|
||||||
print(f" • {problem}")
|
|
||||||
else:
|
|
||||||
print(f"\n✅ CÓDIGO SCL SIN PROBLEMAS ??? DETECTADOS")
|
|
||||||
|
|
||||||
# Mostrar sección principal del código generado
|
|
||||||
print(f"\n📄 CÓDIGO PRINCIPAL (primeras 30 líneas relevantes):")
|
|
||||||
main_start = -1
|
|
||||||
for i, line in enumerate(lines):
|
|
||||||
if "CÓDIGO PRINCIPAL" in line:
|
|
||||||
main_start = i
|
|
||||||
break
|
|
||||||
|
|
||||||
if main_start > -1:
|
|
||||||
relevant_lines = []
|
|
||||||
for i in range(main_start, min(main_start + 50, len(lines))):
|
|
||||||
line = lines[i]
|
|
||||||
if ('CALL ' in line or
|
|
||||||
'Red ' in line or
|
|
||||||
'IF ' in line or
|
|
||||||
'mDummy :=' in line):
|
|
||||||
relevant_lines.append(f" {i+1:3d}: {line}")
|
|
||||||
|
|
||||||
for line in relevant_lines[:30]:
|
|
||||||
print(line)
|
|
||||||
|
|
||||||
if len(relevant_lines) > 30:
|
|
||||||
print(f" ... ({len(relevant_lines) - 30} líneas más)")
|
|
||||||
|
|
||||||
return scl_code
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
test_filling_head_pid()
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -15,5 +15,5 @@
|
||||||
"xref_source_subdir": "source"
|
"xref_source_subdir": "source"
|
||||||
},
|
},
|
||||||
"level3": {},
|
"level3": {},
|
||||||
"working_directory": "C:\\Trabajo\\SIDEL\\13 - E5.007560 - Modifica O&U - SAE235\\Reporte\\ExportTia"
|
"working_directory": "D:\\Trabajo\\VM\\44 - 98050 - Fiera\\Reporte\\ExportsTia\\Source"
|
||||||
}
|
}
|
|
@ -1,9 +1,9 @@
|
||||||
{
|
{
|
||||||
"path": "C:\\Trabajo\\SIDEL\\13 - E5.007560 - Modifica O&U - SAE235\\Reporte\\ExportTia",
|
"path": "D:\\Trabajo\\VM\\44 - 98050 - Fiera\\Reporte\\ExportsTia\\Source",
|
||||||
"history": [
|
"history": [
|
||||||
|
"D:\\Trabajo\\VM\\44 - 98050 - Fiera\\Reporte\\ExportsTia\\Source",
|
||||||
"C:\\Trabajo\\SIDEL\\13 - E5.007560 - Modifica O&U - SAE235\\Reporte\\ExportTia",
|
"C:\\Trabajo\\SIDEL\\13 - E5.007560 - Modifica O&U - SAE235\\Reporte\\ExportTia",
|
||||||
"D:\\Trabajo\\VM\\22 - 93841 - Sidel - Tilting\\Reporte\\TiaExports",
|
"D:\\Trabajo\\VM\\22 - 93841 - Sidel - Tilting\\Reporte\\TiaExports",
|
||||||
"D:\\Trabajo\\VM\\44 - 98050 - Fiera\\Reporte\\ExportsTia\\Source",
|
|
||||||
"C:\\Trabajo\\SIDEL\\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\\Reporte\\SourceDoc\\SourceXML",
|
"C:\\Trabajo\\SIDEL\\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\\Reporte\\SourceDoc\\SourceXML",
|
||||||
"C:\\Trabajo\\SIDEL\\06 - E5.007363 - Modifica O&U - SAE196 (cip integrato)\\Reporte\\IOExport"
|
"C:\\Trabajo\\SIDEL\\06 - E5.007363 - Modifica O&U - SAE196 (cip integrato)\\Reporte\\IOExport"
|
||||||
]
|
]
|
||||||
|
|
17675
data/log.txt
17675
data/log.txt
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue