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 d93fb48..4f79177 100644 Binary files a/DB_Structure.xlsx and b/DB_Structure.xlsx differ 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 3d88268..3f4e796 100644 Binary files a/__pycache__/ExpandDB.cpython-310.pyc and b/__pycache__/ExpandDB.cpython-310.pyc differ diff --git a/__pycache__/ExportData.cpython-310.pyc b/__pycache__/ExportData.cpython-310.pyc index 3b9b398..fe79e37 100644 Binary files a/__pycache__/ExportData.cpython-310.pyc and b/__pycache__/ExportData.cpython-310.pyc differ