From a4bc042b2c1e4166370e8aec219dd5b27f011a4a Mon Sep 17 00:00:00 2001 From: Miguel Date: Mon, 22 Apr 2024 09:21:25 +0200 Subject: [PATCH] Offsets funcionando. El problema era el uso de copy en vez de deepcopy al expandir las udt --- CopyPaste.py | 33 +- DB_Structure.csv | 240 +++++++------- DB_Structure.xlsx | Bin 11235 -> 11669 bytes DB_Structure.xml | 480 +++++++++++++-------------- DB_to_Excel.py | 5 - ExpandDB.py | 148 +++++---- __pycache__/ExpandDB.cpython-310.pyc | Bin 3509 -> 3783 bytes 7 files changed, 458 insertions(+), 448 deletions(-) diff --git a/CopyPaste.py b/CopyPaste.py index 2f8a553..7ab7b55 100644 --- a/CopyPaste.py +++ b/CopyPaste.py @@ -1,24 +1,19 @@ -def handle_array_types(db_struct): +def calculate_offsets(db_struct, current_offset=0, parent=None): """ - Handle array types once all UDTs are expanded. - This function modifies the structure in place. + 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): - 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 + if "type" in value and not "offset" in value: + + current_offset = calculate_offsets( + value, current_offset, value + ) # Recurse into nested structs + + elif isinstance(db_struct, list): + for item in db_struct: + current_offset = calculate_offsets(item, current_offset, parent) + return current_offset \ No newline at end of file diff --git a/DB_Structure.csv b/DB_Structure.csv index 36ae6fd..e0758f8 100644 --- a/DB_Structure.csv +++ b/DB_Structure.csv @@ -22,129 +22,129 @@ 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 +SECT1.N1,DInt,1248,DBD1248,.DB_IOT.STATO_MACCHINA +SECT1.N2,DInt,1252,DBD1252,.DB_IOT.ALLARME_FERMO +SECT1.N3,DInt,1256,DBD1256,.DB_IOT.WARNING_ATTIVO (che compromette produzione) +SECT1.N4,Int,1260,DBW1260,.DB_IOT.STATO_OPERATIVO (Semaforo) +SECT1.N5,Int,1262,DBW1262,".DB_IOT.MODO_OPERATIVO (Prod,Simula,Man, ecc)" +SECT1.N6,DInt,1264,DBD1264,.DB_IOT.ALARM_STOP_NO +SECT1.N7.V1,DInt,1268,DBD1268,PIECES_TOT +SECT1.N7.V2,DInt,1272,DBD1272,PIECES_OK +SECT1.N7.V3,DInt,1276,DBD1276,PIECES_KO_1 +SECT1.N7.V4,DInt,1280,DBD1280,PIECES_KO_2 +SECT1.N7.V5,DInt,1284,DBD1284,PIECES_KO_3 +SECT1.N7.V6,DInt,1288,DBD1288,PIECES_KO_4 +SECT1.N7.V7,DInt,1292,DBD1292,PIECES_KO_5 +SECT1.N7.V8,DInt,1296,DBD1296,PIECES_KO_6 +SECT1.N7.V9,DInt,1300,DBD1300,PIECES_KO_7 +SECT1.N7.V10,DInt,1304,DBD1304,PIECES_KO_8 +SECT1.N7.V11,DInt,1308,DBD1308,PIECES_KO_9 +SECT1.N7.V12,DInt,1312,DBD1312,PIECES_KO_10 +SECT1.N7.V13,DInt,1316,DBD1316,T_ALARM_HOURS +SECT1.N7.V14,DInt,1320,DBD1320,T_DRY_CYCLE_HOURS +SECT1.N7.V15,DInt,1324,DBD1324,T_POWERED_HOURS +SECT1.N7.V16,DInt,1328,DBD1328,T_PRODUCT_100_HOURS +SECT1.N7.V17,DInt,1332,DBD1332,T_PRODUCT_0_HOURS +SECT1.N7.V18,DInt,1336,DBD1336,T_STOP_HOURS +SECT1.N7.V19,Int,1340,DBW1340,T_ALARM_MINUTES +SECT1.N7.V20,Int,1342,DBW1342,T_DRY_CYCLE_MINUTES +SECT1.N7.V21,Int,1344,DBW1344,T_POWERED_MINUTES +SECT1.N7.V22,Int,1346,DBW1346,T_PRODUCT_100_MINUTES +SECT1.N7.V23,Int,1348,DBW1348,T_PRODUCT_0_MINUTES +SECT1.N7.V24,Int,1350,DBW1350,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 +SECT2.N1,DInt,1352,DBD1352,.DB_IOT.STATO_MACCHINA +SECT2.N2,DInt,1356,DBD1356,.DB_IOT.ALLARME_FERMO +SECT2.N3,DInt,1360,DBD1360,.DB_IOT.WARNING_ATTIVO (che compromette produzione) +SECT2.N4,Int,1364,DBW1364,.DB_IOT.STATO_OPERATIVO (Semaforo) +SECT2.N5,Int,1366,DBW1366,".DB_IOT.MODO_OPERATIVO (Prod,Simula,Man, ecc)" +SECT2.N6,DInt,1368,DBD1368,.DB_IOT.ALARM_STOP_NO +SECT2.N7.V1,DInt,1372,DBD1372,PIECES_TOT +SECT2.N7.V2,DInt,1376,DBD1376,PIECES_OK +SECT2.N7.V3,DInt,1380,DBD1380,PIECES_KO_1 +SECT2.N7.V4,DInt,1384,DBD1384,PIECES_KO_2 +SECT2.N7.V5,DInt,1388,DBD1388,PIECES_KO_3 +SECT2.N7.V6,DInt,1392,DBD1392,PIECES_KO_4 +SECT2.N7.V7,DInt,1396,DBD1396,PIECES_KO_5 +SECT2.N7.V8,DInt,1400,DBD1400,PIECES_KO_6 +SECT2.N7.V9,DInt,1404,DBD1404,PIECES_KO_7 +SECT2.N7.V10,DInt,1408,DBD1408,PIECES_KO_8 +SECT2.N7.V11,DInt,1412,DBD1412,PIECES_KO_9 +SECT2.N7.V12,DInt,1416,DBD1416,PIECES_KO_10 +SECT2.N7.V13,DInt,1420,DBD1420,T_ALARM_HOURS +SECT2.N7.V14,DInt,1424,DBD1424,T_DRY_CYCLE_HOURS +SECT2.N7.V15,DInt,1428,DBD1428,T_POWERED_HOURS +SECT2.N7.V16,DInt,1432,DBD1432,T_PRODUCT_100_HOURS +SECT2.N7.V17,DInt,1436,DBD1436,T_PRODUCT_0_HOURS +SECT2.N7.V18,DInt,1440,DBD1440,T_STOP_HOURS +SECT2.N7.V19,Int,1444,DBW1444,T_ALARM_MINUTES +SECT2.N7.V20,Int,1446,DBW1446,T_DRY_CYCLE_MINUTES +SECT2.N7.V21,Int,1448,DBW1448,T_POWERED_MINUTES +SECT2.N7.V22,Int,1450,DBW1450,T_PRODUCT_100_MINUTES +SECT2.N7.V23,Int,1452,DBW1452,T_PRODUCT_0_MINUTES +SECT2.N7.V24,Int,1454,DBW1454,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 +SECT3.N1,DInt,1456,DBD1456,.DB_IOT.STATO_MACCHINA +SECT3.N2,DInt,1460,DBD1460,.DB_IOT.ALLARME_FERMO +SECT3.N3,DInt,1464,DBD1464,.DB_IOT.WARNING_ATTIVO (che compromette produzione) +SECT3.N4,Int,1468,DBW1468,.DB_IOT.STATO_OPERATIVO (Semaforo) +SECT3.N5,Int,1470,DBW1470,".DB_IOT.MODO_OPERATIVO (Prod,Simula,Man, ecc)" +SECT3.N6,DInt,1472,DBD1472,.DB_IOT.ALARM_STOP_NO +SECT3.N7.V1,DInt,1476,DBD1476,PIECES_TOT +SECT3.N7.V2,DInt,1480,DBD1480,PIECES_OK +SECT3.N7.V3,DInt,1484,DBD1484,PIECES_KO_1 +SECT3.N7.V4,DInt,1488,DBD1488,PIECES_KO_2 +SECT3.N7.V5,DInt,1492,DBD1492,PIECES_KO_3 +SECT3.N7.V6,DInt,1496,DBD1496,PIECES_KO_4 +SECT3.N7.V7,DInt,1500,DBD1500,PIECES_KO_5 +SECT3.N7.V8,DInt,1504,DBD1504,PIECES_KO_6 +SECT3.N7.V9,DInt,1508,DBD1508,PIECES_KO_7 +SECT3.N7.V10,DInt,1512,DBD1512,PIECES_KO_8 +SECT3.N7.V11,DInt,1516,DBD1516,PIECES_KO_9 +SECT3.N7.V12,DInt,1520,DBD1520,PIECES_KO_10 +SECT3.N7.V13,DInt,1524,DBD1524,T_ALARM_HOURS +SECT3.N7.V14,DInt,1528,DBD1528,T_DRY_CYCLE_HOURS +SECT3.N7.V15,DInt,1532,DBD1532,T_POWERED_HOURS +SECT3.N7.V16,DInt,1536,DBD1536,T_PRODUCT_100_HOURS +SECT3.N7.V17,DInt,1540,DBD1540,T_PRODUCT_0_HOURS +SECT3.N7.V18,DInt,1544,DBD1544,T_STOP_HOURS +SECT3.N7.V19,Int,1548,DBW1548,T_ALARM_MINUTES +SECT3.N7.V20,Int,1550,DBW1550,T_DRY_CYCLE_MINUTES +SECT3.N7.V21,Int,1552,DBW1552,T_POWERED_MINUTES +SECT3.N7.V22,Int,1554,DBW1554,T_PRODUCT_100_MINUTES +SECT3.N7.V23,Int,1556,DBW1556,T_PRODUCT_0_MINUTES +SECT3.N7.V24,Int,1558,DBW1558,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 +SECT4.N1,DInt,1560,DBD1560,.DB_IOT.STATO_MACCHINA +SECT4.N2,DInt,1564,DBD1564,.DB_IOT.ALLARME_FERMO +SECT4.N3,DInt,1568,DBD1568,.DB_IOT.WARNING_ATTIVO (che compromette produzione) +SECT4.N4,Int,1572,DBW1572,.DB_IOT.STATO_OPERATIVO (Semaforo) +SECT4.N5,Int,1574,DBW1574,".DB_IOT.MODO_OPERATIVO (Prod,Simula,Man, ecc)" +SECT4.N6,DInt,1576,DBD1576,.DB_IOT.ALARM_STOP_NO +SECT4.N7.V1,DInt,1580,DBD1580,PIECES_TOT +SECT4.N7.V2,DInt,1584,DBD1584,PIECES_OK +SECT4.N7.V3,DInt,1588,DBD1588,PIECES_KO_1 +SECT4.N7.V4,DInt,1592,DBD1592,PIECES_KO_2 +SECT4.N7.V5,DInt,1596,DBD1596,PIECES_KO_3 +SECT4.N7.V6,DInt,1600,DBD1600,PIECES_KO_4 +SECT4.N7.V7,DInt,1604,DBD1604,PIECES_KO_5 +SECT4.N7.V8,DInt,1608,DBD1608,PIECES_KO_6 +SECT4.N7.V9,DInt,1612,DBD1612,PIECES_KO_7 +SECT4.N7.V10,DInt,1616,DBD1616,PIECES_KO_8 +SECT4.N7.V11,DInt,1620,DBD1620,PIECES_KO_9 +SECT4.N7.V12,DInt,1624,DBD1624,PIECES_KO_10 +SECT4.N7.V13,DInt,1628,DBD1628,T_ALARM_HOURS +SECT4.N7.V14,DInt,1632,DBD1632,T_DRY_CYCLE_HOURS +SECT4.N7.V15,DInt,1636,DBD1636,T_POWERED_HOURS +SECT4.N7.V16,DInt,1640,DBD1640,T_PRODUCT_100_HOURS +SECT4.N7.V17,DInt,1644,DBD1644,T_PRODUCT_0_HOURS +SECT4.N7.V18,DInt,1648,DBD1648,T_STOP_HOURS +SECT4.N7.V19,Int,1652,DBW1652,T_ALARM_MINUTES +SECT4.N7.V20,Int,1654,DBW1654,T_DRY_CYCLE_MINUTES +SECT4.N7.V21,Int,1656,DBW1656,T_POWERED_MINUTES +SECT4.N7.V22,Int,1658,DBW1658,T_PRODUCT_100_MINUTES +SECT4.N7.V23,Int,1660,DBW1660,T_PRODUCT_0_MINUTES +SECT4.N7.V24,Int,1662,DBW1662,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 diff --git a/DB_Structure.xlsx b/DB_Structure.xlsx index 4f79177b80c91d5445bd081f9310cf142e2b6ffe..f1043f25798d0efa02db2053995e8b354b343371 100644 GIT binary patch delta 7268 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 delta 6875 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 CY{`rO diff --git a/DB_Structure.xml b/DB_Structure.xml index 0627122..68c2727 100644 --- a/DB_Structure.xml +++ b/DB_Structure.xml @@ -158,183 +158,183 @@ DInt .DB_IOT.STATO_MACCHINA - 1664 - DBD1664 + 1248 + DBD1248 DInt .DB_IOT.ALLARME_FERMO - 1668 - DBD1668 + 1252 + DBD1252 DInt .DB_IOT.WARNING_ATTIVO (che compromette produzione) - 1672 - DBD1672 + 1256 + DBD1256 Int .DB_IOT.STATO_OPERATIVO (Semaforo) - 1676 - DBW1676 + 1260 + DBW1260 Int .DB_IOT.MODO_OPERATIVO (Prod,Simula,Man, ecc) - 1678 - DBW1678 + 1262 + DBW1262 DInt .DB_IOT.ALARM_STOP_NO - 1680 - DBD1680 + 1264 + DBD1264 DInt PIECES_TOT - 1684 - DBD1684 + 1268 + DBD1268 DInt PIECES_OK - 1688 - DBD1688 + 1272 + DBD1272 DInt PIECES_KO_1 - 1692 - DBD1692 + 1276 + DBD1276 DInt PIECES_KO_2 - 1696 - DBD1696 + 1280 + DBD1280 DInt PIECES_KO_3 - 1700 - DBD1700 + 1284 + DBD1284 DInt PIECES_KO_4 - 1704 - DBD1704 + 1288 + DBD1288 DInt PIECES_KO_5 - 1708 - DBD1708 + 1292 + DBD1292 DInt PIECES_KO_6 - 1712 - DBD1712 + 1296 + DBD1296 DInt PIECES_KO_7 - 1716 - DBD1716 + 1300 + DBD1300 DInt PIECES_KO_8 - 1720 - DBD1720 + 1304 + DBD1304 DInt PIECES_KO_9 - 1724 - DBD1724 + 1308 + DBD1308 DInt PIECES_KO_10 - 1728 - DBD1728 + 1312 + DBD1312 DInt T_ALARM_HOURS - 1732 - DBD1732 + 1316 + DBD1316 DInt T_DRY_CYCLE_HOURS - 1736 - DBD1736 + 1320 + DBD1320 DInt T_POWERED_HOURS - 1740 - DBD1740 + 1324 + DBD1324 DInt T_PRODUCT_100_HOURS - 1744 - DBD1744 + 1328 + DBD1328 DInt T_PRODUCT_0_HOURS - 1748 - DBD1748 + 1332 + DBD1332 DInt T_STOP_HOURS - 1752 - DBD1752 + 1336 + DBD1336 Int T_ALARM_MINUTES - 1756 - DBW1756 + 1340 + DBW1340 Int T_DRY_CYCLE_MINUTES - 1758 - DBW1758 + 1342 + DBW1342 Int T_POWERED_MINUTES - 1760 - DBW1760 + 1344 + DBW1344 Int T_PRODUCT_100_MINUTES - 1762 - DBW1762 + 1346 + DBW1346 Int T_PRODUCT_0_MINUTES - 1764 - DBW1764 + 1348 + DBW1348 Int T_STOP_MINUTES - 1766 - DBW1766 + 1350 + DBW1350 @@ -350,183 +350,183 @@ DInt .DB_IOT.STATO_MACCHINA - 1664 - DBD1664 + 1352 + DBD1352 DInt .DB_IOT.ALLARME_FERMO - 1668 - DBD1668 + 1356 + DBD1356 DInt .DB_IOT.WARNING_ATTIVO (che compromette produzione) - 1672 - DBD1672 + 1360 + DBD1360 Int .DB_IOT.STATO_OPERATIVO (Semaforo) - 1676 - DBW1676 + 1364 + DBW1364 Int .DB_IOT.MODO_OPERATIVO (Prod,Simula,Man, ecc) - 1678 - DBW1678 + 1366 + DBW1366 DInt .DB_IOT.ALARM_STOP_NO - 1680 - DBD1680 + 1368 + DBD1368 DInt PIECES_TOT - 1684 - DBD1684 + 1372 + DBD1372 DInt PIECES_OK - 1688 - DBD1688 + 1376 + DBD1376 DInt PIECES_KO_1 - 1692 - DBD1692 + 1380 + DBD1380 DInt PIECES_KO_2 - 1696 - DBD1696 + 1384 + DBD1384 DInt PIECES_KO_3 - 1700 - DBD1700 + 1388 + DBD1388 DInt PIECES_KO_4 - 1704 - DBD1704 + 1392 + DBD1392 DInt PIECES_KO_5 - 1708 - DBD1708 + 1396 + DBD1396 DInt PIECES_KO_6 - 1712 - DBD1712 + 1400 + DBD1400 DInt PIECES_KO_7 - 1716 - DBD1716 + 1404 + DBD1404 DInt PIECES_KO_8 - 1720 - DBD1720 + 1408 + DBD1408 DInt PIECES_KO_9 - 1724 - DBD1724 + 1412 + DBD1412 DInt PIECES_KO_10 - 1728 - DBD1728 + 1416 + DBD1416 DInt T_ALARM_HOURS - 1732 - DBD1732 + 1420 + DBD1420 DInt T_DRY_CYCLE_HOURS - 1736 - DBD1736 + 1424 + DBD1424 DInt T_POWERED_HOURS - 1740 - DBD1740 + 1428 + DBD1428 DInt T_PRODUCT_100_HOURS - 1744 - DBD1744 + 1432 + DBD1432 DInt T_PRODUCT_0_HOURS - 1748 - DBD1748 + 1436 + DBD1436 DInt T_STOP_HOURS - 1752 - DBD1752 + 1440 + DBD1440 Int T_ALARM_MINUTES - 1756 - DBW1756 + 1444 + DBW1444 Int T_DRY_CYCLE_MINUTES - 1758 - DBW1758 + 1446 + DBW1446 Int T_POWERED_MINUTES - 1760 - DBW1760 + 1448 + DBW1448 Int T_PRODUCT_100_MINUTES - 1762 - DBW1762 + 1450 + DBW1450 Int T_PRODUCT_0_MINUTES - 1764 - DBW1764 + 1452 + DBW1452 Int T_STOP_MINUTES - 1766 - DBW1766 + 1454 + DBW1454 @@ -542,183 +542,183 @@ DInt .DB_IOT.STATO_MACCHINA - 1664 - DBD1664 + 1456 + DBD1456 DInt .DB_IOT.ALLARME_FERMO - 1668 - DBD1668 + 1460 + DBD1460 DInt .DB_IOT.WARNING_ATTIVO (che compromette produzione) - 1672 - DBD1672 + 1464 + DBD1464 Int .DB_IOT.STATO_OPERATIVO (Semaforo) - 1676 - DBW1676 + 1468 + DBW1468 Int .DB_IOT.MODO_OPERATIVO (Prod,Simula,Man, ecc) - 1678 - DBW1678 + 1470 + DBW1470 DInt .DB_IOT.ALARM_STOP_NO - 1680 - DBD1680 + 1472 + DBD1472 DInt PIECES_TOT - 1684 - DBD1684 + 1476 + DBD1476 DInt PIECES_OK - 1688 - DBD1688 + 1480 + DBD1480 DInt PIECES_KO_1 - 1692 - DBD1692 + 1484 + DBD1484 DInt PIECES_KO_2 - 1696 - DBD1696 + 1488 + DBD1488 DInt PIECES_KO_3 - 1700 - DBD1700 + 1492 + DBD1492 DInt PIECES_KO_4 - 1704 - DBD1704 + 1496 + DBD1496 DInt PIECES_KO_5 - 1708 - DBD1708 + 1500 + DBD1500 DInt PIECES_KO_6 - 1712 - DBD1712 + 1504 + DBD1504 DInt PIECES_KO_7 - 1716 - DBD1716 + 1508 + DBD1508 DInt PIECES_KO_8 - 1720 - DBD1720 + 1512 + DBD1512 DInt PIECES_KO_9 - 1724 - DBD1724 + 1516 + DBD1516 DInt PIECES_KO_10 - 1728 - DBD1728 + 1520 + DBD1520 DInt T_ALARM_HOURS - 1732 - DBD1732 + 1524 + DBD1524 DInt T_DRY_CYCLE_HOURS - 1736 - DBD1736 + 1528 + DBD1528 DInt T_POWERED_HOURS - 1740 - DBD1740 + 1532 + DBD1532 DInt T_PRODUCT_100_HOURS - 1744 - DBD1744 + 1536 + DBD1536 DInt T_PRODUCT_0_HOURS - 1748 - DBD1748 + 1540 + DBD1540 DInt T_STOP_HOURS - 1752 - DBD1752 + 1544 + DBD1544 Int T_ALARM_MINUTES - 1756 - DBW1756 + 1548 + DBW1548 Int T_DRY_CYCLE_MINUTES - 1758 - DBW1758 + 1550 + DBW1550 Int T_POWERED_MINUTES - 1760 - DBW1760 + 1552 + DBW1552 Int T_PRODUCT_100_MINUTES - 1762 - DBW1762 + 1554 + DBW1554 Int T_PRODUCT_0_MINUTES - 1764 - DBW1764 + 1556 + DBW1556 Int T_STOP_MINUTES - 1766 - DBW1766 + 1558 + DBW1558 @@ -734,183 +734,183 @@ DInt .DB_IOT.STATO_MACCHINA - 1664 - DBD1664 + 1560 + DBD1560 DInt .DB_IOT.ALLARME_FERMO - 1668 - DBD1668 + 1564 + DBD1564 DInt .DB_IOT.WARNING_ATTIVO (che compromette produzione) - 1672 - DBD1672 + 1568 + DBD1568 Int .DB_IOT.STATO_OPERATIVO (Semaforo) - 1676 - DBW1676 + 1572 + DBW1572 Int .DB_IOT.MODO_OPERATIVO (Prod,Simula,Man, ecc) - 1678 - DBW1678 + 1574 + DBW1574 DInt .DB_IOT.ALARM_STOP_NO - 1680 - DBD1680 + 1576 + DBD1576 DInt PIECES_TOT - 1684 - DBD1684 + 1580 + DBD1580 DInt PIECES_OK - 1688 - DBD1688 + 1584 + DBD1584 DInt PIECES_KO_1 - 1692 - DBD1692 + 1588 + DBD1588 DInt PIECES_KO_2 - 1696 - DBD1696 + 1592 + DBD1592 DInt PIECES_KO_3 - 1700 - DBD1700 + 1596 + DBD1596 DInt PIECES_KO_4 - 1704 - DBD1704 + 1600 + DBD1600 DInt PIECES_KO_5 - 1708 - DBD1708 + 1604 + DBD1604 DInt PIECES_KO_6 - 1712 - DBD1712 + 1608 + DBD1608 DInt PIECES_KO_7 - 1716 - DBD1716 + 1612 + DBD1612 DInt PIECES_KO_8 - 1720 - DBD1720 + 1616 + DBD1616 DInt PIECES_KO_9 - 1724 - DBD1724 + 1620 + DBD1620 DInt PIECES_KO_10 - 1728 - DBD1728 + 1624 + DBD1624 DInt T_ALARM_HOURS - 1732 - DBD1732 + 1628 + DBD1628 DInt T_DRY_CYCLE_HOURS - 1736 - DBD1736 + 1632 + DBD1632 DInt T_POWERED_HOURS - 1740 - DBD1740 + 1636 + DBD1636 DInt T_PRODUCT_100_HOURS - 1744 - DBD1744 + 1640 + DBD1640 DInt T_PRODUCT_0_HOURS - 1748 - DBD1748 + 1644 + DBD1644 DInt T_STOP_HOURS - 1752 - DBD1752 + 1648 + DBD1648 Int T_ALARM_MINUTES - 1756 - DBW1756 + 1652 + DBW1652 Int T_DRY_CYCLE_MINUTES - 1758 - DBW1758 + 1654 + DBW1654 Int T_POWERED_MINUTES - 1760 - DBW1760 + 1656 + DBW1656 Int T_PRODUCT_100_MINUTES - 1762 - DBW1762 + 1658 + DBW1658 Int T_PRODUCT_0_MINUTES - 1764 - DBW1764 + 1660 + DBW1660 Int T_STOP_MINUTES - 1766 - DBW1766 + 1662 + DBW1662 diff --git a/DB_to_Excel.py b/DB_to_Excel.py index 334865a..a4eb88c 100644 --- a/DB_to_Excel.py +++ b/DB_to_Excel.py @@ -158,11 +158,6 @@ if __name__ == "__main__": expand_dbs(udt_json, db_json) # Expand DBs with UDT definitions - for db_name, db_content in db_json.items(): - calculate_offsets( - db_content - ) # Calculate offsets including special handling for Bool and String - # Display the expanded DBs as a table df = display_as_table(db_json) save_dataframe_to_file(df) # Save the DataFrame to a CSV file diff --git a/ExpandDB.py b/ExpandDB.py index 1b310f1..5d49447 100644 --- a/ExpandDB.py +++ b/ExpandDB.py @@ -1,6 +1,15 @@ import re import json import pandas as pd +import pprint +from copy import deepcopy + + +def debug_print_db_struct(db_struct): + pprint.pprint( + db_struct, width=80, indent=2 + ) # Ajusta el parámetro 'width' según necesidad + def expand_udt_references(db_struct, udts): """ @@ -17,11 +26,9 @@ def expand_udt_references(db_struct, udts): '"' ) # Remove quotes which may wrap UDT names with spaces if type_name in udts: - # Replace the UDT reference with its definition, if it exists - db_struct["fields"] = udts[ - type_name - ].copy() # Assume structure to insert is under 'fields' - print(f"Expanded UDT '{type_name}' at field '{key}' ") + # Replace the UDT reference with its deeply copied definition + db_struct["fields"] = deepcopy(udts[type_name]) + print(f"Expanded UDT '{type_name}' at field '{key}'") elif isinstance(db_struct, list): for item in db_struct: expand_udt_references(item, udts) @@ -38,21 +45,27 @@ def handle_array_types(db_struct): # Recursively process nested dictionaries handle_array_types(value) - if isinstance(value, dict) and 'type' in value: - match = re.match(r"Array\[(\d+)\.\.(\d+)\] of (\w+)", value['type']) + 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) - comment = value.get('comment', '') + 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 + value["Array"] = ( + {} + ) # Initialize a sub-dictionary for array elements for i in range(lower_bound, upper_bound + 1): element_key = f"[{i}]" - value['Array'][element_key] = { - 'type': base_type, - 'comment': comment, - 'is_array_element': True + value["Array"][element_key] = { + "type": base_type, + "comment": comment, + "is_array_element": True, } # Optionally, modify or remove the original type designation if necessary @@ -63,9 +76,6 @@ def handle_array_types(db_struct): handle_array_types(value) - - - type_sizes = { "Int": 2, "DInt": 4, @@ -80,9 +90,7 @@ 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 - ) + 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 @@ -95,63 +103,74 @@ def calculate_plc_address(type_name, byte_offset, bit_offset=None): 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): +def calculate_offsets(db_struct, current_offset=0): """ Recursively calculate byte offsets for each field in the DB structure considering special types. """ + is_array_element = False 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): - if "type" in value: - type_name = value["type"] - is_array_element = value.get('is_array_element', False) - size = type_sizes.get( - type_name, 0 - ) # Default to 1 byte if type is not recognized + for key, value in db_struct.items(): + # Skip 'fields' and 'Struct' keys in the name path + # + if ( + isinstance(value, dict) and "type" in value + ): # Directly a field with 'type' + type_name = value["type"] + is_array_element = value.get("is_array_element", False) + size = type_sizes.get( + type_name, 0 + ) # Default to 1 byte if type is not recognized - 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 + 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 + ) - 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 - else: - size = type_sizes.get(type_name, 1) # Default to generic size if not an array - - # Adjusting Bool sizes based on grouping - if type_name == "Bool": - if last_key_was_bool: # This is a grouped bool - 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 + # 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 else: - last_key_was_bool = False + size = type_sizes.get( + type_name, 1 + ) # Default to generic size if not an array - value["offset"] = current_offset - value['plc_address'] = plc_address # Store the calculated PLC address - current_offset += size + # Adjusting Bool sizes based on grouping + if type_name == "Bool": + if last_key_was_bool: # This is a grouped bool + 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 - current_offset = calculate_offsets( - value, current_offset, value - ) # Recurse into nested structs + value["offset"] = current_offset + value["plc_address"] = plc_address # Store the calculated PLC address + print(f"Offset '{current_offset}' at field '{key}' ") + current_offset += size + + # Recursively handle nested dictionaries and lists + if isinstance(value, dict) or isinstance(value, list): + current_offset = calculate_offsets(value, current_offset) elif isinstance(db_struct, list): - for item in db_struct: - current_offset = calculate_offsets(item, current_offset, parent) + for index, item in enumerate(db_struct): + for item in db_struct: + current_offset = calculate_offsets(item, current_offset) + return current_offset @@ -164,4 +183,5 @@ def expand_dbs(udts, dbs): expand_udt_references(db_content, udts) handle_array_types(db_content) calculate_offsets(db_content) + debug_print_db_struct(db_content) print(f"Completed expansion for DB: {db_name}") diff --git a/__pycache__/ExpandDB.cpython-310.pyc b/__pycache__/ExpandDB.cpython-310.pyc index 3f4e7961df603e6f4a8f6bbe7750590661e1db1a..6376c1a0b3a285a90faee3df3ba5f844d6fd678e 100644 GIT binary patch delta 1851 zcmZ8iO>7%Q6rP!#9j|xSj`LgErj@0%b=*j8r6NFWL24TW2q{HsCBURIY2K!F<2df@ zrZmy4jFjFg1l5WI&`Jph5E2(u_0EkOa6?)o?m2PdlBx~wjZ+BNns49En|bfeoAgYzXZU+CaBQJ-_LKHTzoA5@`%AetD>0mRwLNm-CT@T z{~z)(Tyqph{31d>WKRr<3I-jDkbB&J8oENNogo==Ap{D#dBj8c~z$1_aEfKZ| z^kIa$%AL15k3LlaKYtqEXBy7*h4*rPf}R)bVv^p~r%*}K^qM$v3h&xaR=ZI%ZmmVJ zo+3k1k7vIZCWAeR&dT0_-utMu6%_;V`-n3XS+&?tlXN%^e-gFHvgX_k=c zaZ)l!9ZXmm6BefUhH@b-;TCjaw|sx=8`@N_WIq<;o~>=FH(La@STt4M+Q8)mNqv3x zgUMN#s?T24R5w?0wY;zpM@b%Z+w;vi03F5gns>=gR%?2Iwu)M{Ufx3sYAm*T^h+dB zG3Xk>BtypNI*G>#ULY9Ge(}d@c`@p&EJb=QiO?3YDKF2jXpNj}_CwGVbtZ$Oy?<#o zPU|Fwf0l=bd;dL5?nigJa~;55 z8~=c7;|fAWmMt6m+?3mT8Yk-NgNDQ};cqU84fYTNhy I!SId00bF@_sQ>@~ delta 1552 zcmZWp&2Jk;6rY(L&yIK3j_al=Y0|_YEs4uV1geCDLQ&d)S_uWIAQ2gm<#;yK#I?=r zrXta-Tq)%WDvN}Ws>nG3=ZHi90*-J)S~&KSGdEBZ-WwYc#IEKyZ+70-{^q^;>Ee%5 z#crYC5qMg+FK-@BKP*nu+Qa9kZ!zUOAT_SI%E6pdLb;_@*mKetInuE z6+n`zsK!7$ujsp^T0TOzYw4Hto@c1xlVso?ki#+d94+q#3zbG(*=&VvRaw|&3zhUO z=gkWlZ+3e-S+1vBowzEpyxOQovEFXR>Ao}1e;|51ou@0yIuD+6FrpU#yxchTXu!&p zQ%3oTbQoilop2_OCmeR4|KSxS4Jbe6ROb&l|CLgf{+_$Sj#w(ir6mSV^dvx5YDM*i z){UKd*beW8op`P4YYe0Xf{P&255()GB8nx1GYE6(_oCXjK4`1vkF4uk;f@~1eGBJM zngy7FaVmAm%B%#*Ux6g0Q)U6RKR`=Q*|8T$3cv6KQb$XD9^i47UmJ4m3)VM>i@+oDM?vYv`H!&}}Aq4P2(b`Ir0uc1jryG5w53 zt=&++f@^e{iFVleIKHFL;+IoZiOZ`18!)1E04z+8V$(}_p|SBjDRBvN!0b0Bo#FQ) zXa#IhI%vWfrvgw~CB{HLf#wq4Q%Q?ptgohzgNwztA%>v?a)3uMn?4Da(y78%GdV3` zW5@~Uah>tRIKHC)>q@T$q=^4+f5Zim;3QDSVEJ#c$u-3Q