From ee112f5e77ae6b38d6c729d3f3350613a7998453 Mon Sep 17 00:00:00 2001 From: Miguel Date: Sun, 21 Apr 2024 19:55:11 +0200 Subject: [PATCH] Buscando el problema de los Offsets Fuera de Orden --- .gitignore | 160 +++++++++++ CopyPaste.py | 44 ++- DB_Structure.csv | 354 +++++++++++++------------ DB_Structure.xlsx | Bin 10125 -> 11235 bytes DB_Structure.xml | 251 +++++++++++++++--- ExpandDB.py | 78 ++++-- ExportData.py | 29 +- __pycache__/ExpandDB.cpython-310.pyc | Bin 2846 -> 3509 bytes __pycache__/ExportData.cpython-310.pyc | Bin 2244 -> 2393 bytes 9 files changed, 659 insertions(+), 257 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..68bc17f --- /dev/null +++ b/.gitignore @@ -0,0 +1,160 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# 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 + +# 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 + +# 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/#use-with-ide +.pdm.toml + +# 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 +.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/ diff --git a/CopyPaste.py b/CopyPaste.py index 9265593..2f8a553 100644 --- a/CopyPaste.py +++ b/CopyPaste.py @@ -1,28 +1,24 @@ -def calculate_offsets(db_struct, current_offset=0): +def handle_array_types(db_struct): """ - Recursively calculate byte offsets for each field in the DB structure, - applying general alignment rules except inside arrays. + Handle array types once all UDTs are expanded. + This function modifies the structure in place. """ if isinstance(db_struct, dict): - for key, value in db_struct.items(): - if isinstance(value, dict) and 'type' in value: - is_array_element = value.get('is_array_element', False) - type_name = value['type'] - size = type_sizes.get(type_name, 1) - - if 'String' in type_name: - match = re.match(r'String\[(\d+)\]', type_name) - if match: - size = int(match.group(1)) + 2 # String length + 2 for the null terminator and length prefix - - if not is_array_element and current_offset % 2 != 0: - current_offset += 1 # Align to the next even offset if it's not an array element - - value['offset'] = current_offset - current_offset += size - - # Recursively handle nested structures + for key, value in list(db_struct.items()): if isinstance(value, dict): - current_offset = calculate_offsets(value, current_offset) - - return current_offset + handle_array_types(value) + elif isinstance(value, str): + # Parsing array definitions, e.g., "Array[1..3] of Real" + match = re.match(r"Array\[(\d+)\.\.(\d+)\] of (\w+)", value) + if match: + lower_bound, upper_bound, base_type = ( + int(match.group(1)), + int(match.group(2)), + match.group(3), + ) + # Expand this field into multiple fields + db_struct.pop(key) # Remove the original field + for i in range(lower_bound, upper_bound + 1): + db_struct[f"{key}_{i}"] = {"type": base_type, 'is_array_element': True} + print( + f"Expanded field '{key}' into array fields: {key}_{lower_bound} to {key}_{upper_bound} of type {base_type} \ No newline at end of file diff --git a/DB_Structure.csv b/DB_Structure.csv index dd2f1e0..36ae6fd 100644 --- a/DB_Structure.csv +++ b/DB_Structure.csv @@ -1,176 +1,178 @@ -Nombre,Tipo,Offset,Comentario -MAIN,"""UDT SIPA SV Main""",0, -MAIN.N1,DInt,0,.DB_IOT.USERLEVEL -MAIN.N2,String[81],4,.DB_IOT.USERNAME -MAIN.N3,String[81],88,.DB_IOT.NOME_RICETTA -MAIN.N4,Int,172,.DB_IOT.NEXT_MAINT_CYCLES -MAIN.N5.V1,String[254],174, -MAIN.N5.V2,String[254],430, -MAIN.N5.V3,String[254],686, -MAIN.N5.V4,String[254],942, -MAIN.N5.V5,String[8],1198, -MAIN.N6.type_1,Real,1208,N/A -MAIN.N6.type_2,Real,1212,N/A -MAIN.N6.type_3,Real,1216,N/A -MAIN.N7.type_1,Real,1220,N/A -MAIN.N7.type_2,Real,1224,N/A -MAIN.N7.type_3,Real,1228,N/A -MAIN.N8,Real,1232,.DB_IOT.ELECTRIC_POWER_D -MAIN.N9,Real,1236,.DB_IOT.ELECTRIC_POWER_FACTOR_D -MAIN.N10,Real,1240,.DB_IOT.ELECTRIC_POWER_HOUR_D -MAIN.N11,Real,1244,.DB_IOT.ELECTRIC_POWER_WH -SECT1,"""UDT SIPA SV Section""",1248, -SECT1.N1,DInt,1664,.DB_IOT.STATO_MACCHINA -SECT1.N2,DInt,1668,.DB_IOT.ALLARME_FERMO -SECT1.N3,DInt,1672,.DB_IOT.WARNING_ATTIVO (che compromette produzione) -SECT1.N4,Int,1676,.DB_IOT.STATO_OPERATIVO (Semaforo) -SECT1.N5,Int,1678,".DB_IOT.MODO_OPERATIVO (Prod,Simula,Man, ecc)" -SECT1.N6,DInt,1680,.DB_IOT.ALARM_STOP_NO -SECT1.N7.V1,DInt,1684,PIECES_TOT -SECT1.N7.V2,DInt,1688,PIECES_OK -SECT1.N7.V3,DInt,1692,PIECES_KO_1 -SECT1.N7.V4,DInt,1696,PIECES_KO_2 -SECT1.N7.V5,DInt,1700,PIECES_KO_3 -SECT1.N7.V6,DInt,1704,PIECES_KO_4 -SECT1.N7.V7,DInt,1708,PIECES_KO_5 -SECT1.N7.V8,DInt,1712,PIECES_KO_6 -SECT1.N7.V9,DInt,1716,PIECES_KO_7 -SECT1.N7.V10,DInt,1720,PIECES_KO_8 -SECT1.N7.V11,DInt,1724,PIECES_KO_9 -SECT1.N7.V12,DInt,1728,PIECES_KO_10 -SECT1.N7.V13,DInt,1732,T_ALARM_HOURS -SECT1.N7.V14,DInt,1736,T_DRY_CYCLE_HOURS -SECT1.N7.V15,DInt,1740,T_POWERED_HOURS -SECT1.N7.V16,DInt,1744,T_PRODUCT_100_HOURS -SECT1.N7.V17,DInt,1748,T_PRODUCT_0_HOURS -SECT1.N7.V18,DInt,1752,T_STOP_HOURS -SECT1.N7.V19,Int,1756,T_ALARM_MINUTES -SECT1.N7.V20,Int,1758,T_DRY_CYCLE_MINUTES -SECT1.N7.V21,Int,1760,T_POWERED_MINUTES -SECT1.N7.V22,Int,1762,T_PRODUCT_100_MINUTES -SECT1.N7.V23,Int,1764,T_PRODUCT_0_MINUTES -SECT1.N7.V24,Int,1766,T_STOP_MINUTES -SECT2,"""UDT SIPA SV Section""",1352, -SECT2.N1,DInt,1664,.DB_IOT.STATO_MACCHINA -SECT2.N2,DInt,1668,.DB_IOT.ALLARME_FERMO -SECT2.N3,DInt,1672,.DB_IOT.WARNING_ATTIVO (che compromette produzione) -SECT2.N4,Int,1676,.DB_IOT.STATO_OPERATIVO (Semaforo) -SECT2.N5,Int,1678,".DB_IOT.MODO_OPERATIVO (Prod,Simula,Man, ecc)" -SECT2.N6,DInt,1680,.DB_IOT.ALARM_STOP_NO -SECT2.N7.V1,DInt,1684,PIECES_TOT -SECT2.N7.V2,DInt,1688,PIECES_OK -SECT2.N7.V3,DInt,1692,PIECES_KO_1 -SECT2.N7.V4,DInt,1696,PIECES_KO_2 -SECT2.N7.V5,DInt,1700,PIECES_KO_3 -SECT2.N7.V6,DInt,1704,PIECES_KO_4 -SECT2.N7.V7,DInt,1708,PIECES_KO_5 -SECT2.N7.V8,DInt,1712,PIECES_KO_6 -SECT2.N7.V9,DInt,1716,PIECES_KO_7 -SECT2.N7.V10,DInt,1720,PIECES_KO_8 -SECT2.N7.V11,DInt,1724,PIECES_KO_9 -SECT2.N7.V12,DInt,1728,PIECES_KO_10 -SECT2.N7.V13,DInt,1732,T_ALARM_HOURS -SECT2.N7.V14,DInt,1736,T_DRY_CYCLE_HOURS -SECT2.N7.V15,DInt,1740,T_POWERED_HOURS -SECT2.N7.V16,DInt,1744,T_PRODUCT_100_HOURS -SECT2.N7.V17,DInt,1748,T_PRODUCT_0_HOURS -SECT2.N7.V18,DInt,1752,T_STOP_HOURS -SECT2.N7.V19,Int,1756,T_ALARM_MINUTES -SECT2.N7.V20,Int,1758,T_DRY_CYCLE_MINUTES -SECT2.N7.V21,Int,1760,T_POWERED_MINUTES -SECT2.N7.V22,Int,1762,T_PRODUCT_100_MINUTES -SECT2.N7.V23,Int,1764,T_PRODUCT_0_MINUTES -SECT2.N7.V24,Int,1766,T_STOP_MINUTES -SECT3,"""UDT SIPA SV Section""",1456, -SECT3.N1,DInt,1664,.DB_IOT.STATO_MACCHINA -SECT3.N2,DInt,1668,.DB_IOT.ALLARME_FERMO -SECT3.N3,DInt,1672,.DB_IOT.WARNING_ATTIVO (che compromette produzione) -SECT3.N4,Int,1676,.DB_IOT.STATO_OPERATIVO (Semaforo) -SECT3.N5,Int,1678,".DB_IOT.MODO_OPERATIVO (Prod,Simula,Man, ecc)" -SECT3.N6,DInt,1680,.DB_IOT.ALARM_STOP_NO -SECT3.N7.V1,DInt,1684,PIECES_TOT -SECT3.N7.V2,DInt,1688,PIECES_OK -SECT3.N7.V3,DInt,1692,PIECES_KO_1 -SECT3.N7.V4,DInt,1696,PIECES_KO_2 -SECT3.N7.V5,DInt,1700,PIECES_KO_3 -SECT3.N7.V6,DInt,1704,PIECES_KO_4 -SECT3.N7.V7,DInt,1708,PIECES_KO_5 -SECT3.N7.V8,DInt,1712,PIECES_KO_6 -SECT3.N7.V9,DInt,1716,PIECES_KO_7 -SECT3.N7.V10,DInt,1720,PIECES_KO_8 -SECT3.N7.V11,DInt,1724,PIECES_KO_9 -SECT3.N7.V12,DInt,1728,PIECES_KO_10 -SECT3.N7.V13,DInt,1732,T_ALARM_HOURS -SECT3.N7.V14,DInt,1736,T_DRY_CYCLE_HOURS -SECT3.N7.V15,DInt,1740,T_POWERED_HOURS -SECT3.N7.V16,DInt,1744,T_PRODUCT_100_HOURS -SECT3.N7.V17,DInt,1748,T_PRODUCT_0_HOURS -SECT3.N7.V18,DInt,1752,T_STOP_HOURS -SECT3.N7.V19,Int,1756,T_ALARM_MINUTES -SECT3.N7.V20,Int,1758,T_DRY_CYCLE_MINUTES -SECT3.N7.V21,Int,1760,T_POWERED_MINUTES -SECT3.N7.V22,Int,1762,T_PRODUCT_100_MINUTES -SECT3.N7.V23,Int,1764,T_PRODUCT_0_MINUTES -SECT3.N7.V24,Int,1766,T_STOP_MINUTES -SECT4,"""UDT SIPA SV Section""",1560, -SECT4.N1,DInt,1664,.DB_IOT.STATO_MACCHINA -SECT4.N2,DInt,1668,.DB_IOT.ALLARME_FERMO -SECT4.N3,DInt,1672,.DB_IOT.WARNING_ATTIVO (che compromette produzione) -SECT4.N4,Int,1676,.DB_IOT.STATO_OPERATIVO (Semaforo) -SECT4.N5,Int,1678,".DB_IOT.MODO_OPERATIVO (Prod,Simula,Man, ecc)" -SECT4.N6,DInt,1680,.DB_IOT.ALARM_STOP_NO -SECT4.N7.V1,DInt,1684,PIECES_TOT -SECT4.N7.V2,DInt,1688,PIECES_OK -SECT4.N7.V3,DInt,1692,PIECES_KO_1 -SECT4.N7.V4,DInt,1696,PIECES_KO_2 -SECT4.N7.V5,DInt,1700,PIECES_KO_3 -SECT4.N7.V6,DInt,1704,PIECES_KO_4 -SECT4.N7.V7,DInt,1708,PIECES_KO_5 -SECT4.N7.V8,DInt,1712,PIECES_KO_6 -SECT4.N7.V9,DInt,1716,PIECES_KO_7 -SECT4.N7.V10,DInt,1720,PIECES_KO_8 -SECT4.N7.V11,DInt,1724,PIECES_KO_9 -SECT4.N7.V12,DInt,1728,PIECES_KO_10 -SECT4.N7.V13,DInt,1732,T_ALARM_HOURS -SECT4.N7.V14,DInt,1736,T_DRY_CYCLE_HOURS -SECT4.N7.V15,DInt,1740,T_POWERED_HOURS -SECT4.N7.V16,DInt,1744,T_PRODUCT_100_HOURS -SECT4.N7.V17,DInt,1748,T_PRODUCT_0_HOURS -SECT4.N7.V18,DInt,1752,T_STOP_HOURS -SECT4.N7.V19,Int,1756,T_ALARM_MINUTES -SECT4.N7.V20,Int,1758,T_DRY_CYCLE_MINUTES -SECT4.N7.V21,Int,1760,T_POWERED_MINUTES -SECT4.N7.V22,Int,1762,T_PRODUCT_100_MINUTES -SECT4.N7.V23,Int,1764,T_PRODUCT_0_MINUTES -SECT4.N7.V24,Int,1766,T_STOP_MINUTES -SECT5,"""UDT SIPA SV Section""",1664, -SECT5.N1,DInt,1664,.DB_IOT.STATO_MACCHINA -SECT5.N2,DInt,1668,.DB_IOT.ALLARME_FERMO -SECT5.N3,DInt,1672,.DB_IOT.WARNING_ATTIVO (che compromette produzione) -SECT5.N4,Int,1676,.DB_IOT.STATO_OPERATIVO (Semaforo) -SECT5.N5,Int,1678,".DB_IOT.MODO_OPERATIVO (Prod,Simula,Man, ecc)" -SECT5.N6,DInt,1680,.DB_IOT.ALARM_STOP_NO -SECT5.N7.V1,DInt,1684,PIECES_TOT -SECT5.N7.V2,DInt,1688,PIECES_OK -SECT5.N7.V3,DInt,1692,PIECES_KO_1 -SECT5.N7.V4,DInt,1696,PIECES_KO_2 -SECT5.N7.V5,DInt,1700,PIECES_KO_3 -SECT5.N7.V6,DInt,1704,PIECES_KO_4 -SECT5.N7.V7,DInt,1708,PIECES_KO_5 -SECT5.N7.V8,DInt,1712,PIECES_KO_6 -SECT5.N7.V9,DInt,1716,PIECES_KO_7 -SECT5.N7.V10,DInt,1720,PIECES_KO_8 -SECT5.N7.V11,DInt,1724,PIECES_KO_9 -SECT5.N7.V12,DInt,1728,PIECES_KO_10 -SECT5.N7.V13,DInt,1732,T_ALARM_HOURS -SECT5.N7.V14,DInt,1736,T_DRY_CYCLE_HOURS -SECT5.N7.V15,DInt,1740,T_POWERED_HOURS -SECT5.N7.V16,DInt,1744,T_PRODUCT_100_HOURS -SECT5.N7.V17,DInt,1748,T_PRODUCT_0_HOURS -SECT5.N7.V18,DInt,1752,T_STOP_HOURS -SECT5.N7.V19,Int,1756,T_ALARM_MINUTES -SECT5.N7.V20,Int,1758,T_DRY_CYCLE_MINUTES -SECT5.N7.V21,Int,1760,T_POWERED_MINUTES -SECT5.N7.V22,Int,1762,T_PRODUCT_100_MINUTES -SECT5.N7.V23,Int,1764,T_PRODUCT_0_MINUTES -SECT5.N7.V24,Int,1766,T_STOP_MINUTES +Nombre,Tipo,Offset,Dirección PLC,Comentario +MAIN,"""UDT SIPA SV Main""",0,DBX0.0, +MAIN.N1,DInt,0,DBD0,.DB_IOT.USERLEVEL +MAIN.N2,String[81],4,DBX4.0,.DB_IOT.USERNAME +MAIN.N3,String[81],88,DBX88.0,.DB_IOT.NOME_RICETTA +MAIN.N4,Int,172,DBW172,.DB_IOT.NEXT_MAINT_CYCLES +MAIN.N5.V1,String[254],174,DBX174.0, +MAIN.N5.V2,String[254],430,DBX430.0, +MAIN.N5.V3,String[254],686,DBX686.0, +MAIN.N5.V4,String[254],942,DBX942.0, +MAIN.N5.V5,String[8],1198,DBX1198.0, +MAIN.N6,Array[1..3] of Real,1208,DBX1208.0,.DB_IOT.ELECTRIC_VOLTAGE_PHASE_D +MAIN.N6[1],Real,1208,DBD1208,.DB_IOT.ELECTRIC_VOLTAGE_PHASE_D +MAIN.N6[2],Real,1212,DBD1212,.DB_IOT.ELECTRIC_VOLTAGE_PHASE_D +MAIN.N6[3],Real,1216,DBD1216,.DB_IOT.ELECTRIC_VOLTAGE_PHASE_D +MAIN.N7,Array[1..3] of Real,1220,DBX1220.0,.DB_IOT.ELECTRIC_CURRENT_PHASE_D +MAIN.N7[1],Real,1220,DBD1220,.DB_IOT.ELECTRIC_CURRENT_PHASE_D +MAIN.N7[2],Real,1224,DBD1224,.DB_IOT.ELECTRIC_CURRENT_PHASE_D +MAIN.N7[3],Real,1228,DBD1228,.DB_IOT.ELECTRIC_CURRENT_PHASE_D +MAIN.N8,Real,1232,DBD1232,.DB_IOT.ELECTRIC_POWER_D +MAIN.N9,Real,1236,DBD1236,.DB_IOT.ELECTRIC_POWER_FACTOR_D +MAIN.N10,Real,1240,DBD1240,.DB_IOT.ELECTRIC_POWER_HOUR_D +MAIN.N11,Real,1244,DBD1244,.DB_IOT.ELECTRIC_POWER_WH +SECT1,"""UDT SIPA SV Section""",1248,DBX1248.0, +SECT1.N1,DInt,1664,DBD1664,.DB_IOT.STATO_MACCHINA +SECT1.N2,DInt,1668,DBD1668,.DB_IOT.ALLARME_FERMO +SECT1.N3,DInt,1672,DBD1672,.DB_IOT.WARNING_ATTIVO (che compromette produzione) +SECT1.N4,Int,1676,DBW1676,.DB_IOT.STATO_OPERATIVO (Semaforo) +SECT1.N5,Int,1678,DBW1678,".DB_IOT.MODO_OPERATIVO (Prod,Simula,Man, ecc)" +SECT1.N6,DInt,1680,DBD1680,.DB_IOT.ALARM_STOP_NO +SECT1.N7.V1,DInt,1684,DBD1684,PIECES_TOT +SECT1.N7.V2,DInt,1688,DBD1688,PIECES_OK +SECT1.N7.V3,DInt,1692,DBD1692,PIECES_KO_1 +SECT1.N7.V4,DInt,1696,DBD1696,PIECES_KO_2 +SECT1.N7.V5,DInt,1700,DBD1700,PIECES_KO_3 +SECT1.N7.V6,DInt,1704,DBD1704,PIECES_KO_4 +SECT1.N7.V7,DInt,1708,DBD1708,PIECES_KO_5 +SECT1.N7.V8,DInt,1712,DBD1712,PIECES_KO_6 +SECT1.N7.V9,DInt,1716,DBD1716,PIECES_KO_7 +SECT1.N7.V10,DInt,1720,DBD1720,PIECES_KO_8 +SECT1.N7.V11,DInt,1724,DBD1724,PIECES_KO_9 +SECT1.N7.V12,DInt,1728,DBD1728,PIECES_KO_10 +SECT1.N7.V13,DInt,1732,DBD1732,T_ALARM_HOURS +SECT1.N7.V14,DInt,1736,DBD1736,T_DRY_CYCLE_HOURS +SECT1.N7.V15,DInt,1740,DBD1740,T_POWERED_HOURS +SECT1.N7.V16,DInt,1744,DBD1744,T_PRODUCT_100_HOURS +SECT1.N7.V17,DInt,1748,DBD1748,T_PRODUCT_0_HOURS +SECT1.N7.V18,DInt,1752,DBD1752,T_STOP_HOURS +SECT1.N7.V19,Int,1756,DBW1756,T_ALARM_MINUTES +SECT1.N7.V20,Int,1758,DBW1758,T_DRY_CYCLE_MINUTES +SECT1.N7.V21,Int,1760,DBW1760,T_POWERED_MINUTES +SECT1.N7.V22,Int,1762,DBW1762,T_PRODUCT_100_MINUTES +SECT1.N7.V23,Int,1764,DBW1764,T_PRODUCT_0_MINUTES +SECT1.N7.V24,Int,1766,DBW1766,T_STOP_MINUTES +SECT2,"""UDT SIPA SV Section""",1352,DBX1352.0, +SECT2.N1,DInt,1664,DBD1664,.DB_IOT.STATO_MACCHINA +SECT2.N2,DInt,1668,DBD1668,.DB_IOT.ALLARME_FERMO +SECT2.N3,DInt,1672,DBD1672,.DB_IOT.WARNING_ATTIVO (che compromette produzione) +SECT2.N4,Int,1676,DBW1676,.DB_IOT.STATO_OPERATIVO (Semaforo) +SECT2.N5,Int,1678,DBW1678,".DB_IOT.MODO_OPERATIVO (Prod,Simula,Man, ecc)" +SECT2.N6,DInt,1680,DBD1680,.DB_IOT.ALARM_STOP_NO +SECT2.N7.V1,DInt,1684,DBD1684,PIECES_TOT +SECT2.N7.V2,DInt,1688,DBD1688,PIECES_OK +SECT2.N7.V3,DInt,1692,DBD1692,PIECES_KO_1 +SECT2.N7.V4,DInt,1696,DBD1696,PIECES_KO_2 +SECT2.N7.V5,DInt,1700,DBD1700,PIECES_KO_3 +SECT2.N7.V6,DInt,1704,DBD1704,PIECES_KO_4 +SECT2.N7.V7,DInt,1708,DBD1708,PIECES_KO_5 +SECT2.N7.V8,DInt,1712,DBD1712,PIECES_KO_6 +SECT2.N7.V9,DInt,1716,DBD1716,PIECES_KO_7 +SECT2.N7.V10,DInt,1720,DBD1720,PIECES_KO_8 +SECT2.N7.V11,DInt,1724,DBD1724,PIECES_KO_9 +SECT2.N7.V12,DInt,1728,DBD1728,PIECES_KO_10 +SECT2.N7.V13,DInt,1732,DBD1732,T_ALARM_HOURS +SECT2.N7.V14,DInt,1736,DBD1736,T_DRY_CYCLE_HOURS +SECT2.N7.V15,DInt,1740,DBD1740,T_POWERED_HOURS +SECT2.N7.V16,DInt,1744,DBD1744,T_PRODUCT_100_HOURS +SECT2.N7.V17,DInt,1748,DBD1748,T_PRODUCT_0_HOURS +SECT2.N7.V18,DInt,1752,DBD1752,T_STOP_HOURS +SECT2.N7.V19,Int,1756,DBW1756,T_ALARM_MINUTES +SECT2.N7.V20,Int,1758,DBW1758,T_DRY_CYCLE_MINUTES +SECT2.N7.V21,Int,1760,DBW1760,T_POWERED_MINUTES +SECT2.N7.V22,Int,1762,DBW1762,T_PRODUCT_100_MINUTES +SECT2.N7.V23,Int,1764,DBW1764,T_PRODUCT_0_MINUTES +SECT2.N7.V24,Int,1766,DBW1766,T_STOP_MINUTES +SECT3,"""UDT SIPA SV Section""",1456,DBX1456.0, +SECT3.N1,DInt,1664,DBD1664,.DB_IOT.STATO_MACCHINA +SECT3.N2,DInt,1668,DBD1668,.DB_IOT.ALLARME_FERMO +SECT3.N3,DInt,1672,DBD1672,.DB_IOT.WARNING_ATTIVO (che compromette produzione) +SECT3.N4,Int,1676,DBW1676,.DB_IOT.STATO_OPERATIVO (Semaforo) +SECT3.N5,Int,1678,DBW1678,".DB_IOT.MODO_OPERATIVO (Prod,Simula,Man, ecc)" +SECT3.N6,DInt,1680,DBD1680,.DB_IOT.ALARM_STOP_NO +SECT3.N7.V1,DInt,1684,DBD1684,PIECES_TOT +SECT3.N7.V2,DInt,1688,DBD1688,PIECES_OK +SECT3.N7.V3,DInt,1692,DBD1692,PIECES_KO_1 +SECT3.N7.V4,DInt,1696,DBD1696,PIECES_KO_2 +SECT3.N7.V5,DInt,1700,DBD1700,PIECES_KO_3 +SECT3.N7.V6,DInt,1704,DBD1704,PIECES_KO_4 +SECT3.N7.V7,DInt,1708,DBD1708,PIECES_KO_5 +SECT3.N7.V8,DInt,1712,DBD1712,PIECES_KO_6 +SECT3.N7.V9,DInt,1716,DBD1716,PIECES_KO_7 +SECT3.N7.V10,DInt,1720,DBD1720,PIECES_KO_8 +SECT3.N7.V11,DInt,1724,DBD1724,PIECES_KO_9 +SECT3.N7.V12,DInt,1728,DBD1728,PIECES_KO_10 +SECT3.N7.V13,DInt,1732,DBD1732,T_ALARM_HOURS +SECT3.N7.V14,DInt,1736,DBD1736,T_DRY_CYCLE_HOURS +SECT3.N7.V15,DInt,1740,DBD1740,T_POWERED_HOURS +SECT3.N7.V16,DInt,1744,DBD1744,T_PRODUCT_100_HOURS +SECT3.N7.V17,DInt,1748,DBD1748,T_PRODUCT_0_HOURS +SECT3.N7.V18,DInt,1752,DBD1752,T_STOP_HOURS +SECT3.N7.V19,Int,1756,DBW1756,T_ALARM_MINUTES +SECT3.N7.V20,Int,1758,DBW1758,T_DRY_CYCLE_MINUTES +SECT3.N7.V21,Int,1760,DBW1760,T_POWERED_MINUTES +SECT3.N7.V22,Int,1762,DBW1762,T_PRODUCT_100_MINUTES +SECT3.N7.V23,Int,1764,DBW1764,T_PRODUCT_0_MINUTES +SECT3.N7.V24,Int,1766,DBW1766,T_STOP_MINUTES +SECT4,"""UDT SIPA SV Section""",1560,DBX1560.0, +SECT4.N1,DInt,1664,DBD1664,.DB_IOT.STATO_MACCHINA +SECT4.N2,DInt,1668,DBD1668,.DB_IOT.ALLARME_FERMO +SECT4.N3,DInt,1672,DBD1672,.DB_IOT.WARNING_ATTIVO (che compromette produzione) +SECT4.N4,Int,1676,DBW1676,.DB_IOT.STATO_OPERATIVO (Semaforo) +SECT4.N5,Int,1678,DBW1678,".DB_IOT.MODO_OPERATIVO (Prod,Simula,Man, ecc)" +SECT4.N6,DInt,1680,DBD1680,.DB_IOT.ALARM_STOP_NO +SECT4.N7.V1,DInt,1684,DBD1684,PIECES_TOT +SECT4.N7.V2,DInt,1688,DBD1688,PIECES_OK +SECT4.N7.V3,DInt,1692,DBD1692,PIECES_KO_1 +SECT4.N7.V4,DInt,1696,DBD1696,PIECES_KO_2 +SECT4.N7.V5,DInt,1700,DBD1700,PIECES_KO_3 +SECT4.N7.V6,DInt,1704,DBD1704,PIECES_KO_4 +SECT4.N7.V7,DInt,1708,DBD1708,PIECES_KO_5 +SECT4.N7.V8,DInt,1712,DBD1712,PIECES_KO_6 +SECT4.N7.V9,DInt,1716,DBD1716,PIECES_KO_7 +SECT4.N7.V10,DInt,1720,DBD1720,PIECES_KO_8 +SECT4.N7.V11,DInt,1724,DBD1724,PIECES_KO_9 +SECT4.N7.V12,DInt,1728,DBD1728,PIECES_KO_10 +SECT4.N7.V13,DInt,1732,DBD1732,T_ALARM_HOURS +SECT4.N7.V14,DInt,1736,DBD1736,T_DRY_CYCLE_HOURS +SECT4.N7.V15,DInt,1740,DBD1740,T_POWERED_HOURS +SECT4.N7.V16,DInt,1744,DBD1744,T_PRODUCT_100_HOURS +SECT4.N7.V17,DInt,1748,DBD1748,T_PRODUCT_0_HOURS +SECT4.N7.V18,DInt,1752,DBD1752,T_STOP_HOURS +SECT4.N7.V19,Int,1756,DBW1756,T_ALARM_MINUTES +SECT4.N7.V20,Int,1758,DBW1758,T_DRY_CYCLE_MINUTES +SECT4.N7.V21,Int,1760,DBW1760,T_POWERED_MINUTES +SECT4.N7.V22,Int,1762,DBW1762,T_PRODUCT_100_MINUTES +SECT4.N7.V23,Int,1764,DBW1764,T_PRODUCT_0_MINUTES +SECT4.N7.V24,Int,1766,DBW1766,T_STOP_MINUTES +SECT5,"""UDT SIPA SV Section""",1664,DBX1664.0, +SECT5.N1,DInt,1664,DBD1664,.DB_IOT.STATO_MACCHINA +SECT5.N2,DInt,1668,DBD1668,.DB_IOT.ALLARME_FERMO +SECT5.N3,DInt,1672,DBD1672,.DB_IOT.WARNING_ATTIVO (che compromette produzione) +SECT5.N4,Int,1676,DBW1676,.DB_IOT.STATO_OPERATIVO (Semaforo) +SECT5.N5,Int,1678,DBW1678,".DB_IOT.MODO_OPERATIVO (Prod,Simula,Man, ecc)" +SECT5.N6,DInt,1680,DBD1680,.DB_IOT.ALARM_STOP_NO +SECT5.N7.V1,DInt,1684,DBD1684,PIECES_TOT +SECT5.N7.V2,DInt,1688,DBD1688,PIECES_OK +SECT5.N7.V3,DInt,1692,DBD1692,PIECES_KO_1 +SECT5.N7.V4,DInt,1696,DBD1696,PIECES_KO_2 +SECT5.N7.V5,DInt,1700,DBD1700,PIECES_KO_3 +SECT5.N7.V6,DInt,1704,DBD1704,PIECES_KO_4 +SECT5.N7.V7,DInt,1708,DBD1708,PIECES_KO_5 +SECT5.N7.V8,DInt,1712,DBD1712,PIECES_KO_6 +SECT5.N7.V9,DInt,1716,DBD1716,PIECES_KO_7 +SECT5.N7.V10,DInt,1720,DBD1720,PIECES_KO_8 +SECT5.N7.V11,DInt,1724,DBD1724,PIECES_KO_9 +SECT5.N7.V12,DInt,1728,DBD1728,PIECES_KO_10 +SECT5.N7.V13,DInt,1732,DBD1732,T_ALARM_HOURS +SECT5.N7.V14,DInt,1736,DBD1736,T_DRY_CYCLE_HOURS +SECT5.N7.V15,DInt,1740,DBD1740,T_POWERED_HOURS +SECT5.N7.V16,DInt,1744,DBD1744,T_PRODUCT_100_HOURS +SECT5.N7.V17,DInt,1748,DBD1748,T_PRODUCT_0_HOURS +SECT5.N7.V18,DInt,1752,DBD1752,T_STOP_HOURS +SECT5.N7.V19,Int,1756,DBW1756,T_ALARM_MINUTES +SECT5.N7.V20,Int,1758,DBW1758,T_DRY_CYCLE_MINUTES +SECT5.N7.V21,Int,1760,DBW1760,T_POWERED_MINUTES +SECT5.N7.V22,Int,1762,DBW1762,T_PRODUCT_100_MINUTES +SECT5.N7.V23,Int,1764,DBW1764,T_PRODUCT_0_MINUTES +SECT5.N7.V24,Int,1766,DBW1766,T_STOP_MINUTES diff --git a/DB_Structure.xlsx b/DB_Structure.xlsx index d93fb4862e710b2d1f8ee937d1b9e230d8676990..4f79177b80c91d5445bd081f9310cf142e2b6ffe 100644 GIT binary patch delta 6812 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 IBp4O`1C`dcVgLXD delta 5709 zcmai2c{tSl*S2I$6cW=6l_FEtW-^u`rG$)~D1?YXM)q~G6cUm|XpAglU$SP&nh8l5 z``#2`?50Mx_dA}a-}An|_m5|;Yd+?>=RW7$=bZcVz2-tTjn*ysz|8r4L?u=FFayKv zz4&fsQS7@TS0|ajsj~ZZ=S7X5PIzt6+2BQ-FJ{qRxD-0|w?`?fw?=KD~61K=KDNdXBYu+m=*D1Ykz|v?lzbE&8ucr+x zJ2c9XU`Gq*sVUfSu*lumPPhGnHld;j7YoWxD{lb3yC$l*M{ zmbt5l-VFf?%Bk;>?d0k8@wwZ3eT1!I-9cBYh6dGG06O{F7VfOmk6$5 zOU?_od3&$el`tsZfRo-_T8rpXxx9isqB^2+AfUA{uyst>&Aq7jsLJ6G zqo9&GA{`G;E5D#Sgi zcI17D(v)Ol3AdYC0h>YI6|NOinO_H=kC_|D8zUEAPC51~Zp&J{jI>OX$$$3!Idg_?K-bVn&i*nj7}QB^&a^(jGHy z^eVUN-!iNt@q6SqMwW}EJqh{I2hVcT$sNe_XQhW>_)p;5M1imeh3y5a+qLL54k+>r zRlB5JvBaKU~#!QEGqEn|T; z-vALKAHf=?LKPcN8ip!zo~pV{v` zifyJHIBrm=>FSkw^JAnU4bP3#4`ucINTxSb=e1JKr{K#fLP{5(FHnOFtU7r!diIJ| zF>dN6Ypke2{N8*9k<$NaYWd+FpQCUY&-^>_yd~{XMog3?CIT)PMBL!IjCfB2Tlq~%C6hao$eoYK z!*ymMk!tM3V`=1rtxfx=b`G#hZhBg26=LFkTDcjTfdcma#QCOHm6pcj>waU*-m;sk zNo4Ks)%y}kE{)F8dYQd@z*cQwD=6_;Sz9pqPqBHz#7jUz$Ew2s0&{!6mNw7WRrdg) zv_GiwpJMv%0cJ$Fag4_L2qTesn)cN_U@rJLoR}zAgw1`R{3?(Q%o9fLnf0Lr=O=y; zAXw{^K2V;c^2^4a1jninZF$CW6ol<=8-A~DKX}I`4PvA72W+VZ?6^OKV2tu_aO}#c zYS(H6c+eVEhY5&rZld91kor{I_*X$vDU0~bho-48SnTzn$w5AN@+2)<4T5#T*ffJv zKQ^cS2vz*4-VYxBi)wFcjcE>&oTr1)Ad(x`{7?vAS%mDgSeNK;dQ$jkC4$wnped5W z{S>QsrmwmPsZ<=@i;p2QdpkEpvU;}COMMGfq^kGVjrYXliMsA<=nGa5Z5&M$Jxh&%L(Lg)`_is_OH_G6@xMuFk(F!tGL*wcEQxcG56BQ^edL^^55LYJX4M_zzuUhi24K~PK9BVx4_*< z4Asr8(>7+d!;Np|E*FZOcwrM^$#Z+h?TaL!;MTs@sXtn!Yre1gDpyUl7PxVth6n=t zT7P3Nq}&o_6My$$>~FRGv$PRrQ!9^K#HRKUK<=^$J+WyT*$GJO+u{OY6L&g@+VC@% zMVtg%1;!KuDn?`fhG7Q*_7KtFFIdC1(o=ZQNa21nIO%#z>R*`&@X;rLKR^3T(|9>@ zOtB&)CtZ?ps2?QM&!s8S*G&dt4d29DPV@DFNDG1_C%QdC`OK2ae&a3u-xU1?0#j%M zoCJ$a2&k?RNB7_@iFiw(Ujf-5*fUscKO1#~ufjpE*jBF?j*zwf{G^Fv>qa%td@rAI zL-Aw>t zJSE;JShj(sB@wbtU@YAs0P`V3#y&`GbZJfvY2ujnSyiz7^1SDSH2GU*`M1{d4{kJa zd^{-Y$j~3}=GfMwnX7T1ZPa74}QP(#NY_xDFLbp|RvceAvelVT-f1YEb4N-L|P$Z2?$e zaS0w&mTdRt{bwByzs5hV19?O9-#w`Si*cE-&vtu<8nK>Fd)jp&+H6l5#VeAkC7QNA zejf|8z$%en@xT7OPlsP3CF1v6;Cc+x|P$AXfmU)z6oApzp*gi3JM8Y-o z<{Kyvslv|OyQo`cKtgdK;aOhnjQbm3$7ocR$9&24ygnhmasRN@AExH6hF*fwlDN`h zftd>hTQc5!lG;wL9o*#n2FFlQc)}TtW-gS6WMPYh($hqN{-OGCvqK9ipUCRu-sIG` zEk2IH(H7HZ-QO-EN8BYAPo0e5jutuxGxe?w9EDk{)4s$OssvkTG zQ;inP11way`iY|+>d}{>O5C}y zNK&?*LtHQa6Nk)@?3^Q-cEr;O+0RG#IV}v5FCTej^yL^_F_%Ki>gUO03ve;Azrz0y8YFLW}SYNiI#$JPmxo2PQ~nNY6%cFW1CLDPn^VD zKr<*0?}%168kW`1%F97#8R2NU!ZXHS6yXMRg-&L% z!zo9~ga-m6s-O-@Aa`RglCk4bo=*BHdt|}ZVSnQ<7vQ^j6!wB%E|ZkYS3mg)I!3lY z9a2D1#$GTJN8$WG%y{E33UI0XzjBTef&D{;Z!@a2(10XHEsP!Vp{1AW7ESl{9dFmejR3kyfitInos>HV~#x1x1gaLd>HoC&5tm$SxtPVj+z zibHX4ooNd8aykvLkj;C}j>5LU1jwdw@(y4jk`)lXZL0R6U$EqDMx&Pd9T(0=yyt<@ zv79?w1L869QordaR-luv_XzNSn>CB4sclO~4EMRN@Cu0+yf$V$C$1IXH_)j!hvRIr z%t|jlGB7{Cz}Omf)W|AY=$sO|046_>t)~@(1sWPE4Ph!+we7DC6#2qs2AKMkw&B^Y zA34z_ZO@I#D7y+aVCh%Q0PTh*dXM2n1%Eb_(+N0%_BKSTK-T_mCny3=pfcEWaXu++ zOQ8o#F36HDdA`inYkhr`WE+jl|Kn)Rab6UF>KMmH#hBu5OgX*w8HNOLB7#uv% zduD@NrFv$4ZMkoCp|jz$>XI(8Z;qA~M4iL@+FhY-_xn-<5W>3DsM&^_eY@)2qkGI{ z*2f+*a&F0fs1`rKz@Q)$zbbefJ7nRSagCpKYD;T}CnDcO%jJTIoB6P%{*8+cE+uzT zJ&cVb6ypy_JaoeJFBVJ3)HhRCa9tJ;CR${yc#h!$Xat{%-GN%g;*Q)!u4|Q9ojTN{ z#BM|X!u!~o(!!ed4kD!jN+s>SaoTF3Y%Pmw_Jg0{M7cuR57>8IW9prt>N({}Ku zv%zec=7od#U%Ox9xKf7i`s9G~p_3+w6+h;32fFO~^EoXp4ok`ZPP~8kXFqFtpOyWN z-Gr6Ej-5g^TT2y(&y|#iiP&0N!+h~Aow81vI;Q65l3%3XtH*7?pb?bYXdEDWxX5eG} zRk&MdnU8qY~Gs^$>T9mtbW}3FPsjjB~g(9SVb78~V57^#mKDq$L=_ zO~Kp=XI26aO%HJsy%3cxrI46KjB~iH5_l8~VB!=^^S>S&$ATe@6!tqB3`$HxM;c=q zy$)20mOz3R*_}1+C^3y58KOhh8i)V&Ab4LnT_PF`;hdNB_Qke z5P2`Vx20GHN>%YcsQS*CD}2Qa+k?|m3aWV`yp4F>P_{fkHQLzyS?jQ~I}@%%N;+$L zbx{ksEX6+keC$JW^r%HGm24N5EIfwbYL3m#H^PXR4e+EKb8*SDsma$k1zix+*H$&VpW!JXJTpQR~D>W8~!LO@`;I~ zLxJ;A8ZIppYH%V_C3wp4?ry=*)yJz+auMEfC+nh~@>m@cnyiUEdr_FpIegq0CvliZBJFt{;Z#@2v*m*1^?4sak zaOF4BrF5x7^&F1z5$3Ab(U68fJ8?JOm0WxjtZeeL6!azAuzJIt*I)9~9WU!0c;YBU zDpD7rLM`zhee)15i_TXPJrn-%wv-{^)1I1` zoD=se5=i0st;d6mDD49A#lFYxwov=2wXR4auTQmq{>g{*NCG@nRY z@|e`Lhp4@Kpf#<;96wNosNq39ZL4&N_qurV$}Yd_K=E=*PO08bksv;A>ij){oWV-y z3iZtSqV&(jEiqM0G{a*XkyU*sh>BDC?9W8VxPc4i%M|x#`rrT3m4KQsf%)Tup(nxrJc$_?_!<6rRR+H} z8vh=8iD^;j`8frqqu_X@b7#QxVT&^|Fz7QeFdX@Z%upFjI~gBv4#|WPjjug-iuKoN H`j`I$D=Z5r diff --git a/DB_Structure.xml b/DB_Structure.xml index a842c56..0627122 100644 --- a/DB_Structure.xml +++ b/DB_Structure.xml @@ -11,108 +11,144 @@ DInt .DB_IOT.USERLEVEL 0 + DBD0 String[81] .DB_IOT.USERNAME 4 + DBX4.0 String[81] .DB_IOT.NOME_RICETTA 88 + DBX88.0 Int .DB_IOT.NEXT_MAINT_CYCLES 172 + DBW172 String[254] 174 + DBX174.0 String[254] 430 + DBX430.0 String[254] 686 + DBX686.0 String[254] 942 + DBX942.0 String[8] 1198 + DBX1198.0 + Array[1..3] of Real .DB_IOT.ELECTRIC_VOLTAGE_PHASE_D - - Real - true - 1208 - - - Real - true - 1212 - - - Real - true - 1216 - + + <[1]> + Real + .DB_IOT.ELECTRIC_VOLTAGE_PHASE_D + true + 1208 + DBD1208 + + <[2]> + Real + .DB_IOT.ELECTRIC_VOLTAGE_PHASE_D + true + 1212 + DBD1212 + + <[3]> + Real + .DB_IOT.ELECTRIC_VOLTAGE_PHASE_D + true + 1216 + DBD1216 + + + 1208 + DBX1208.0 + Array[1..3] of Real .DB_IOT.ELECTRIC_CURRENT_PHASE_D - - Real - true - 1220 - - - Real - true - 1224 - - - Real - true - 1228 - + + <[1]> + Real + .DB_IOT.ELECTRIC_CURRENT_PHASE_D + true + 1220 + DBD1220 + + <[2]> + Real + .DB_IOT.ELECTRIC_CURRENT_PHASE_D + true + 1224 + DBD1224 + + <[3]> + Real + .DB_IOT.ELECTRIC_CURRENT_PHASE_D + true + 1228 + DBD1228 + + + 1220 + DBX1220.0 Real .DB_IOT.ELECTRIC_POWER_D 1232 + DBD1232 Real .DB_IOT.ELECTRIC_POWER_FACTOR_D 1236 + DBD1236 Real .DB_IOT.ELECTRIC_POWER_HOUR_D 1240 + DBD1240 Real .DB_IOT.ELECTRIC_POWER_WH 1244 + DBD1244 0 + DBX0.0 "UDT SIPA SV Section" @@ -123,157 +159,188 @@ DInt .DB_IOT.STATO_MACCHINA 1664 + DBD1664 DInt .DB_IOT.ALLARME_FERMO 1668 + DBD1668 DInt .DB_IOT.WARNING_ATTIVO (che compromette produzione) 1672 + DBD1672 Int .DB_IOT.STATO_OPERATIVO (Semaforo) 1676 + DBW1676 Int .DB_IOT.MODO_OPERATIVO (Prod,Simula,Man, ecc) 1678 + DBW1678 DInt .DB_IOT.ALARM_STOP_NO 1680 + DBD1680 DInt PIECES_TOT 1684 + DBD1684 DInt PIECES_OK 1688 + DBD1688 DInt PIECES_KO_1 1692 + DBD1692 DInt PIECES_KO_2 1696 + DBD1696 DInt PIECES_KO_3 1700 + DBD1700 DInt PIECES_KO_4 1704 + DBD1704 DInt PIECES_KO_5 1708 + DBD1708 DInt PIECES_KO_6 1712 + DBD1712 DInt PIECES_KO_7 1716 + DBD1716 DInt PIECES_KO_8 1720 + DBD1720 DInt PIECES_KO_9 1724 + DBD1724 DInt PIECES_KO_10 1728 + DBD1728 DInt T_ALARM_HOURS 1732 + DBD1732 DInt T_DRY_CYCLE_HOURS 1736 + DBD1736 DInt T_POWERED_HOURS 1740 + DBD1740 DInt T_PRODUCT_100_HOURS 1744 + DBD1744 DInt T_PRODUCT_0_HOURS 1748 + DBD1748 DInt T_STOP_HOURS 1752 + DBD1752 Int T_ALARM_MINUTES 1756 + DBW1756 Int T_DRY_CYCLE_MINUTES 1758 + DBW1758 Int T_POWERED_MINUTES 1760 + DBW1760 Int T_PRODUCT_100_MINUTES 1762 + DBW1762 Int T_PRODUCT_0_MINUTES 1764 + DBW1764 Int T_STOP_MINUTES 1766 + DBW1766 1248 + DBX1248.0 "UDT SIPA SV Section" @@ -284,157 +351,188 @@ DInt .DB_IOT.STATO_MACCHINA 1664 + DBD1664 DInt .DB_IOT.ALLARME_FERMO 1668 + DBD1668 DInt .DB_IOT.WARNING_ATTIVO (che compromette produzione) 1672 + DBD1672 Int .DB_IOT.STATO_OPERATIVO (Semaforo) 1676 + DBW1676 Int .DB_IOT.MODO_OPERATIVO (Prod,Simula,Man, ecc) 1678 + DBW1678 DInt .DB_IOT.ALARM_STOP_NO 1680 + DBD1680 DInt PIECES_TOT 1684 + DBD1684 DInt PIECES_OK 1688 + DBD1688 DInt PIECES_KO_1 1692 + DBD1692 DInt PIECES_KO_2 1696 + DBD1696 DInt PIECES_KO_3 1700 + DBD1700 DInt PIECES_KO_4 1704 + DBD1704 DInt PIECES_KO_5 1708 + DBD1708 DInt PIECES_KO_6 1712 + DBD1712 DInt PIECES_KO_7 1716 + DBD1716 DInt PIECES_KO_8 1720 + DBD1720 DInt PIECES_KO_9 1724 + DBD1724 DInt PIECES_KO_10 1728 + DBD1728 DInt T_ALARM_HOURS 1732 + DBD1732 DInt T_DRY_CYCLE_HOURS 1736 + DBD1736 DInt T_POWERED_HOURS 1740 + DBD1740 DInt T_PRODUCT_100_HOURS 1744 + DBD1744 DInt T_PRODUCT_0_HOURS 1748 + DBD1748 DInt T_STOP_HOURS 1752 + DBD1752 Int T_ALARM_MINUTES 1756 + DBW1756 Int T_DRY_CYCLE_MINUTES 1758 + DBW1758 Int T_POWERED_MINUTES 1760 + DBW1760 Int T_PRODUCT_100_MINUTES 1762 + DBW1762 Int T_PRODUCT_0_MINUTES 1764 + DBW1764 Int T_STOP_MINUTES 1766 + DBW1766 1352 + DBX1352.0 "UDT SIPA SV Section" @@ -445,157 +543,188 @@ DInt .DB_IOT.STATO_MACCHINA 1664 + DBD1664 DInt .DB_IOT.ALLARME_FERMO 1668 + DBD1668 DInt .DB_IOT.WARNING_ATTIVO (che compromette produzione) 1672 + DBD1672 Int .DB_IOT.STATO_OPERATIVO (Semaforo) 1676 + DBW1676 Int .DB_IOT.MODO_OPERATIVO (Prod,Simula,Man, ecc) 1678 + DBW1678 DInt .DB_IOT.ALARM_STOP_NO 1680 + DBD1680 DInt PIECES_TOT 1684 + DBD1684 DInt PIECES_OK 1688 + DBD1688 DInt PIECES_KO_1 1692 + DBD1692 DInt PIECES_KO_2 1696 + DBD1696 DInt PIECES_KO_3 1700 + DBD1700 DInt PIECES_KO_4 1704 + DBD1704 DInt PIECES_KO_5 1708 + DBD1708 DInt PIECES_KO_6 1712 + DBD1712 DInt PIECES_KO_7 1716 + DBD1716 DInt PIECES_KO_8 1720 + DBD1720 DInt PIECES_KO_9 1724 + DBD1724 DInt PIECES_KO_10 1728 + DBD1728 DInt T_ALARM_HOURS 1732 + DBD1732 DInt T_DRY_CYCLE_HOURS 1736 + DBD1736 DInt T_POWERED_HOURS 1740 + DBD1740 DInt T_PRODUCT_100_HOURS 1744 + DBD1744 DInt T_PRODUCT_0_HOURS 1748 + DBD1748 DInt T_STOP_HOURS 1752 + DBD1752 Int T_ALARM_MINUTES 1756 + DBW1756 Int T_DRY_CYCLE_MINUTES 1758 + DBW1758 Int T_POWERED_MINUTES 1760 + DBW1760 Int T_PRODUCT_100_MINUTES 1762 + DBW1762 Int T_PRODUCT_0_MINUTES 1764 + DBW1764 Int T_STOP_MINUTES 1766 + DBW1766 1456 + DBX1456.0 "UDT SIPA SV Section" @@ -606,157 +735,188 @@ DInt .DB_IOT.STATO_MACCHINA 1664 + DBD1664 DInt .DB_IOT.ALLARME_FERMO 1668 + DBD1668 DInt .DB_IOT.WARNING_ATTIVO (che compromette produzione) 1672 + DBD1672 Int .DB_IOT.STATO_OPERATIVO (Semaforo) 1676 + DBW1676 Int .DB_IOT.MODO_OPERATIVO (Prod,Simula,Man, ecc) 1678 + DBW1678 DInt .DB_IOT.ALARM_STOP_NO 1680 + DBD1680 DInt PIECES_TOT 1684 + DBD1684 DInt PIECES_OK 1688 + DBD1688 DInt PIECES_KO_1 1692 + DBD1692 DInt PIECES_KO_2 1696 + DBD1696 DInt PIECES_KO_3 1700 + DBD1700 DInt PIECES_KO_4 1704 + DBD1704 DInt PIECES_KO_5 1708 + DBD1708 DInt PIECES_KO_6 1712 + DBD1712 DInt PIECES_KO_7 1716 + DBD1716 DInt PIECES_KO_8 1720 + DBD1720 DInt PIECES_KO_9 1724 + DBD1724 DInt PIECES_KO_10 1728 + DBD1728 DInt T_ALARM_HOURS 1732 + DBD1732 DInt T_DRY_CYCLE_HOURS 1736 + DBD1736 DInt T_POWERED_HOURS 1740 + DBD1740 DInt T_PRODUCT_100_HOURS 1744 + DBD1744 DInt T_PRODUCT_0_HOURS 1748 + DBD1748 DInt T_STOP_HOURS 1752 + DBD1752 Int T_ALARM_MINUTES 1756 + DBW1756 Int T_DRY_CYCLE_MINUTES 1758 + DBW1758 Int T_POWERED_MINUTES 1760 + DBW1760 Int T_PRODUCT_100_MINUTES 1762 + DBW1762 Int T_PRODUCT_0_MINUTES 1764 + DBW1764 Int T_STOP_MINUTES 1766 + DBW1766 1560 + DBX1560.0 "UDT SIPA SV Section" @@ -767,157 +927,188 @@ DInt .DB_IOT.STATO_MACCHINA 1664 + DBD1664 DInt .DB_IOT.ALLARME_FERMO 1668 + DBD1668 DInt .DB_IOT.WARNING_ATTIVO (che compromette produzione) 1672 + DBD1672 Int .DB_IOT.STATO_OPERATIVO (Semaforo) 1676 + DBW1676 Int .DB_IOT.MODO_OPERATIVO (Prod,Simula,Man, ecc) 1678 + DBW1678 DInt .DB_IOT.ALARM_STOP_NO 1680 + DBD1680 DInt PIECES_TOT 1684 + DBD1684 DInt PIECES_OK 1688 + DBD1688 DInt PIECES_KO_1 1692 + DBD1692 DInt PIECES_KO_2 1696 + DBD1696 DInt PIECES_KO_3 1700 + DBD1700 DInt PIECES_KO_4 1704 + DBD1704 DInt PIECES_KO_5 1708 + DBD1708 DInt PIECES_KO_6 1712 + DBD1712 DInt PIECES_KO_7 1716 + DBD1716 DInt PIECES_KO_8 1720 + DBD1720 DInt PIECES_KO_9 1724 + DBD1724 DInt PIECES_KO_10 1728 + DBD1728 DInt T_ALARM_HOURS 1732 + DBD1732 DInt T_DRY_CYCLE_HOURS 1736 + DBD1736 DInt T_POWERED_HOURS 1740 + DBD1740 DInt T_PRODUCT_100_HOURS 1744 + DBD1744 DInt T_PRODUCT_0_HOURS 1748 + DBD1748 DInt T_STOP_HOURS 1752 + DBD1752 Int T_ALARM_MINUTES 1756 + DBW1756 Int T_DRY_CYCLE_MINUTES 1758 + DBW1758 Int T_POWERED_MINUTES 1760 + DBW1760 Int T_PRODUCT_100_MINUTES 1762 + DBW1762 Int T_PRODUCT_0_MINUTES 1764 + DBW1764 Int T_STOP_MINUTES 1766 + DBW1766 1664 + DBX1664.0 diff --git a/ExpandDB.py b/ExpandDB.py index 9f4e7e4..1b310f1 100644 --- a/ExpandDB.py +++ b/ExpandDB.py @@ -29,29 +29,41 @@ def expand_udt_references(db_struct, udts): def handle_array_types(db_struct): """ - Handle array types once all UDTs are expanded. - This function modifies the structure in place. + Handle array types to expand them into multiple fields as sub-elements while preserving comments. + Modifies the structure in place by expanding array definitions within their original field. """ if isinstance(db_struct, dict): for key, value in list(db_struct.items()): if isinstance(value, dict): + # Recursively process nested dictionaries handle_array_types(value) - elif isinstance(value, str): - # Parsing array definitions, e.g., "Array[1..3] of Real" - match = re.match(r"Array\[(\d+)\.\.(\d+)\] of (\w+)", value) + + if isinstance(value, dict) and 'type' in value: + match = re.match(r"Array\[(\d+)\.\.(\d+)\] of (\w+)", value['type']) if match: - lower_bound, upper_bound, base_type = ( - int(match.group(1)), - int(match.group(2)), - match.group(3), - ) - # Expand this field into multiple fields - db_struct.pop(key) # Remove the original field + lower_bound, upper_bound, base_type = int(match.group(1)), int(match.group(2)), match.group(3) + comment = value.get('comment', '') + + # Instead of popping the original key, initialize a sub-dictionary + value['Array'] = {} # Initialize a sub-dictionary for array elements + for i in range(lower_bound, upper_bound + 1): - db_struct[f"{key}_{i}"] = {"type": base_type, 'is_array_element': True} - print( - f"Expanded field '{key}' into array fields: {key}_{lower_bound} to {key}_{upper_bound} of type {base_type}" - ) + element_key = f"[{i}]" + value['Array'][element_key] = { + 'type': base_type, + 'comment': comment, + 'is_array_element': True + } + + # Optionally, modify or remove the original type designation if necessary + # value.pop('type', None) # Uncomment this if you want to remove the 'type' from the original + + # Continue the recursive handling if it's not an array definition + elif isinstance(value, dict): + handle_array_types(value) + + + type_sizes = { @@ -64,11 +76,31 @@ type_sizes = { } +def calculate_plc_address(type_name, byte_offset, bit_offset=None): + """ + Calculate the PLC address notation based on byte size, byte offset and bit offset. + """ + byte_size = type_sizes.get( + type_name, 0 + ) + if type_name == "Bool": + if bit_offset is not None: + return f"DBX{byte_offset}.{bit_offset}" # Address for single bits + return f"DBB{byte_offset}" # Address for single bytes + elif byte_size == 2: + return f"DBW{byte_offset}" # Address for two-byte words + elif byte_size == 4: + return f"DBD{byte_offset}" # Address for four-byte double words + else: + return f"DBX{byte_offset}.0" # Default to bit address for types longer than 4 bytes (e.g., strings) + + def calculate_offsets(db_struct, current_offset=0, parent=None): """ Recursively calculate byte offsets for each field in the DB structure considering special types. """ last_key_was_bool = False + last_bit_offset = 0 # To track bit offsets within a byte if isinstance(db_struct, dict): for key, value in list(db_struct.items()): if isinstance(value, dict): @@ -81,10 +113,18 @@ def calculate_offsets(db_struct, current_offset=0, parent=None): if not is_array_element and current_offset % 2 != 0: current_offset += 1 # Align to the next even offset if it's not an array element - + last_bit_offset = 0 + + plc_address = value.get('plc_address', False) + if plc_address is not False: + print("Address Already Calcolated!") + + plc_address = calculate_plc_address(type_name, current_offset, last_bit_offset) + # Special handling for String types if "String" in type_name: match = re.match(r"String\[(\d+)\]", type_name) + last_bit_offset = 0 if match: length = int(match.group(1)) size = length + 2 # Account for null-termination and string length prefix @@ -94,14 +134,16 @@ def calculate_offsets(db_struct, current_offset=0, parent=None): # Adjusting Bool sizes based on grouping if type_name == "Bool": if last_key_was_bool: # This is a grouped bool - size = 0.125 # One bit per Bool if grouped + last_bit_offset += 1 # One bit per Bool if grouped else: size = 2 # Bools use a full byte if not grouped + last_bit_offset = 0 last_key_was_bool = True else: last_key_was_bool = False value["offset"] = current_offset + value['plc_address'] = plc_address # Store the calculated PLC address current_offset += size current_offset = calculate_offsets( diff --git a/ExportData.py b/ExportData.py index a178f54..a597ebb 100644 --- a/ExportData.py +++ b/ExportData.py @@ -1,6 +1,7 @@ import xmltodict import pandas as pd + def save_json_to_xml(json_data, filename="DB_Structure.xml"): """ Convert JSON data to XML and save it to a file. @@ -32,23 +33,33 @@ def collect_data_for_table(db_struct, parent_prefix="", collected_data=[]): Recursively collect data from the DB structure to display in a tabular format, omitting 'fields' and 'Struct' in the names. """ + is_array_element = False if isinstance(db_struct, dict): for key, value in db_struct.items(): # Skip 'fields' and 'Struct' keys in the name path - if key == 'fields' or key == 'Struct': + # + if key == "fields" or key == "Struct" or key == "Array": next_prefix = parent_prefix # Continue with the current prefix else: - next_prefix = f"{parent_prefix}.{key}" if parent_prefix else key - - if isinstance(value, dict) and 'type' in value: # Directly a field with 'type' + if isinstance(value, dict): + is_array_element = value.get('is_array_element', False) + if not is_array_element: + next_prefix = f"{parent_prefix}.{key}" if parent_prefix else key + else: + next_prefix = f"{parent_prefix}{key}" if parent_prefix else key + + if ( + isinstance(value, dict) and "type" in value + ): # Directly a field with 'type' field_data = { "Nombre": next_prefix, - "Tipo": value.get('type', 'N/A'), - "Offset": value.get('offset', 'N/A'), - "Comentario": value.get('comment', 'N/A') + "Tipo": value.get("type", "N/A"), + "Offset": value.get("offset", "N/A"), + "Dirección PLC": value.get("plc_address", "N/A"), + "Comentario": value.get("comment", "N/A"), } collected_data.append(field_data) - + # Recursively handle nested dictionaries and lists if isinstance(value, dict) or isinstance(value, list): collect_data_for_table(value, next_prefix, collected_data) @@ -56,7 +67,7 @@ def collect_data_for_table(db_struct, parent_prefix="", collected_data=[]): for index, item in enumerate(db_struct): item_prefix = f"{parent_prefix}[{index}]" if parent_prefix else f"[{index}]" collect_data_for_table(item, item_prefix, collected_data) - + return collected_data diff --git a/__pycache__/ExpandDB.cpython-310.pyc b/__pycache__/ExpandDB.cpython-310.pyc index 3d88268966987ebe93990d488915d896ca599c6a..3f4e7961df603e6f4a8f6bbe7750590661e1db1a 100644 GIT binary patch delta 1988 zcmZ8h&2Jk;6rY)${qTD2xS>rOrL>b0P?k2Ottuf^QBgls^#B2yN>pwt<776;D$Y8Y z-4qL49TT8PcmO~ zZAxSc?f zI9rbstQsrPR`FV#G+Tp;gEWf4htyRSm@<6w|$L?b(k9NoZUz55pT9QAZs{ z2P2N4b`r!1Sm_xMzI~Yb)MMkUMmc?x2Gq00SwITZ=Av*dIS?dSCecOS#a=o{`7tSm0AucQerM5~DJrpEVC=zY?afpzTUV@{@c-D>;d+p4Q zfm*W)lFNk)iuQyGDE<>TaPOT1AZ~l)!m)QyRNmWI2xj!2-n{p{H*e>C`_twR>$OR> z>N8y5{`^Y6vvyi*!pEoA-)Yp8uPTpVucQK1eZ=-W1v{*L>Bp~s<0l@%YbfubB!8eX z%rXNDuE&O3cIGVE0`9W?UWccUa*XmKx?zOn3jlUpDSQ$$M#eoWDX@IWQ^z`Z_N;SO zR(uHySlJHQg;y-WaZb3Cid3d9UgcX@VnI`}!b-&(Y{Bv3T3WKMlFI!K+p+MNsgf-{ zX5Txv+41`(P+s9HuOb5DSf@Zq)D`O@Hn?b11v`wSU7a8KA+8U)DpsQ?>}uV87@CLE zClqx$>CsLzqh(1#A+iIUYoC7!zyO7 z>aFl5Z-sLaqHkUfC;g(|aJya2PG##|O@q(5j&eEfn%-gVV0JDCdNP~l&U7-(rS8Uq zNLLZp_B730*GWA`>T32>wm!;XsISnmP-|puqIv-(X`%Av74VB4Z~*}izytr>cQ3>9 zz+nr-GybJ`DnM^$pS$-@0!)!81-ELzn1a;#mtV90@hd`pArUYt3w~+Et^ADX5m8}- zAwlGsP>urRR>`1^q!4I(wv@bKLCJNd#F3-PcHd+vsM3jbvA}LYO3%6oF59x+Mk1Dx zlr9l5^{uaDgQZ^Vu8I;4(W-pJ^`}VUedS}6E17z#k~(PNM_9nNg4@VP>(OP#w~~Ad zCxzpx#or4*0jBO5O{gUIAQ5&0k)&Z9&(5u~q@q9N)R zvtRrM1lgbd>&^d6|1!m>fm~1;vf;x@_}~UQiqYLiLkJ&e_#W;61np;afhUJfHH-w@ za|E~`IElwS;A9acT>sod3=-o;_G{(bB~qdJdvK>^&`gMobwNd_d>zE!`WCwIkD&+I sZkKg4d%L<>FY;bRm!{tIt!!M~3h5I)Mu~Xm25)kt;>C9V^8MiEKN^85?f?J) diff --git a/__pycache__/ExportData.cpython-310.pyc b/__pycache__/ExportData.cpython-310.pyc index 3b9b39873c2f4845abdbab6ea9d2d0fe82d29585..fe79e379f4fd71babea84f4438b4afde4cdbbeee 100644 GIT binary patch delta 704 zcmX|9&ubGw6rMM~b~C$4qZC>jsR0ohrS_tzz0}eoShNb&OHe}0Zc1pHw6j~KWtIv# z>P7ZgE6JZAJqw~9{1@Dde}aEN5Bg?nGs}DP&3xbcc#qj17k*tV^@~MCaD7?4*1qe1 zF8LJ1Nrh5?iFB5Ig{ky6yL{-OqJXi25#0wu0!Ua)42fYt^?@NnIwGs&W%mV5cp?lB z=oXDCxU>H|-=ccfKq7lru}+g~6TN9aivs_nNE}0l+&Ciua_$xF=1AaBZ(?*q zM>=5eoa}mrZde(KE%_;S3>g4UJcARvNdX)Dkau1*F7{tK<~cz5_9lkHB}4WdkL#Coq4XJT3F=6+W0M2)6Jjj$VThrKw1n;DPycftd;3IlI;`_&ot=JNKFQU4C49iujt*O`&i9jE z^(lR{l4keN5J*1V7hANbRQ$3&lkw3i}nrQp~;Q5==zqDqZZ7ZCYQRjk>&K&f;bj_Wcxow4( Y)l)WAY_k0z{oY+DFr}1Ra{U|s0I58wF#rGn delta 535 zcmXw#!D>`76ozw7a&vPt)9YAt)K-cEf^7#Z#f7*MadzTtDilOPXl6j#-m$q+P;;p; z?p$W)SeSVP@d0$vg|Fb<^bLFfb>Ybs6Y}SWbMocq{8&CcpHG&SG^6$L^!j+FKj&=( z@nsbeAP;N&8+5}Nzj_>76rKBY%3maodFEh>cGt5xF4%xQeeeV;UJ1_)>|=S6Zrn$E z*+Z2SEf2QmVa5#ie8x_A0iIV0QA9%-7~#b$W(Pj;V$O{)$pRZEqdRVF8m&>EL?u1W zg_jF}7^Fdz!^R~P>5-FO5D2Fn*iq(j=U?1dd+Soqra*C5C~jIQ3RX11GM`dBeIkm) z{P(=dh^72Ff;6ya5w_6^!{ozuEyvGC2d1p$jHd$pX5$K}Y? z>E7hMFJeCG@_$oKUPxn|T{XFKH<+saUDt#Z}w{RKZ=ch&#^