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 4f79177..f1043f2 100644
Binary files a/DB_Structure.xlsx and b/DB_Structure.xlsx differ
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 3f4e796..6376c1a 100644
Binary files a/__pycache__/ExpandDB.cpython-310.pyc and b/__pycache__/ExpandDB.cpython-310.pyc differ