antes de eliminar las estructuras de Begin block de los json

This commit is contained in:
Miguel 2025-05-18 01:04:24 +02:00
parent 00f3b6d2ec
commit e85c0c169d
4 changed files with 986 additions and 423 deletions

View File

@ -1,9 +1,9 @@
--- Log de Ejecución: x4.py ---
Grupo: S7_DB_Utils
Directorio de Trabajo: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001
Inicio: 2025-05-17 21:37:42
Fin: 2025-05-17 21:37:42
Duración: 0:00:00.131741
Inicio: 2025-05-18 00:51:35
Fin: 2025-05-18 00:51:35
Duración: 0:00:00.110751
Estado: SUCCESS (Código de Salida: 0)
--- SALIDA ESTÁNDAR (STDOUT) ---
@ -23,11 +23,11 @@ INFO: Usando '_begin_block_assignments_ordered' para generar bloque BEGIN de DB
Archivo S7 reconstruido generado: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\documentation\db1001_format.txt
Archivo Markdown de documentación generado: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\documentation\db1001_format.md
--- Procesando archivo JSON: db1001_format_updated.json ---
Archivo JSON 'db1001_format_updated.json' cargado correctamente.
--- Procesando archivo JSON: db1001_updated.json ---
Archivo JSON 'db1001_updated.json' cargado correctamente.
INFO: Usando '_begin_block_assignments_ordered' para generar bloque BEGIN de DB 'HMI_Blender_Parameters'.
Archivo S7 reconstruido generado: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\documentation\db1001_format_updated.txt
Archivo Markdown de documentación generado: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\documentation\db1001_format_updated.md
Archivo S7 reconstruido generado: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\documentation\db1001_updated.txt
Archivo Markdown de documentación generado: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\documentation\db1001_updated.md
--- Proceso de generación de documentación completado ---

View File

@ -1,28 +1,309 @@
--- Log de Ejecución: x7_value_updater.py ---
Grupo: S7_DB_Utils
Directorio de Trabajo: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001
Inicio: 2025-05-17 23:48:43
Fin: 2025-05-17 23:48:43
Duración: 0:00:00.106052
Inicio: 2025-05-18 00:51:17
Fin: 2025-05-18 00:51:18
Duración: 0:00:00.223903
Estado: SUCCESS (Código de Salida: 0)
--- SALIDA ESTÁNDAR (STDOUT) ---
Using working directory: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001
Found _data file: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_data.db
Found _format file: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_format.db
Parsing S7 file: db1001_data.db...
Serializing to JSON: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\json\db1001_data_data.json
JSON saved: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\json\db1001_data_data.json
Parsing S7 file: db1001_format.db...
Serializing to JSON: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\json\db1001_format_format.json
JSON saved: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\json\db1001_format_format.json
Comparing structure of DB: HMI_Blender_Parameters
La estructura del DB 'HMI_Blender_Parameters' es compatible.
Los archivos JSON se guardarán en: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\json
Se encontraron 1 pares de archivos para procesar.
All DB structures are compatible. Proceeding to generate _updated file.
INFO: Usando '_begin_block_assignments_ordered' para generar bloque BEGIN de DB 'HMI_Blender_Parameters'.
--- Procesando par de archivos ---
Data file: db1001_data.db
Format file: db1001_format.db
Parseando archivo data: db1001_data.db
Parseando archivo format: db1001_format.db
Archivos JSON generados: db1001_data.json y db1001_format.json
Aplanando variables por offset...
Comparando estructuras: 251 variables en _data, 251 variables en _format
Successfully generated _updated S7 file: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_updated.db
Los archivos son compatibles. Creando el archivo _updated...
Mapeando STAT0.STAT1.STAT2 -> Processor_Options.Blender_OPT._ModelNum (offset 0.0)
Mapeando STAT0.STAT1.STAT3 -> Processor_Options.Blender_OPT._CO2_Offset (offset 2.0)
Mapeando STAT0.STAT1.STAT4 -> Processor_Options.Blender_OPT._MaxSyrDeltaBrix (offset 6.0)
Mapeando STAT0.STAT1.STAT5 -> Processor_Options.Blender_OPT._BrixMeter (offset 10.0)
Mapeando STAT0.STAT1.STAT6 -> Processor_Options.Blender_OPT.Spare101 (offset 10.1)
Mapeando STAT0.STAT1.STAT7 -> Processor_Options.Blender_OPT._TrackH2OEnable (offset 10.2)
Mapeando STAT0.STAT1.STAT8 -> Processor_Options.Blender_OPT._PAmPDSType (offset 10.3)
Mapeando STAT0.STAT1.STAT9 -> Processor_Options.Blender_OPT._HistoricalTrends (offset 10.4)
Mapeando STAT0.STAT1.STAT10 -> Processor_Options.Blender_OPT._PowerMeter (offset 10.5)
Mapeando STAT0.STAT1.STAT11 -> Processor_Options.Blender_OPT._Report (offset 10.6)
Mapeando STAT0.STAT1.STAT12 -> Processor_Options.Blender_OPT._Balaiage (offset 10.7)
Mapeando STAT0.STAT1.STAT13 -> Processor_Options.Blender_OPT._Valves_FullFeedback (offset 11.0)
Mapeando STAT0.STAT1.STAT14 -> Processor_Options.Blender_OPT._Valves_SingleFeedback (offset 11.1)
Mapeando STAT0.STAT1.STAT15 -> Processor_Options.Blender_OPT._PumpsSafetySwitches (offset 11.2)
Mapeando STAT0.STAT1.STAT16 -> Processor_Options.Blender_OPT._SurgeProtectionAct (offset 11.3)
Mapeando STAT0.STAT1.STAT17 -> Processor_Options.Blender_OPT._DBC_Type (offset 11.4)
Mapeando STAT0.STAT1.STAT18 -> Processor_Options.Blender_OPT._CO2InletMeter (offset 11.5)
Mapeando STAT0.STAT1.STAT19 -> Processor_Options.Blender_OPT._ProductO2Meter (offset 11.6)
Mapeando STAT0.STAT1.STAT20 -> Processor_Options.Blender_OPT._CopressedAirInletMeter (offset 11.7)
Mapeando STAT0.STAT1.STAT21 -> Processor_Options.Blender_OPT._MeterType (offset 12.0)
Mapeando STAT0.STAT1.STAT22 -> Processor_Options.Blender_OPT._MeterReceiveOnly (offset 14.0)
Mapeando STAT0.STAT1.STAT23 -> Processor_Options.Blender_OPT._SyrBrixMeter (offset 14.1)
Mapeando STAT0.STAT1.STAT24 -> Processor_Options.Blender_OPT._Flooding_Start_Up (offset 14.2)
Mapeando STAT0.STAT1.STAT25 -> Processor_Options.Blender_OPT._FastChangeOverEnabled (offset 14.3)
Mapeando STAT0.STAT1.STAT26 -> Processor_Options.Blender_OPT._WaterInletMeter (offset 14.4)
Mapeando STAT0.STAT1.STAT27 -> Processor_Options.Blender_OPT._BlendFillSystem (offset 14.5)
Mapeando STAT0.STAT1.STAT28 -> Processor_Options.Blender_OPT._TrackFillerSpeed (offset 14.6)
Mapeando STAT0.STAT1.STAT29 -> Processor_Options.Blender_OPT._SignalExchange (offset 16.0)
Mapeando STAT0.STAT1.STAT30 -> Processor_Options.Blender_OPT._CoolerPresent (offset 18.0)
Mapeando STAT0.STAT1.STAT31 -> Processor_Options.Blender_OPT._CoolerControl (offset 20.0)
Mapeando STAT0.STAT1.STAT32 -> Processor_Options.Blender_OPT._CoolerType (offset 22.0)
Mapeando STAT0.STAT1.STAT33 -> Processor_Options.Blender_OPT._LocalCIP (offset 24.0)
Mapeando STAT0.STAT1.STAT34 -> Processor_Options.Blender_OPT._ICS_CustomerHotWater (offset 24.1)
Mapeando STAT0.STAT1.STAT35 -> Processor_Options.Blender_OPT._ICS_CustomerChemRecov (offset 24.2)
Mapeando STAT0.STAT1.STAT36 -> Processor_Options.Blender_OPT._CIPSignalExchange (offset 24.3)
Mapeando STAT0.STAT1.STAT37 -> Processor_Options.Blender_OPT._ICS_CustomerChemicals (offset 24.4)
Mapeando STAT0.STAT1.STAT38 -> Processor_Options.Blender_OPT._CarboPresent (offset 24.5)
Mapeando STAT0.STAT1.STAT39 -> Processor_Options.Blender_OPT._InverterSyrupPumpPPP302 (offset 24.6)
Mapeando STAT0.STAT1.STAT40 -> Processor_Options.Blender_OPT._InverterWaterPumpPPN301 (offset 24.7)
Mapeando STAT0.STAT1.STAT41 -> Processor_Options.Blender_OPT._DoubleDeair (offset 25.0)
Mapeando STAT0.STAT1.STAT42 -> Processor_Options.Blender_OPT._DeairPreMixed (offset 25.1)
Mapeando STAT0.STAT1.STAT43 -> Processor_Options.Blender_OPT._Deaireation (offset 25.2)
Mapeando STAT0.STAT1.STAT44 -> Processor_Options.Blender_OPT._StillWaterByPass (offset 25.3)
Mapeando STAT0.STAT1.STAT45 -> Processor_Options.Blender_OPT._ManifoldSetting (offset 25.4)
Mapeando STAT0.STAT1.STAT46 -> Processor_Options.Blender_OPT._InverterProdPumpPPM303 (offset 25.5)
Mapeando STAT0.STAT1.STAT47 -> Processor_Options.Blender_OPT._SidelCip (offset 25.6)
Mapeando STAT0.STAT1.STAT48 -> Processor_Options.Blender_OPT._EthernetCom_CpuPN_CP (offset 25.7)
Mapeando STAT0.STAT1.STAT49 -> Processor_Options.Blender_OPT._2ndOutlet (offset 26.0)
Mapeando STAT0.STAT1.STAT50 -> Processor_Options.Blender_OPT._Promass (offset 28.0)
Mapeando STAT0.STAT1.STAT51 -> Processor_Options.Blender_OPT._WaterPromass (offset 30.0)
Mapeando STAT0.STAT1.STAT52 -> Processor_Options.Blender_OPT._ProductConductimeter (offset 30.1)
Mapeando STAT0.STAT1.STAT53 -> Processor_Options.Blender_OPT._ICS_CustomerH2ORecov (offset 30.2)
Mapeando STAT0.STAT1.STAT54 -> Processor_Options.Blender_OPT.Spare303 (offset 30.3)
Mapeando STAT0.STAT1.STAT55 -> Processor_Options.Blender_OPT._CO2_GAS2_Injection (offset 30.4)
Mapeando STAT0.STAT1.STAT56 -> Processor_Options.Blender_OPT._InverterVacuuPumpPPN304 (offset 30.5)
Mapeando STAT0.STAT1.STAT57 -> Processor_Options.Blender_OPT._InverterBoostPumpPPM307 (offset 30.6)
Mapeando STAT0.STAT1.STAT58 -> Processor_Options.Blender_OPT._RunOut_Water (offset 30.7)
Mapeando STAT0.STAT1.STAT59 -> Processor_Options.Blender_OPT._FlowMeterType (offset 31.0)
Mapeando STAT0.STAT1.STAT60 -> Processor_Options.Blender_OPT._SidelFiller (offset 31.1)
Mapeando STAT0.STAT1.STAT61 -> Processor_Options.Blender_OPT._Simulation (offset 31.2)
Mapeando STAT0.STAT1.STAT62 -> Processor_Options.Blender_OPT._ProductCoolingCTRL (offset 31.3)
Mapeando STAT0.STAT1.STAT63 -> Processor_Options.Blender_OPT._ChillerCTRL (offset 31.4)
Mapeando STAT0.STAT1.STAT64 -> Processor_Options.Blender_OPT._CO2_SterileFilter (offset 31.5)
Mapeando STAT0.STAT1.STAT65 -> Processor_Options.Blender_OPT._InverterRecirPumpPPM306 (offset 31.6)
Mapeando STAT0.STAT1.STAT66 -> Processor_Options.Blender_OPT._ProdPressReleaseRVM304 (offset 31.7)
Mapeando STAT0.STAT1.STAT67 -> Processor_Options.Blender_OPT._VacuumPump (offset 32.0)
Mapeando STAT0.STAT1.STAT68 -> Processor_Options.Blender_OPT._GAS2InjectionType (offset 34.0)
Mapeando STAT0.STAT1.STAT69 -> Processor_Options.Blender_OPT._InjectionPress_Ctrl (offset 36.0)
Mapeando STAT0.STAT1.STAT70 -> Processor_Options.Blender_OPT._ProdPressureType (offset 38.0)
Mapeando STAT0.STAT1.STAT71 -> Processor_Options.Blender_OPT._CIPHeatType (offset 40.0)
Mapeando STAT0.STAT1.STAT72 -> Processor_Options.Blender_OPT._EHS_NrRes (offset 42.0)
Mapeando STAT73[1] -> Spare1 (offset 44.0)
Mapeando STAT73[2] -> Spare1 (offset 44.0)
Mapeando STAT73[3] -> Spare1 (offset 44.0)
Mapeando STAT73[4] -> Spare1 (offset 44.0)
Mapeando STAT73[5] -> Spare1 (offset 44.0)
Mapeando STAT73[6] -> Spare1 (offset 44.0)
Mapeando STAT73[7] -> Spare1 (offset 44.0)
Mapeando STAT73[8] -> Spare1 (offset 44.0)
Mapeando STAT73[9] -> Spare1 (offset 44.0)
Mapeando STAT74 -> _RVM301_DeadBand (offset 62.0)
Mapeando STAT75 -> _RVM301_Kp (offset 66.0)
Mapeando STAT76.STAT77 -> Actual_Recipe_Parameters._Name (offset 70.0)
Mapeando STAT76.STAT78 -> Actual_Recipe_Parameters._EnProdTemp (offset 104.0)
Mapeando STAT76.STAT79 -> Actual_Recipe_Parameters._SyrFlushing (offset 104.1)
Mapeando STAT76.STAT80 -> Actual_Recipe_Parameters._GAS2_Injection (offset 104.2)
Mapeando STAT76.STAT81 -> Actual_Recipe_Parameters._Eq_Pression_Selected (offset 104.3)
Mapeando STAT76.STAT82 -> Actual_Recipe_Parameters._DeoxStripEn (offset 104.4)
Mapeando STAT76.STAT83 -> Actual_Recipe_Parameters._DeoxVacuumEn (offset 104.5)
Mapeando STAT76.STAT84 -> Actual_Recipe_Parameters._DeoxPreMixed (offset 104.6)
Mapeando STAT76.STAT85 -> Actual_Recipe_Parameters._EnBlowOffProdPipeCO2Fil (offset 104.7)
Mapeando STAT76.STAT86 -> Actual_Recipe_Parameters._WaterSelection (offset 105.0)
Mapeando STAT76.STAT87 -> Actual_Recipe_Parameters._FillerNextRecipeNum (offset 106.0)
Mapeando STAT76.STAT88 -> Actual_Recipe_Parameters._BottleShape (offset 107.0)
Mapeando STAT76.STAT89 -> Actual_Recipe_Parameters._Type (offset 108.0)
Mapeando STAT76.STAT90 -> Actual_Recipe_Parameters._ProdMeterRecipeNum (offset 110.0)
Mapeando STAT76.STAT91 -> Actual_Recipe_Parameters._SyrupBrix (offset 112.0)
Mapeando STAT76.STAT92 -> Actual_Recipe_Parameters._SyrupDensity (offset 116.0)
Mapeando STAT76.STAT93 -> Actual_Recipe_Parameters._SyrupFactor (offset 120.0)
Mapeando STAT76.STAT94 -> Actual_Recipe_Parameters._ProductBrix (offset 124.0)
Mapeando STAT76.STAT95 -> Actual_Recipe_Parameters._ProductionRate (offset 128.0)
Mapeando STAT76.STAT96 -> Actual_Recipe_Parameters._Ratio (offset 132.0)
Mapeando STAT76.STAT97 -> Actual_Recipe_Parameters._ProdBrixOffset (offset 136.0)
Mapeando STAT76.STAT98 -> Actual_Recipe_Parameters._CO2Vols (offset 140.0)
Mapeando STAT76.STAT99 -> Actual_Recipe_Parameters._CO2Fact (offset 144.0)
Mapeando STAT76.STAT100 -> Actual_Recipe_Parameters._ProdTankPress (offset 148.0)
Mapeando STAT76.STAT101 -> Actual_Recipe_Parameters._SP_ProdTemp (offset 152.0)
Mapeando STAT76.STAT102 -> Actual_Recipe_Parameters._PrdTankMinLevel (offset 156.0)
Mapeando STAT76.STAT103 -> Actual_Recipe_Parameters._WaterValveSave (offset 160.0)
Mapeando STAT76.STAT104 -> Actual_Recipe_Parameters._SyrupValveSave (offset 164.0)
Mapeando STAT76.STAT105 -> Actual_Recipe_Parameters._CarboCO2ValveSave (offset 168.0)
Mapeando STAT76.STAT106 -> Actual_Recipe_Parameters._ProdMeterHighBrix (offset 172.0)
Mapeando STAT76.STAT107 -> Actual_Recipe_Parameters._ProdMeterLowBrix (offset 176.0)
Mapeando STAT76.STAT108 -> Actual_Recipe_Parameters._ProdMeterHighCO2 (offset 180.0)
Mapeando STAT76.STAT109 -> Actual_Recipe_Parameters._ProdMeterLowCO2 (offset 184.0)
Mapeando STAT76.STAT110 -> Actual_Recipe_Parameters._ProdMeter_ZeroCO2 (offset 188.0)
Mapeando STAT76.STAT111 -> Actual_Recipe_Parameters._ProdMeter_ZeroBrix (offset 192.0)
Mapeando STAT76.STAT112 -> Actual_Recipe_Parameters._ProdHighCond (offset 196.0)
Mapeando STAT76.STAT113 -> Actual_Recipe_Parameters._ProdLowCond (offset 200.0)
Mapeando STAT76.STAT114 -> Actual_Recipe_Parameters._BottleSize (offset 204.0)
Mapeando STAT76.STAT115 -> Actual_Recipe_Parameters._FillingValveHead_SP (offset 208.0)
Mapeando STAT76.STAT116 -> Actual_Recipe_Parameters._SyrMeter_ZeroBrix (offset 212.0)
Mapeando STAT76.STAT117 -> Actual_Recipe_Parameters._FirstProdExtraCO2Fact (offset 216.0)
Mapeando STAT76.STAT118 -> Actual_Recipe_Parameters._Gas2Vols (offset 220.0)
Mapeando STAT76.STAT119 -> Actual_Recipe_Parameters._Gas2Fact (offset 224.0)
Mapeando STAT76.STAT120 -> Actual_Recipe_Parameters._SyrupPumpPressure (offset 228.0)
Mapeando STAT76.STAT121 -> Actual_Recipe_Parameters._WaterPumpPressure (offset 232.0)
Mapeando STAT76.STAT122 -> Actual_Recipe_Parameters._CO2_Air_N2_PressSelect (offset 236.0)
Mapeando STAT76.STAT123 -> Actual_Recipe_Parameters._KFactRVM304BlowOff (offset 238.0)
Mapeando STAT76.STAT124 -> Actual_Recipe_Parameters._ProdRecircPumpFreq (offset 242.0)
Mapeando STAT76.STAT125 -> Actual_Recipe_Parameters._ProdBoosterPumpPress (offset 246.0)
Mapeando STAT76.STAT126 -> Actual_Recipe_Parameters._ProdSendPumpFreq (offset 250.0)
Mapeando STAT127[1] -> Spare2 (offset 254.0)
Mapeando STAT127[2] -> Spare2 (offset 254.0)
Mapeando STAT127[3] -> Spare2 (offset 254.0)
Mapeando STAT127[4] -> Spare2 (offset 254.0)
Mapeando STAT127[5] -> Spare2 (offset 254.0)
Mapeando STAT128 -> Next_Recipe_Name (offset 264.0)
Mapeando STAT129 -> Next_Recipe_Number (offset 298.0)
Mapeando STAT130[1] -> Spare3 (offset 300.0)
Mapeando STAT130[2] -> Spare3 (offset 300.0)
Mapeando STAT130[3] -> Spare3 (offset 300.0)
Mapeando STAT130[4] -> Spare3 (offset 300.0)
Mapeando STAT130[5] -> Spare3 (offset 300.0)
Mapeando STAT130[6] -> Spare3 (offset 300.0)
Mapeando STAT130[7] -> Spare3 (offset 300.0)
Mapeando STAT130[8] -> Spare3 (offset 300.0)
Mapeando STAT130[9] -> Spare3 (offset 300.0)
Mapeando STAT130[10] -> Spare3 (offset 300.0)
Mapeando STAT130[11] -> Spare3 (offset 300.0)
Mapeando STAT130[12] -> Spare3 (offset 300.0)
Mapeando STAT130[13] -> Spare3 (offset 300.0)
Mapeando STAT130[14] -> Spare3 (offset 300.0)
Mapeando STAT130[15] -> Spare3 (offset 300.0)
Mapeando STAT130[16] -> Spare3 (offset 300.0)
Mapeando STAT130[17] -> Spare3 (offset 300.0)
Mapeando STAT130[18] -> Spare3 (offset 300.0)
Mapeando STAT131.STAT132 -> ProcessSetup.Spare000 (offset 336.0)
Mapeando STAT131.STAT133 -> ProcessSetup.Spare040 (offset 340.0)
Mapeando STAT131.STAT134 -> ProcessSetup._KWaterLoss (offset 344.0)
Mapeando STAT131.STAT135 -> ProcessSetup._KSyrupLoss (offset 348.0)
Mapeando STAT131.STAT136 -> ProcessSetup._KProdLoss (offset 352.0)
Mapeando STAT131.STAT137 -> ProcessSetup._KPPM303 (offset 356.0)
Mapeando STAT131.STAT138 -> ProcessSetup._BaialageRVM301OVMin (offset 360.0)
Mapeando STAT131.STAT139 -> ProcessSetup._SyrupLinePressure (offset 364.0)
Mapeando STAT131.STAT140 -> ProcessSetup._CIPRMM301OV (offset 368.0)
Mapeando STAT131.STAT141 -> ProcessSetup._CIPRMP302OV (offset 372.0)
Mapeando STAT131.STAT142 -> ProcessSetup._CIPTM301MinLevel (offset 376.0)
Mapeando STAT131.STAT143 -> ProcessSetup._CIPTM301MaxLevel (offset 380.0)
Mapeando STAT131.STAT144 -> ProcessSetup._CIPPPM303Freq (offset 384.0)
Mapeando STAT131.STAT145 -> ProcessSetup._CIPTP301MinLevel (offset 388.0)
Mapeando STAT131.STAT146 -> ProcessSetup._CIPTP301MaxLevel (offset 392.0)
Mapeando STAT131.STAT147 -> ProcessSetup._RinseRMM301OV (offset 396.0)
Mapeando STAT131.STAT148 -> ProcessSetup._RinseRMP302OV (offset 400.0)
Mapeando STAT131.STAT149 -> ProcessSetup._RinseTM301Press (offset 404.0)
Mapeando STAT131.STAT150 -> ProcessSetup._RinsePPM303Freq (offset 408.0)
Mapeando STAT131.STAT151 -> ProcessSetup._DrainTM301Press (offset 412.0)
Mapeando STAT131.STAT152 -> ProcessSetup._KRecBlendError (offset 416.0)
Mapeando STAT131.STAT153 -> ProcessSetup._KRecCarboCO2Error (offset 420.0)
Mapeando STAT131.STAT154 -> ProcessSetup._MaxBlendError (offset 424.0)
Mapeando STAT131.STAT155 -> ProcessSetup._MaxCarboCO2Error (offset 428.0)
Mapeando STAT131.STAT156 -> ProcessSetup._StartUpBrixExtraWater (offset 432.0)
Mapeando STAT131.STAT157 -> ProcessSetup._StartUpCO2ExtraWater (offset 436.0)
Mapeando STAT131.STAT158 -> ProcessSetup._StartUpPPM303Freq (offset 440.0)
Mapeando STAT131.STAT159 -> ProcessSetup._SyrupRoomTank (offset 444.0)
Mapeando STAT131.STAT160 -> ProcessSetup._SyrupRunOutLiters (offset 446.0)
Mapeando STAT131.STAT161 -> ProcessSetup._InjCO2Press_Offset (offset 450.0)
Mapeando STAT131.STAT162 -> ProcessSetup._InjCO2Press_MinFlow (offset 454.0)
Mapeando STAT131.STAT163 -> ProcessSetup._InjCO2Press_MaxFlow (offset 458.0)
Mapeando STAT131.STAT164 -> ProcessSetup._CarboCO2Pressure (offset 462.0)
Mapeando STAT131.STAT165 -> ProcessSetup._N2MinPressure (offset 466.0)
Mapeando STAT131.STAT166 -> ProcessSetup._DiffSensor_Height (offset 470.0)
Mapeando STAT131.STAT167 -> ProcessSetup._DiffSensor_DeltaHeight (offset 474.0)
Mapeando STAT131.STAT168 -> ProcessSetup._DiffSensor_Offset (offset 478.0)
Mapeando STAT131.STAT169 -> ProcessSetup._FillingValveHeight (offset 482.0)
Mapeando STAT131.STAT170 -> ProcessSetup._FillerDiameter (offset 486.0)
Mapeando STAT131.STAT171 -> ProcessSetup._FillingValveNum (offset 490.0)
Mapeando STAT131.STAT172 -> ProcessSetup._FillerProdPipeDN (offset 492.0)
Mapeando STAT131.STAT173 -> ProcessSetup._FillerProdPipeMass (offset 496.0)
Mapeando STAT131.STAT174 -> ProcessSetup._FillingTime (offset 500.0)
Mapeando STAT131.STAT175 -> ProcessSetup._TM301Height_0 (offset 504.0)
Mapeando STAT131.STAT176 -> ProcessSetup._TM301LevelPerc_2 (offset 508.0)
Mapeando STAT131.STAT177 -> ProcessSetup._TM301Height_2 (offset 512.0)
Mapeando STAT131.STAT178 -> ProcessSetup._RVN304Factor (offset 516.0)
Mapeando STAT131.STAT179 -> ProcessSetup._DrainTM301Flushing (offset 520.0)
Mapeando STAT131.STAT180 -> ProcessSetup._FirstProdExtraBrix (offset 524.0)
Mapeando STAT131.STAT181 -> ProcessSetup._FirstProdDietExtraSyr (offset 528.0)
Mapeando STAT131.STAT182 -> ProcessSetup._EndProdLastSyrlt (offset 532.0)
Mapeando STAT131.STAT183 -> ProcessSetup._TM301DrainSt0Time (offset 536.0)
Mapeando STAT131.STAT184 -> ProcessSetup._TM301DrainSt1Time (offset 538.0)
Mapeando STAT131.STAT185 -> ProcessSetup._ProdPipeRunOutSt0Time (offset 540.0)
Mapeando STAT131.STAT186 -> ProcessSetup._RMM301ProdPipeRunOu (offset 542.0)
Mapeando STAT131.STAT187 -> ProcessSetup._RMP302ProdPipeRunOu (offset 546.0)
Mapeando STAT131.STAT188 -> ProcessSetup._ProdPipeRunOutAmount (offset 550.0)
Mapeando STAT131.STAT189 -> ProcessSetup._TM301RunOutChiller (offset 554.0)
Mapeando STAT131.STAT190 -> ProcessSetup._MinSpeedNominalProd (offset 558.0)
Mapeando STAT131.STAT191 -> ProcessSetup._MinSpeedSlowProd (offset 562.0)
Mapeando STAT131.STAT192 -> ProcessSetup._FastChgOvrTM301DrnPrss (offset 566.0)
Mapeando STAT131.STAT193 -> ProcessSetup._CIPTN301MinLevel (offset 570.0)
Mapeando STAT131.STAT194 -> ProcessSetup._CIPTN301MaxLevel (offset 574.0)
Mapeando STAT131.STAT195 -> ProcessSetup._ProdPPN304Freq (offset 578.0)
Mapeando STAT131.STAT196 -> ProcessSetup._GAS2InjectionPress (offset 582.0)
Mapeando STAT131.STAT197 -> ProcessSetup._BaialageRVM301OVMax (offset 586.0)
Mapeando STAT131.STAT198 -> ProcessSetup._RinsePPN301Freq (offset 590.0)
Mapeando STAT131.STAT199 -> ProcessSetup._CIPPPN301Freq (offset 594.0)
Mapeando STAT131.STAT200 -> ProcessSetup._RinsePPP302Freq (offset 598.0)
Mapeando STAT131.STAT201 -> ProcessSetup._CIPPPP302Freq (offset 602.0)
Mapeando STAT131.STAT202 -> ProcessSetup._PercSyrupBrixSyrStarUp (offset 606.0)
Mapeando STAT131.STAT203 -> ProcessSetup._RefTempCoolingCTRL (offset 610.0)
Mapeando STAT131.STAT204 -> ProcessSetup._H2OSerpPrimingVolume (offset 614.0)
Mapeando STAT131.STAT205 -> ProcessSetup._AVN301_Nozzle_Kv (offset 618.0)
Mapeando STAT131.STAT206 -> ProcessSetup._AVN302_Nozzle_Kv (offset 622.0)
Mapeando STAT131.STAT207 -> ProcessSetup._AVN303_Nozzle_Kv (offset 626.0)
Mapeando STAT131.STAT208 -> ProcessSetup._DeoxSpryball_Kv (offset 630.0)
Mapeando STAT131.STAT209 -> ProcessSetup._PremixedLineDrainTime (offset 634.0)
Mapeando STAT131.STAT210 -> ProcessSetup._PPN301_H_MaxFlow (offset 636.0)
Mapeando STAT131.STAT211 -> ProcessSetup._PPN301_H_MinFlow (offset 640.0)
Mapeando STAT131.STAT212 -> ProcessSetup._PPN301_MaxFlow (offset 644.0)
Mapeando STAT131.STAT213 -> ProcessSetup._PPN301_MinFlow (offset 648.0)
Mapeando STAT131.STAT214 -> ProcessSetup._PPP302_H_MaxFlow (offset 652.0)
Mapeando STAT131.STAT215 -> ProcessSetup._PPP302_H_MinFlow (offset 656.0)
Mapeando STAT131.STAT216 -> ProcessSetup._PPP302_MaxFlow (offset 660.0)
Mapeando STAT131.STAT217 -> ProcessSetup._PPP302_MinFlow (offset 664.0)
Mapeando STAT131.STAT218 -> ProcessSetup._RinsePPM306Freq (offset 668.0)
Mapeando STAT131.STAT219 -> ProcessSetup._CIPPPM306Freq (offset 672.0)
Mapeando STAT131.STAT220 -> ProcessSetup._PPM307_H_MaxFlow (offset 676.0)
Mapeando STAT131.STAT221 -> ProcessSetup._PPM307_H_MinFlow (offset 680.0)
Mapeando STAT131.STAT222 -> ProcessSetup._PPM307_MaxFlow (offset 684.0)
Mapeando STAT131.STAT223 -> ProcessSetup._PPM307_MinFlow (offset 688.0)
Mapeando STAT131.STAT224 -> ProcessSetup._Temp0_VacuumCtrl (offset 692.0)
Mapeando STAT131.STAT225 -> ProcessSetup._Temp1_VacuumCtrl (offset 696.0)
Mapeando STAT131.STAT226 -> ProcessSetup._Temp2_VacuumCtrl (offset 700.0)
Mapeando STAT131.STAT227 -> ProcessSetup._Temp3_VacuumCtrl (offset 704.0)
Mapeando STAT131.STAT228 -> ProcessSetup._Temp4_VacuumCtrl (offset 708.0)
Mapeando STAT131.STAT229 -> ProcessSetup._T1_VacuumCtrl (offset 712.0)
Mapeando STAT131.STAT230 -> ProcessSetup._T2_VacuumCtrl (offset 716.0)
Mapeando STAT131.STAT231 -> ProcessSetup._T3_VacuumCtrl (offset 720.0)
Mapeando STAT131.STAT232 -> ProcessSetup._T4_VacuumCtrl (offset 724.0)
Mapeando STAT131.STAT233 -> ProcessSetup._ICS_VolDosWorkTimePAA (offset 728.0)
Mapeando STAT131.STAT234 -> ProcessSetup._ICS_VolPauseTimePAA (offset 730.0)
Mapeando STAT131.STAT235 -> ProcessSetup._ICS_PAAPulseWeight (offset 732.0)
Mapeando STAT131.STAT236 -> ProcessSetup._ICS_CausticPulseWeight (offset 734.0)
Mapeando STAT131.STAT237 -> ProcessSetup._ICS_AcidPulseWeight (offset 736.0)
Mapeando STAT131.STAT238 -> ProcessSetup._ICS_VolumeRestOfLine (offset 738.0)
Mapeando STAT131.STAT239 -> ProcessSetup._ICS_VolDosWorkTimeCaus (offset 742.0)
Mapeando STAT131.STAT240 -> ProcessSetup._ICS_VolDosPauseTimeCaus (offset 744.0)
Mapeando STAT131.STAT241 -> ProcessSetup._ICS_VolDosWorkTimeAcid (offset 746.0)
Mapeando STAT131.STAT242 -> ProcessSetup._ICS_VolDosPauseTimeAcid (offset 748.0)
Mapeando STAT131.STAT243 -> ProcessSetup._ICS_ConcDosWorkTimeCaus (offset 750.0)
Mapeando STAT131.STAT244 -> ProcessSetup._ICS_ConcDosPausTimeCaus (offset 752.0)
Mapeando STAT131.STAT245 -> ProcessSetup._ICS_ConcDosWorkTimeAcid (offset 754.0)
Mapeando STAT131.STAT246 -> ProcessSetup._ICS_ConcDosPausTimeAcid (offset 756.0)
Mapeando STAT131.STAT247 -> ProcessSetup._RinsePPM307Freq (offset 758.0)
Mapeando STAT131.STAT248 -> ProcessSetup._CIPPPM307Freq (offset 762.0)
Mapeando STAT131.STAT249 -> ProcessSetup._CIP2StepTN301Lvl (offset 766.0)
Mapeando STAT131.STAT250 -> ProcessSetup._CIP2StepTM301Lvl (offset 770.0)
Mapeando STAT131.STAT251 -> ProcessSetup._CIP2StepTP301Lvl (offset 774.0)
Mapeando STAT131.STAT252 -> ProcessSetup._PumpNominalFreq (offset 778.0)
Mapeando STAT253 -> _SwitchOff_DensityOK (offset 782.0)
Mapeando STAT254 -> STAT254 (offset 784.0)
Archivo _updated generado: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\json\db1001_updated.json
--- Proceso completado ---
--- ERRORES (STDERR) ---
Ninguno

View File

@ -1,413 +1,393 @@
# --- x7.py ---
import json
import os
import sys
import glob
import sys
import copy
import re
from typing import List, Dict, Optional, Tuple, Any
from typing import Dict, List, Tuple, Any, Optional
# Assuming x3.py and x4.py are in the same directory or accessible via PYTHONPATH
# Imports from x3.py
from x3 import (
S7Parser,
ParsedData, # Dataclass for top-level structure
# The following dataclasses are defined in x3.py and used by S7Parser.
# We might not need to import them explicitly if we work with dicts from JSON.
# VariableInfo, ArrayDimension, UdtInfo, DbInfo,
custom_json_serializer,
find_working_directory,
# Importar load_configuration desde backend.script_utils
script_root = os.path.dirname(
os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
)
sys.path.append(script_root)
from backend.script_utils import load_configuration
# Imports from x4.py (or reimplementations if direct import is problematic)
# These functions from x4.py work on dictionary representations of the parsed data.
from x4 import (
format_data_type_for_source,
generate_variable_declaration_for_source,
generate_struct_members_for_source,
generate_begin_block_assignments,
generate_s7_source_code_lines,
)
# Importar lo necesario desde x3.py
sys.path.append(os.path.dirname(__file__))
from x3 import S7Parser, find_working_directory, custom_json_serializer, ParsedData
# --- Helper Functions ---
def find_data_format_files(working_dir: str) -> Tuple[Optional[str], Optional[str]]:
"""Finds _data and _format files in the working directory."""
data_file: Optional[str] = None
format_file: Optional[str] = None
extensions = ["*.db", "*.awl", "*.db.txt", "*.awl.txt"]
all_s7_files = []
for ext_pattern in extensions:
all_s7_files.extend(glob.glob(os.path.join(working_dir, ext_pattern)))
# Prioritize longer extensions first for matching to avoid partial matches like .db when .db.txt exists
all_s7_files.sort(key=len, reverse=True)
for f_path in all_s7_files:
basename = os.path.basename(f_path)
# Check for _data file (and ensure it's not an _updated file from a previous run)
if "_data" in basename and "_updated" not in basename:
# More specific check to avoid matching e.g. "some_other_data_related_file"
# We expect "PREFIX_data.EXT"
name_part, _ = os.path.splitext(
basename
) # For "file.db.txt", this gives "file.db"
if name_part.endswith("_data") or basename.replace(
os.path.splitext(basename)[-1], ""
).endswith(
"_data"
): # Handles single and double extensions
if data_file is None: # Take the first one found (after sorting)
data_file = f_path
# Check for _format file
if "_format" in basename and "_updated" not in basename:
name_part, _ = os.path.splitext(basename)
if name_part.endswith("_format") or basename.replace(
os.path.splitext(basename)[-1], ""
).endswith("_format"):
if format_file is None:
format_file = f_path
if data_file:
print(f"Found _data file: {data_file}")
else:
print("Warning: No _data file found.")
if format_file:
print(f"Found _format file: {format_file}")
else:
print("Warning: No _format file found.")
return data_file, format_file
def parse_s7_to_json_file(s7_filepath: str, json_dir: str) -> Optional[str]:
"""Parses an S7 source file to JSON and saves it."""
parser = S7Parser()
filename = os.path.basename(s7_filepath)
print(f"Parsing S7 file: {filename}...")
try:
parsed_result = parser.parse_file(s7_filepath)
except Exception as e:
print(f"Error parsing {filename}: {e}")
return None
output_filename_base = os.path.splitext(filename)[0]
# Handle double extensions like .db.txt
if ".db" in output_filename_base or ".awl" in output_filename_base:
# A more robust way to get the true base name before multiple extensions
# Example: "file.db.txt" -> "file"
# Example: "file.db" -> "file"
temp_name = filename
known_exts = [
".txt",
".db",
".awl",
] # order might matter if extensions can be part of name
for k_ext in reversed(known_exts): # try removing from right to left
if temp_name.lower().endswith(k_ext):
temp_name = temp_name[: -len(k_ext)]
output_filename_base = temp_name # This is the "true" base
json_output_filename = os.path.join(
json_dir,
f"{output_filename_base}_{os.path.basename(s7_filepath).split('_', 1)[1].split('.')[0]}.json",
) # e.g. base_data.json
print(f"Serializing to JSON: {json_output_filename}")
try:
json_output = json.dumps(
parsed_result, default=custom_json_serializer, indent=2
)
with open(json_output_filename, "w", encoding="utf-8") as f:
f.write(json_output)
print(f"JSON saved: {json_output_filename}")
return json_output_filename
except Exception as e:
print(f"Error during JSON serialization or writing for {filename}: {e}")
return None
def load_json_file(json_filepath: str) -> Optional[Dict[str, Any]]:
"""Loads a JSON file into a Python dictionary."""
try:
with open(json_filepath, "r", encoding="utf-8") as f:
data = json.load(f)
return data
except Exception as e:
print(f"Error loading JSON file {json_filepath}: {e}")
return None
def flatten_db_variables_for_compare(
members_list: List[Dict[str, Any]], parent_path: str = ""
) -> List[Tuple[str, Dict[str, Any]]]:
def find_matching_files(working_dir: str) -> List[Tuple[str, str]]:
"""
Flattens DB members for comparison.
Collects all 'leaf' nodes (primitives, arrays of primitives, strings)
and their full paths.
Busca pares de archivos _data y _format con extensión .db o .awl.
"""
flat_list = []
for var_info in members_list:
var_name_segment = var_info["name"]
current_var_path = (
f"{parent_path}{var_name_segment}" if parent_path else var_name_segment
)
# Buscar archivos _data
data_files_db = glob.glob(os.path.join(working_dir, "*_data.db"))
data_files_awl = glob.glob(os.path.join(working_dir, "*_data.awl"))
all_data_files = data_files_db + data_files_awl
# Buscar archivos _format
format_files_db = glob.glob(os.path.join(working_dir, "*_format.db"))
format_files_awl = glob.glob(os.path.join(working_dir, "*_format.awl"))
all_format_files = format_files_db + format_files_awl
# Emparejar archivos _data y _format
matched_pairs = []
for data_file in all_data_files:
base_name = os.path.basename(data_file).replace("_data", "").split('.')[0]
format_candidates = [f for f in all_format_files if os.path.basename(f).startswith(f"{base_name}_format")]
if format_candidates:
matched_pairs.append((data_file, format_candidates[0]))
return matched_pairs
if var_info.get("children"):
flat_list.extend(
flatten_db_variables_for_compare(
var_info["children"], f"{current_var_path}."
)
)
else:
flat_list.append((current_var_path, var_info))
return flat_list
def compare_db_structures(data_db: Dict[str, Any], format_db: Dict[str, Any]) -> bool:
def parse_files_to_json(data_file: str, format_file: str, json_dir: str) -> Tuple[Dict, Dict]:
"""
Compares the structure of two DBs (as dicts from JSON).
Returns True if compatible, False otherwise.
Parsea los archivos _data y _format usando S7Parser y guarda los resultados como JSON.
"""
db_name = format_db.get("name", "UnknownDB")
print(f"Comparing structure of DB: {db_name}")
# Instancias separadas del parser para cada archivo
data_parser = S7Parser()
format_parser = S7Parser()
print(f"Parseando archivo data: {os.path.basename(data_file)}")
data_result = data_parser.parse_file(data_file)
print(f"Parseando archivo format: {os.path.basename(format_file)}")
format_result = format_parser.parse_file(format_file)
# Guardar resultados como JSON
data_base = os.path.splitext(os.path.basename(data_file))[0]
format_base = os.path.splitext(os.path.basename(format_file))[0]
data_json_path = os.path.join(json_dir, f"{data_base}.json")
format_json_path = os.path.join(json_dir, f"{format_base}.json")
# Serializar y guardar como JSON
data_json = json.dumps(data_result, default=custom_json_serializer, indent=2)
format_json = json.dumps(format_result, default=custom_json_serializer, indent=2)
with open(data_json_path, "w", encoding='utf-8') as f:
f.write(data_json)
with open(format_json_path, "w", encoding='utf-8') as f:
f.write(format_json)
print(f"Archivos JSON generados: {os.path.basename(data_json_path)} y {os.path.basename(format_json_path)}")
# Cargar de nuevo como objetos para procesamiento
data_obj = json.loads(data_json)
format_obj = json.loads(format_json)
return data_obj, format_obj
flat_data_vars_with_paths = flatten_db_variables_for_compare(
data_db.get("members", [])
)
flat_format_vars_with_paths = flatten_db_variables_for_compare(
format_db.get("members", [])
)
if len(flat_data_vars_with_paths) != len(flat_format_vars_with_paths):
print(f"Error: DB '{db_name}' tiene un número diferente de variables expandidas (hoja).")
print(f" Número de variables en archivo _data: {len(flat_data_vars_with_paths)}")
print(f" Número de variables en archivo _format: {len(flat_format_vars_with_paths)}")
min_len = min(len(flat_data_vars_with_paths), len(flat_format_vars_with_paths))
divergence_found_early = False
# Revisar si hay un tipo de dato o nombre diferente antes del final de la lista más corta
for k in range(min_len):
path_data_k, var_data_k = flat_data_vars_with_paths[k]
path_format_k, var_format_k = flat_format_vars_with_paths[k]
type_str_data_k = format_data_type_for_source(var_data_k)
type_str_format_k = format_data_type_for_source(var_format_k)
# Comparamos tipos. Los nombres pueden diferir si la estructura interna de un UDT/Struct cambió.
# La ruta del _data es aproximada si los nombres de los miembros de structs/UDTs cambiaron.
if type_str_data_k != type_str_format_k:
print(f" Adicionalmente, se encontró una discrepancia de tipo ANTES del final de la lista más corta (índice {k}):")
print(f" _format variable: Path='{path_format_k}', Nombre='{var_format_k['name']}', Tipo='{type_str_format_k}'")
print(f" _data variable: Path='{path_data_k}' (aprox.), Nombre='{var_data_k['name']}', Tipo='{type_str_data_k}'")
divergence_found_early = True
break
if not divergence_found_early:
# Si no hubo discrepancias tempranas, la diferencia es por variables extra al final.
if len(flat_data_vars_with_paths) > len(flat_format_vars_with_paths):
print(f" El archivo _data tiene {len(flat_data_vars_with_paths) - min_len} variable(s) más.")
print(f" Primeras variables extra en _data (path, nombre, tipo) desde el índice {min_len}:")
for j in range(min_len, min(min_len + 5, len(flat_data_vars_with_paths))): # Mostrar hasta 5 extra
path, var = flat_data_vars_with_paths[j]
print(f" - Path: '{path}', Nombre: '{var['name']}', Tipo: '{format_data_type_for_source(var)}'")
else:
print(f" El archivo _format tiene {len(flat_format_vars_with_paths) - min_len} variable(s) más.")
print(f" Primeras variables extra en _format (path, nombre, tipo) desde el índice {min_len}:")
for j in range(min_len, min(min_len + 5, len(flat_format_vars_with_paths))): # Mostrar hasta 5 extra
path, var = flat_format_vars_with_paths[j]
print(f" - Path: '{path}', Nombre: '{var['name']}', Tipo: '{format_data_type_for_source(var)}'")
return False
for i in range(len(flat_format_vars_with_paths)):
path_data, var_data = flat_data_vars_with_paths[i]
path_format, var_format = flat_format_vars_with_paths[i]
def create_offset_path_map(members: List[Dict], path_prefix: str = "") -> Dict[float, str]:
"""
Crea un mapa que asocia cada offset con la ruta completa de la variable.
Esto será usado para actualizar las asignaciones del bloque BEGIN.
"""
offset_to_path = {}
def process_member(member: Dict, current_path_prefix: str):
offset = member["byte_offset"]
full_path = f"{current_path_prefix}{member['name']}"
type_str_data = format_data_type_for_source(var_data)
type_str_format = format_data_type_for_source(var_format)
# Mapear offset a ruta completa
offset_to_path[offset] = full_path
# Procesar hijos recursivamente
if "children" in member and member["children"]:
for child in member["children"]:
process_member(child, f"{full_path}.")
# Procesar todos los miembros
for member in members:
process_member(member, path_prefix)
return offset_to_path
if type_str_data != type_str_format:
print(f"Error: Discrepancia de tipo en DB '{db_name}' para la variable en el índice {i} (contando desde 0) de la lista expandida.")
print(f" Comparando:")
print(f" _format variable: Path='{path_format}', Nombre='{var_format['name']}', Tipo Declarado='{type_str_format}'")
print(f" Offset: {var_format.get('byte_offset')}, Tamaño: {var_format.get('size_in_bytes')} bytes")
print(f" _data variable: Path='{path_data}' (aprox.), Nombre='{var_data['name']}', Tipo Declarado='{type_str_data}'")
print(f" Offset: {var_data.get('byte_offset')}, Tamaño: {var_data.get('size_in_bytes')} bytes")
return False
print(f"La estructura del DB '{db_name}' es compatible.")
return True
def update_format_db_members_recursive(
format_members: List[Dict[str, Any]], data_members: List[Dict[str, Any]]
):
def flatten_variables_by_offset(data: Dict) -> Dict[float, Dict]:
"""
Recursively updates 'initial_value', 'current_value', and 'current_element_values'
in format_members using values from data_members.
Assumes structures are compatible and lists have the same length.
Aplana completamente todas las variables por offset, similar a flatten_members_for_markdown.
Incluye UDTs expandidos, estructuras anidadas, etc.
"""
for i in range(len(format_members)):
fm_var = format_members[i]
dm_var = data_members[i]
fm_var["initial_value"] = dm_var.get("initial_value")
fm_var["current_value"] = dm_var.get("current_value")
if "current_element_values" in dm_var:
fm_var["current_element_values"] = dm_var["current_element_values"]
elif "current_element_values" in fm_var:
del fm_var["current_element_values"]
if fm_var.get("children") and dm_var.get("children"):
if len(fm_var["children"]) == len(dm_var["children"]):
update_format_db_members_recursive(
fm_var["children"], dm_var["children"]
offset_map = {}
processed_expanded_members = set()
def process_members(members: List[Dict], prefix: str = "", is_expansion: bool = False):
for var_idx, var in enumerate(members):
# Control para miembros UDT expandidos (evitar duplicados)
member_id = f"{prefix}{var['name']}_{var_idx}"
if is_expansion and member_id in processed_expanded_members:
continue
if is_expansion:
processed_expanded_members.add(member_id)
# Extraer offset e información de la variable
offset = var["byte_offset"]
var_info = {
"path": f"{prefix}{var['name']}",
"data_type": var["data_type"],
"size_in_bytes": var["size_in_bytes"],
"bit_size": var.get("bit_size", 0),
"initial_value": var.get("initial_value"),
"current_value": var.get("current_value"),
"current_element_values": var.get("current_element_values")
}
# Guardar en mapa por offset
offset_map[offset] = var_info
# Procesar recursivamente los hijos
if "children" in var and var["children"]:
process_members(
var["children"],
f"{prefix}{var['name']}.",
is_expansion=bool(var.get("udt_source_name"))
)
else:
print(
f"Warning: Mismatch in children count for {fm_var['name']} during update. This is unexpected."
# Procesar todos los DBs
for db in data.get("dbs", []):
process_members(db.get("members", []))
return offset_map
def create_path_to_offset_map(members: List[Dict], path_prefix: str = "") -> Dict[str, float]:
"""
Crea un mapa que asocia cada ruta (path) completa con su offset.
Esto será usado para actualizar las asignaciones del bloque BEGIN.
"""
path_to_offset = {}
processed_expanded_members = set()
def process_member(member: Dict, current_path_prefix: str, is_expansion: bool = False):
member_id = f"{current_path_prefix}{member['name']}"
# Evitar duplicados para miembros expandidos de UDTs
if is_expansion and member_id in processed_expanded_members:
return
if is_expansion:
processed_expanded_members.add(member_id)
offset = member["byte_offset"]
path = f"{current_path_prefix}{member['name']}"
# Mapear ruta a offset
path_to_offset[path] = offset
# Para arrays, también mapear rutas con índices si hay valores iniciales
if member.get("array_dimensions") and member.get("current_element_values"):
for index in member["current_element_values"].keys():
array_path = f"{path}[{index}]"
path_to_offset[array_path] = offset
# Procesar hijos recursivamente
if "children" in member and member["children"]:
for child in member["children"]:
process_member(
child,
f"{path}.",
is_expansion=bool(member.get("udt_source_name"))
)
# Procesar todos los miembros
for member in members:
process_member(member, path_prefix)
return path_to_offset
def compare_structures_by_offset(data_vars: Dict[float, Dict], format_vars: Dict[float, Dict]) -> Tuple[bool, List[str]]:
"""
Compara variables por offset, verificando compatibilidad.
"""
issues = []
# Recopilar todos los offsets únicos de ambos conjuntos
all_offsets = sorted(set(list(data_vars.keys()) + list(format_vars.keys())))
# Verificar que todos los offsets existan en ambos conjuntos
for offset in all_offsets:
if offset not in data_vars:
issues.append(f"Offset {offset} existe en _format pero no en _data")
continue
if offset not in format_vars:
issues.append(f"Offset {offset} existe en _data pero no en _format")
continue
# Verificar coincidencia de tipos
data_type = data_vars[offset]["data_type"].upper()
format_type = format_vars[offset]["data_type"].upper()
if data_type != format_type:
issues.append(f"Tipo de dato diferente en offset {offset}: {data_type} ({data_vars[offset]['path']}) vs {format_type} ({format_vars[offset]['path']})")
# Verificar tamaño
data_size = data_vars[offset]["size_in_bytes"]
format_size = format_vars[offset]["size_in_bytes"]
if data_size != format_size:
issues.append(f"Tamaño diferente en offset {offset}: {data_size} bytes ({data_vars[offset]['path']}) vs {format_size} bytes ({format_vars[offset]['path']})")
# Verificar tamaño en bits para BOOLs
data_bit_size = data_vars[offset]["bit_size"]
format_bit_size = format_vars[offset]["bit_size"]
if data_bit_size != format_bit_size:
issues.append(f"Tamaño en bits diferente en offset {offset}: {data_bit_size} ({data_vars[offset]['path']}) vs {format_bit_size} ({format_vars[offset]['path']})")
return len(issues) == 0, issues
def get_updated_filename(format_filename_basename: str) -> str:
"""Generates the output filename for the _updated file."""
suffixes_map = {
"_format.db.txt": "_updated.db.txt",
"_format.awl.txt": "_updated.awl.txt",
"_format.db": "_updated.db",
"_format.awl": "_updated.awl",
}
def update_values_recursive(target_member: Dict, data_offset_map: Dict[float, Dict]):
"""
Actualiza los valores de target_member con valores de data_offset_map basado en offset.
"""
offset = target_member["byte_offset"]
# Si encontramos una variable con el mismo offset en _data, tomar sus valores
if offset in data_offset_map:
data_var = data_offset_map[offset]
# Actualizar initial_value
if "initial_value" in data_var and data_var["initial_value"] is not None:
target_member["initial_value"] = data_var["initial_value"]
# Actualizar current_value
if "current_value" in data_var and data_var["current_value"] is not None:
target_member["current_value"] = data_var["current_value"]
# Actualizar current_element_values (para arrays)
if "current_element_values" in data_var and data_var["current_element_values"]:
target_member["current_element_values"] = data_var["current_element_values"]
# Actualizar recursivamente los hijos
if "children" in target_member and target_member["children"]:
for child in target_member["children"]:
update_values_recursive(child, data_offset_map)
for s_format, s_updated in suffixes_map.items():
if format_filename_basename.lower().endswith(s_format.lower()):
base = format_filename_basename[: -len(s_format)]
return base + s_updated
def create_updated_json(data_json: Dict, format_json: Dict) -> Dict:
"""
Crea JSON actualizado basado en la estructura de _format con valores de _data.
"""
# Copia profunda de format_json para no modificar el original
updated_json = copy.deepcopy(format_json)
# Extraer todas las variables flat por offset
data_offset_map = flatten_variables_by_offset(data_json)
# Crear mapas de offsets y rutas para cada BD
db_maps = {}
for db_idx, db in enumerate(format_json.get("dbs", [])):
db_name = db["name"]
db_maps[db_name] = {
"offset_to_path": create_offset_path_map(db.get("members", [])),
"path_to_offset": create_path_to_offset_map(db.get("members", []))
}
# Actualizar valores de variables en la estructura de formato
for db_idx, db in enumerate(updated_json.get("dbs", [])):
for member in db.get("members", []):
update_values_recursive(member, data_offset_map)
# Actualizar también asignaciones del bloque BEGIN
db_name = db["name"]
data_db = next((d for d in data_json.get("dbs", []) if d["name"] == db_name), None)
if data_db and "_begin_block_assignments_ordered" in data_db:
# Obtener los mapas para este DB
offset_to_path = db_maps[db_name]["offset_to_path"]
# Crear una nueva lista de asignaciones con las rutas correctas
updated_assignments = []
# Para cada asignación en los datos de origen
for path, value in data_db["_begin_block_assignments_ordered"]:
# Búsqueda por offset si es posible
data_db_path_to_offset = create_path_to_offset_map(data_db.get("members", []))
if path in data_db_path_to_offset:
# Obtener el offset de la ruta original
offset = data_db_path_to_offset[path]
# Buscar la ruta correspondiente en el formato usando el offset
if offset in offset_to_path:
new_path = offset_to_path[offset]
updated_assignments.append([new_path, value])
print(f"Mapeando {path} -> {new_path} (offset {offset})")
else:
print(f"Advertencia: No se encontró un mapeo para el offset {offset} ({path})")
else:
print(f"Advertencia: No se pudo determinar el offset para la ruta {path}")
# Actualizar asignaciones en el JSON actualizado
db["_begin_block_assignments_ordered"] = updated_assignments
# También actualizar el diccionario _initial_values_from_begin_block
if "_initial_values_from_begin_block" in data_db:
updated_values = {}
for path, value in updated_assignments:
updated_values[path] = value
db["_initial_values_from_begin_block"] = updated_values
return updated_json
if "_format" in format_filename_basename:
return format_filename_basename.replace("_format", "_updated")
name, ext = os.path.splitext(format_filename_basename)
return f"{name}_updated{ext}"
# --- Main Script Logic ---
def main():
# Obtener directorio de trabajo
working_dir = find_working_directory()
print(f"Using working directory: {working_dir}")
data_s7_filepath, format_s7_filepath = find_data_format_files(working_dir)
if not data_s7_filepath or not format_s7_filepath:
print(
"Error: Both _data and _format S7 source files must be present. Aborting."
)
# Crear directorio para JSON si no existe
output_json_dir = os.path.join(working_dir, "json")
os.makedirs(output_json_dir, exist_ok=True)
print(f"Los archivos JSON se guardarán en: {output_json_dir}")
# Buscar pares de archivos _data y _format
matched_pairs = find_matching_files(working_dir)
if not matched_pairs:
print("No se encontraron pares de archivos _data y _format para procesar.")
return
json_dir = os.path.join(working_dir, "json")
os.makedirs(json_dir, exist_ok=True)
data_json_filepath = parse_s7_to_json_file(data_s7_filepath, json_dir)
if not data_json_filepath:
print("Failed to parse _data file. Aborting.")
return
data_parsed_dict = load_json_file(data_json_filepath)
if not data_parsed_dict:
print("Failed to load _data JSON. Aborting.")
return
format_json_filepath = parse_s7_to_json_file(format_s7_filepath, json_dir)
if not format_json_filepath:
print("Failed to parse _format file. Aborting.")
return
format_parsed_dict = load_json_file(format_json_filepath)
if not format_parsed_dict:
print("Failed to load _format JSON. Aborting.")
return
data_dbs = data_parsed_dict.get("dbs", [])
format_dbs = format_parsed_dict.get("dbs", [])
if not format_dbs:
print("No Data Blocks found in the _format file. Nothing to update. Aborting.")
return
if len(data_dbs) != len(format_dbs):
print(
f"Error: Mismatch in the number of Data Blocks. "
f"_data file has {len(data_dbs)} DBs, _format file has {len(format_dbs)} DBs. Aborting."
)
return
all_dbs_compatible = True
for i in range(len(format_dbs)):
current_format_db = format_dbs[i]
current_data_db = next(
(db for db in data_dbs if db["name"] == current_format_db["name"]), None
)
if not current_data_db:
print(
f"Error: DB '{current_format_db['name']}' from _format file not found in _data file. Aborting."
)
all_dbs_compatible = False
break
if not compare_db_structures(current_data_db, current_format_db):
all_dbs_compatible = False
break
if not all_dbs_compatible:
print("Comparison failed. Aborting generation of _updated file.")
return
print("\nAll DB structures are compatible. Proceeding to generate _updated file.")
updated_parsed_dict = copy.deepcopy(format_parsed_dict)
updated_parsed_dict["udts"] = format_parsed_dict.get("udts", [])
updated_dbs_list = updated_parsed_dict.get("dbs", [])
for i in range(len(updated_dbs_list)):
updated_db_ref = updated_dbs_list[i]
data_db_original = next(
(db for db in data_dbs if db["name"] == updated_db_ref["name"]), None
)
if not data_db_original:
print(
f"Critical Error: Could not find data DB {updated_db_ref['name']} during update phase. Aborting."
)
return
if "members" in updated_db_ref and "members" in data_db_original:
update_format_db_members_recursive(
updated_db_ref["members"], data_db_original["members"]
)
updated_db_ref["_begin_block_assignments_ordered"] = data_db_original.get(
"_begin_block_assignments_ordered", []
)
updated_db_ref["_initial_values_from_begin_block"] = data_db_original.get(
"_initial_values_from_begin_block", {}
)
s7_output_lines = generate_s7_source_code_lines(updated_parsed_dict)
output_s7_filename_basename = get_updated_filename(
os.path.basename(format_s7_filepath)
)
output_s7_filepath = os.path.join(working_dir, output_s7_filename_basename)
try:
with open(output_s7_filepath, "w", encoding="utf-8") as f:
for line in s7_output_lines:
f.write(line + "\n")
print(f"\nSuccessfully generated _updated S7 file: {output_s7_filepath}")
except Exception as e:
print(f"Error writing _updated S7 file {output_s7_filepath}: {e}")
print(f"Se encontraron {len(matched_pairs)} pares de archivos para procesar.")
for data_file, format_file in matched_pairs:
print(f"\n--- Procesando par de archivos ---")
print(f"Data file: {os.path.basename(data_file)}")
print(f"Format file: {os.path.basename(format_file)}")
# Parsear archivos a JSON
data_json, format_json = parse_files_to_json(data_file, format_file, output_json_dir)
# Aplanar variables por offset
print("Aplanando variables por offset...")
data_offset_map = flatten_variables_by_offset(data_json)
format_offset_map = flatten_variables_by_offset(format_json)
# Comparar estructuras usando offset como clave
print(f"Comparando estructuras: {len(data_offset_map)} variables en _data, {len(format_offset_map)} variables en _format")
compatible, issues = compare_structures_by_offset(data_offset_map, format_offset_map)
if not compatible:
print("\nSe encontraron problemas de compatibilidad entre los archivos:")
for issue in issues:
print(f" - {issue}")
print("\nAbortando el proceso para este par de archivos.")
continue
print("\nLos archivos son compatibles. Creando el archivo _updated...")
# Crear JSON actualizado usando el mapa de offsets de _data
updated_json = create_updated_json(data_json, format_json)
# Guardar la versión actualizada
base_name = os.path.basename(format_file).replace("_format", "").split('.')[0]
updated_json_path = os.path.join(output_json_dir, f"{base_name}_updated.json")
with open(updated_json_path, "w", encoding='utf-8') as f:
json.dump(updated_json, f, default=custom_json_serializer, indent=2)
print(f"Archivo _updated generado: {updated_json_path}")
print("\n--- Proceso completado ---")
if __name__ == "__main__":
main()
main()

View File

@ -1,17 +1,319 @@
[23:48:43] Iniciando ejecución de x7_value_updater.py en C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001...
[23:48:43] Using working directory: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001
[23:48:43] Found _data file: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_data.db
[23:48:43] Found _format file: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_format.db
[23:48:43] Parsing S7 file: db1001_data.db...
[23:48:43] Serializing to JSON: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\json\db1001_data_data.json
[23:48:43] JSON saved: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\json\db1001_data_data.json
[23:48:43] Parsing S7 file: db1001_format.db...
[23:48:43] Serializing to JSON: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\json\db1001_format_format.json
[23:48:43] JSON saved: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\json\db1001_format_format.json
[23:48:43] Comparing structure of DB: HMI_Blender_Parameters
[23:48:43] La estructura del DB 'HMI_Blender_Parameters' es compatible.
[23:48:43] All DB structures are compatible. Proceeding to generate _updated file.
[23:48:43] INFO: Usando '_begin_block_assignments_ordered' para generar bloque BEGIN de DB 'HMI_Blender_Parameters'.
[23:48:43] Successfully generated _updated S7 file: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_updated.db
[23:48:43] Ejecución de x7_value_updater.py finalizada (success). Duración: 0:00:00.106052.
[23:48:43] Log completo guardado en: D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\S7_DB_Utils\log_x7_value_updater.txt
[00:51:17] Iniciando ejecución de x7_value_updater.py en C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001...
[00:51:18] Using working directory: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001
[00:51:18] Los archivos JSON se guardarán en: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\json
[00:51:18] Se encontraron 1 pares de archivos para procesar.
[00:51:18] --- Procesando par de archivos ---
[00:51:18] Data file: db1001_data.db
[00:51:18] Format file: db1001_format.db
[00:51:18] Parseando archivo data: db1001_data.db
[00:51:18] Parseando archivo format: db1001_format.db
[00:51:18] Archivos JSON generados: db1001_data.json y db1001_format.json
[00:51:18] Aplanando variables por offset...
[00:51:18] Comparando estructuras: 251 variables en _data, 251 variables en _format
[00:51:18] Los archivos son compatibles. Creando el archivo _updated...
[00:51:18] Mapeando STAT0.STAT1.STAT2 -> Processor_Options.Blender_OPT._ModelNum (offset 0.0)
[00:51:18] Mapeando STAT0.STAT1.STAT3 -> Processor_Options.Blender_OPT._CO2_Offset (offset 2.0)
[00:51:18] Mapeando STAT0.STAT1.STAT4 -> Processor_Options.Blender_OPT._MaxSyrDeltaBrix (offset 6.0)
[00:51:18] Mapeando STAT0.STAT1.STAT5 -> Processor_Options.Blender_OPT._BrixMeter (offset 10.0)
[00:51:18] Mapeando STAT0.STAT1.STAT6 -> Processor_Options.Blender_OPT.Spare101 (offset 10.1)
[00:51:18] Mapeando STAT0.STAT1.STAT7 -> Processor_Options.Blender_OPT._TrackH2OEnable (offset 10.2)
[00:51:18] Mapeando STAT0.STAT1.STAT8 -> Processor_Options.Blender_OPT._PAmPDSType (offset 10.3)
[00:51:18] Mapeando STAT0.STAT1.STAT9 -> Processor_Options.Blender_OPT._HistoricalTrends (offset 10.4)
[00:51:18] Mapeando STAT0.STAT1.STAT10 -> Processor_Options.Blender_OPT._PowerMeter (offset 10.5)
[00:51:18] Mapeando STAT0.STAT1.STAT11 -> Processor_Options.Blender_OPT._Report (offset 10.6)
[00:51:18] Mapeando STAT0.STAT1.STAT12 -> Processor_Options.Blender_OPT._Balaiage (offset 10.7)
[00:51:18] Mapeando STAT0.STAT1.STAT13 -> Processor_Options.Blender_OPT._Valves_FullFeedback (offset 11.0)
[00:51:18] Mapeando STAT0.STAT1.STAT14 -> Processor_Options.Blender_OPT._Valves_SingleFeedback (offset 11.1)
[00:51:18] Mapeando STAT0.STAT1.STAT15 -> Processor_Options.Blender_OPT._PumpsSafetySwitches (offset 11.2)
[00:51:18] Mapeando STAT0.STAT1.STAT16 -> Processor_Options.Blender_OPT._SurgeProtectionAct (offset 11.3)
[00:51:18] Mapeando STAT0.STAT1.STAT17 -> Processor_Options.Blender_OPT._DBC_Type (offset 11.4)
[00:51:18] Mapeando STAT0.STAT1.STAT18 -> Processor_Options.Blender_OPT._CO2InletMeter (offset 11.5)
[00:51:18] Mapeando STAT0.STAT1.STAT19 -> Processor_Options.Blender_OPT._ProductO2Meter (offset 11.6)
[00:51:18] Mapeando STAT0.STAT1.STAT20 -> Processor_Options.Blender_OPT._CopressedAirInletMeter (offset 11.7)
[00:51:18] Mapeando STAT0.STAT1.STAT21 -> Processor_Options.Blender_OPT._MeterType (offset 12.0)
[00:51:18] Mapeando STAT0.STAT1.STAT22 -> Processor_Options.Blender_OPT._MeterReceiveOnly (offset 14.0)
[00:51:18] Mapeando STAT0.STAT1.STAT23 -> Processor_Options.Blender_OPT._SyrBrixMeter (offset 14.1)
[00:51:18] Mapeando STAT0.STAT1.STAT24 -> Processor_Options.Blender_OPT._Flooding_Start_Up (offset 14.2)
[00:51:18] Mapeando STAT0.STAT1.STAT25 -> Processor_Options.Blender_OPT._FastChangeOverEnabled (offset 14.3)
[00:51:18] Mapeando STAT0.STAT1.STAT26 -> Processor_Options.Blender_OPT._WaterInletMeter (offset 14.4)
[00:51:18] Mapeando STAT0.STAT1.STAT27 -> Processor_Options.Blender_OPT._BlendFillSystem (offset 14.5)
[00:51:18] Mapeando STAT0.STAT1.STAT28 -> Processor_Options.Blender_OPT._TrackFillerSpeed (offset 14.6)
[00:51:18] Mapeando STAT0.STAT1.STAT29 -> Processor_Options.Blender_OPT._SignalExchange (offset 16.0)
[00:51:18] Mapeando STAT0.STAT1.STAT30 -> Processor_Options.Blender_OPT._CoolerPresent (offset 18.0)
[00:51:18] Mapeando STAT0.STAT1.STAT31 -> Processor_Options.Blender_OPT._CoolerControl (offset 20.0)
[00:51:18] Mapeando STAT0.STAT1.STAT32 -> Processor_Options.Blender_OPT._CoolerType (offset 22.0)
[00:51:18] Mapeando STAT0.STAT1.STAT33 -> Processor_Options.Blender_OPT._LocalCIP (offset 24.0)
[00:51:18] Mapeando STAT0.STAT1.STAT34 -> Processor_Options.Blender_OPT._ICS_CustomerHotWater (offset 24.1)
[00:51:18] Mapeando STAT0.STAT1.STAT35 -> Processor_Options.Blender_OPT._ICS_CustomerChemRecov (offset 24.2)
[00:51:18] Mapeando STAT0.STAT1.STAT36 -> Processor_Options.Blender_OPT._CIPSignalExchange (offset 24.3)
[00:51:18] Mapeando STAT0.STAT1.STAT37 -> Processor_Options.Blender_OPT._ICS_CustomerChemicals (offset 24.4)
[00:51:18] Mapeando STAT0.STAT1.STAT38 -> Processor_Options.Blender_OPT._CarboPresent (offset 24.5)
[00:51:18] Mapeando STAT0.STAT1.STAT39 -> Processor_Options.Blender_OPT._InverterSyrupPumpPPP302 (offset 24.6)
[00:51:18] Mapeando STAT0.STAT1.STAT40 -> Processor_Options.Blender_OPT._InverterWaterPumpPPN301 (offset 24.7)
[00:51:18] Mapeando STAT0.STAT1.STAT41 -> Processor_Options.Blender_OPT._DoubleDeair (offset 25.0)
[00:51:18] Mapeando STAT0.STAT1.STAT42 -> Processor_Options.Blender_OPT._DeairPreMixed (offset 25.1)
[00:51:18] Mapeando STAT0.STAT1.STAT43 -> Processor_Options.Blender_OPT._Deaireation (offset 25.2)
[00:51:18] Mapeando STAT0.STAT1.STAT44 -> Processor_Options.Blender_OPT._StillWaterByPass (offset 25.3)
[00:51:18] Mapeando STAT0.STAT1.STAT45 -> Processor_Options.Blender_OPT._ManifoldSetting (offset 25.4)
[00:51:18] Mapeando STAT0.STAT1.STAT46 -> Processor_Options.Blender_OPT._InverterProdPumpPPM303 (offset 25.5)
[00:51:18] Mapeando STAT0.STAT1.STAT47 -> Processor_Options.Blender_OPT._SidelCip (offset 25.6)
[00:51:18] Mapeando STAT0.STAT1.STAT48 -> Processor_Options.Blender_OPT._EthernetCom_CpuPN_CP (offset 25.7)
[00:51:18] Mapeando STAT0.STAT1.STAT49 -> Processor_Options.Blender_OPT._2ndOutlet (offset 26.0)
[00:51:18] Mapeando STAT0.STAT1.STAT50 -> Processor_Options.Blender_OPT._Promass (offset 28.0)
[00:51:18] Mapeando STAT0.STAT1.STAT51 -> Processor_Options.Blender_OPT._WaterPromass (offset 30.0)
[00:51:18] Mapeando STAT0.STAT1.STAT52 -> Processor_Options.Blender_OPT._ProductConductimeter (offset 30.1)
[00:51:18] Mapeando STAT0.STAT1.STAT53 -> Processor_Options.Blender_OPT._ICS_CustomerH2ORecov (offset 30.2)
[00:51:18] Mapeando STAT0.STAT1.STAT54 -> Processor_Options.Blender_OPT.Spare303 (offset 30.3)
[00:51:18] Mapeando STAT0.STAT1.STAT55 -> Processor_Options.Blender_OPT._CO2_GAS2_Injection (offset 30.4)
[00:51:18] Mapeando STAT0.STAT1.STAT56 -> Processor_Options.Blender_OPT._InverterVacuuPumpPPN304 (offset 30.5)
[00:51:18] Mapeando STAT0.STAT1.STAT57 -> Processor_Options.Blender_OPT._InverterBoostPumpPPM307 (offset 30.6)
[00:51:18] Mapeando STAT0.STAT1.STAT58 -> Processor_Options.Blender_OPT._RunOut_Water (offset 30.7)
[00:51:18] Mapeando STAT0.STAT1.STAT59 -> Processor_Options.Blender_OPT._FlowMeterType (offset 31.0)
[00:51:18] Mapeando STAT0.STAT1.STAT60 -> Processor_Options.Blender_OPT._SidelFiller (offset 31.1)
[00:51:18] Mapeando STAT0.STAT1.STAT61 -> Processor_Options.Blender_OPT._Simulation (offset 31.2)
[00:51:18] Mapeando STAT0.STAT1.STAT62 -> Processor_Options.Blender_OPT._ProductCoolingCTRL (offset 31.3)
[00:51:18] Mapeando STAT0.STAT1.STAT63 -> Processor_Options.Blender_OPT._ChillerCTRL (offset 31.4)
[00:51:18] Mapeando STAT0.STAT1.STAT64 -> Processor_Options.Blender_OPT._CO2_SterileFilter (offset 31.5)
[00:51:18] Mapeando STAT0.STAT1.STAT65 -> Processor_Options.Blender_OPT._InverterRecirPumpPPM306 (offset 31.6)
[00:51:18] Mapeando STAT0.STAT1.STAT66 -> Processor_Options.Blender_OPT._ProdPressReleaseRVM304 (offset 31.7)
[00:51:18] Mapeando STAT0.STAT1.STAT67 -> Processor_Options.Blender_OPT._VacuumPump (offset 32.0)
[00:51:18] Mapeando STAT0.STAT1.STAT68 -> Processor_Options.Blender_OPT._GAS2InjectionType (offset 34.0)
[00:51:18] Mapeando STAT0.STAT1.STAT69 -> Processor_Options.Blender_OPT._InjectionPress_Ctrl (offset 36.0)
[00:51:18] Mapeando STAT0.STAT1.STAT70 -> Processor_Options.Blender_OPT._ProdPressureType (offset 38.0)
[00:51:18] Mapeando STAT0.STAT1.STAT71 -> Processor_Options.Blender_OPT._CIPHeatType (offset 40.0)
[00:51:18] Mapeando STAT0.STAT1.STAT72 -> Processor_Options.Blender_OPT._EHS_NrRes (offset 42.0)
[00:51:18] Mapeando STAT73[1] -> Spare1 (offset 44.0)
[00:51:18] Mapeando STAT73[2] -> Spare1 (offset 44.0)
[00:51:18] Mapeando STAT73[3] -> Spare1 (offset 44.0)
[00:51:18] Mapeando STAT73[4] -> Spare1 (offset 44.0)
[00:51:18] Mapeando STAT73[5] -> Spare1 (offset 44.0)
[00:51:18] Mapeando STAT73[6] -> Spare1 (offset 44.0)
[00:51:18] Mapeando STAT73[7] -> Spare1 (offset 44.0)
[00:51:18] Mapeando STAT73[8] -> Spare1 (offset 44.0)
[00:51:18] Mapeando STAT73[9] -> Spare1 (offset 44.0)
[00:51:18] Mapeando STAT74 -> _RVM301_DeadBand (offset 62.0)
[00:51:18] Mapeando STAT75 -> _RVM301_Kp (offset 66.0)
[00:51:18] Mapeando STAT76.STAT77 -> Actual_Recipe_Parameters._Name (offset 70.0)
[00:51:18] Mapeando STAT76.STAT78 -> Actual_Recipe_Parameters._EnProdTemp (offset 104.0)
[00:51:18] Mapeando STAT76.STAT79 -> Actual_Recipe_Parameters._SyrFlushing (offset 104.1)
[00:51:18] Mapeando STAT76.STAT80 -> Actual_Recipe_Parameters._GAS2_Injection (offset 104.2)
[00:51:18] Mapeando STAT76.STAT81 -> Actual_Recipe_Parameters._Eq_Pression_Selected (offset 104.3)
[00:51:18] Mapeando STAT76.STAT82 -> Actual_Recipe_Parameters._DeoxStripEn (offset 104.4)
[00:51:18] Mapeando STAT76.STAT83 -> Actual_Recipe_Parameters._DeoxVacuumEn (offset 104.5)
[00:51:18] Mapeando STAT76.STAT84 -> Actual_Recipe_Parameters._DeoxPreMixed (offset 104.6)
[00:51:18] Mapeando STAT76.STAT85 -> Actual_Recipe_Parameters._EnBlowOffProdPipeCO2Fil (offset 104.7)
[00:51:18] Mapeando STAT76.STAT86 -> Actual_Recipe_Parameters._WaterSelection (offset 105.0)
[00:51:18] Mapeando STAT76.STAT87 -> Actual_Recipe_Parameters._FillerNextRecipeNum (offset 106.0)
[00:51:18] Mapeando STAT76.STAT88 -> Actual_Recipe_Parameters._BottleShape (offset 107.0)
[00:51:18] Mapeando STAT76.STAT89 -> Actual_Recipe_Parameters._Type (offset 108.0)
[00:51:18] Mapeando STAT76.STAT90 -> Actual_Recipe_Parameters._ProdMeterRecipeNum (offset 110.0)
[00:51:18] Mapeando STAT76.STAT91 -> Actual_Recipe_Parameters._SyrupBrix (offset 112.0)
[00:51:18] Mapeando STAT76.STAT92 -> Actual_Recipe_Parameters._SyrupDensity (offset 116.0)
[00:51:18] Mapeando STAT76.STAT93 -> Actual_Recipe_Parameters._SyrupFactor (offset 120.0)
[00:51:18] Mapeando STAT76.STAT94 -> Actual_Recipe_Parameters._ProductBrix (offset 124.0)
[00:51:18] Mapeando STAT76.STAT95 -> Actual_Recipe_Parameters._ProductionRate (offset 128.0)
[00:51:18] Mapeando STAT76.STAT96 -> Actual_Recipe_Parameters._Ratio (offset 132.0)
[00:51:18] Mapeando STAT76.STAT97 -> Actual_Recipe_Parameters._ProdBrixOffset (offset 136.0)
[00:51:18] Mapeando STAT76.STAT98 -> Actual_Recipe_Parameters._CO2Vols (offset 140.0)
[00:51:18] Mapeando STAT76.STAT99 -> Actual_Recipe_Parameters._CO2Fact (offset 144.0)
[00:51:18] Mapeando STAT76.STAT100 -> Actual_Recipe_Parameters._ProdTankPress (offset 148.0)
[00:51:18] Mapeando STAT76.STAT101 -> Actual_Recipe_Parameters._SP_ProdTemp (offset 152.0)
[00:51:18] Mapeando STAT76.STAT102 -> Actual_Recipe_Parameters._PrdTankMinLevel (offset 156.0)
[00:51:18] Mapeando STAT76.STAT103 -> Actual_Recipe_Parameters._WaterValveSave (offset 160.0)
[00:51:18] Mapeando STAT76.STAT104 -> Actual_Recipe_Parameters._SyrupValveSave (offset 164.0)
[00:51:18] Mapeando STAT76.STAT105 -> Actual_Recipe_Parameters._CarboCO2ValveSave (offset 168.0)
[00:51:18] Mapeando STAT76.STAT106 -> Actual_Recipe_Parameters._ProdMeterHighBrix (offset 172.0)
[00:51:18] Mapeando STAT76.STAT107 -> Actual_Recipe_Parameters._ProdMeterLowBrix (offset 176.0)
[00:51:18] Mapeando STAT76.STAT108 -> Actual_Recipe_Parameters._ProdMeterHighCO2 (offset 180.0)
[00:51:18] Mapeando STAT76.STAT109 -> Actual_Recipe_Parameters._ProdMeterLowCO2 (offset 184.0)
[00:51:18] Mapeando STAT76.STAT110 -> Actual_Recipe_Parameters._ProdMeter_ZeroCO2 (offset 188.0)
[00:51:18] Mapeando STAT76.STAT111 -> Actual_Recipe_Parameters._ProdMeter_ZeroBrix (offset 192.0)
[00:51:18] Mapeando STAT76.STAT112 -> Actual_Recipe_Parameters._ProdHighCond (offset 196.0)
[00:51:18] Mapeando STAT76.STAT113 -> Actual_Recipe_Parameters._ProdLowCond (offset 200.0)
[00:51:18] Mapeando STAT76.STAT114 -> Actual_Recipe_Parameters._BottleSize (offset 204.0)
[00:51:18] Mapeando STAT76.STAT115 -> Actual_Recipe_Parameters._FillingValveHead_SP (offset 208.0)
[00:51:18] Mapeando STAT76.STAT116 -> Actual_Recipe_Parameters._SyrMeter_ZeroBrix (offset 212.0)
[00:51:18] Mapeando STAT76.STAT117 -> Actual_Recipe_Parameters._FirstProdExtraCO2Fact (offset 216.0)
[00:51:18] Mapeando STAT76.STAT118 -> Actual_Recipe_Parameters._Gas2Vols (offset 220.0)
[00:51:18] Mapeando STAT76.STAT119 -> Actual_Recipe_Parameters._Gas2Fact (offset 224.0)
[00:51:18] Mapeando STAT76.STAT120 -> Actual_Recipe_Parameters._SyrupPumpPressure (offset 228.0)
[00:51:18] Mapeando STAT76.STAT121 -> Actual_Recipe_Parameters._WaterPumpPressure (offset 232.0)
[00:51:18] Mapeando STAT76.STAT122 -> Actual_Recipe_Parameters._CO2_Air_N2_PressSelect (offset 236.0)
[00:51:18] Mapeando STAT76.STAT123 -> Actual_Recipe_Parameters._KFactRVM304BlowOff (offset 238.0)
[00:51:18] Mapeando STAT76.STAT124 -> Actual_Recipe_Parameters._ProdRecircPumpFreq (offset 242.0)
[00:51:18] Mapeando STAT76.STAT125 -> Actual_Recipe_Parameters._ProdBoosterPumpPress (offset 246.0)
[00:51:18] Mapeando STAT76.STAT126 -> Actual_Recipe_Parameters._ProdSendPumpFreq (offset 250.0)
[00:51:18] Mapeando STAT127[1] -> Spare2 (offset 254.0)
[00:51:18] Mapeando STAT127[2] -> Spare2 (offset 254.0)
[00:51:18] Mapeando STAT127[3] -> Spare2 (offset 254.0)
[00:51:18] Mapeando STAT127[4] -> Spare2 (offset 254.0)
[00:51:18] Mapeando STAT127[5] -> Spare2 (offset 254.0)
[00:51:18] Mapeando STAT128 -> Next_Recipe_Name (offset 264.0)
[00:51:18] Mapeando STAT129 -> Next_Recipe_Number (offset 298.0)
[00:51:18] Mapeando STAT130[1] -> Spare3 (offset 300.0)
[00:51:18] Mapeando STAT130[2] -> Spare3 (offset 300.0)
[00:51:18] Mapeando STAT130[3] -> Spare3 (offset 300.0)
[00:51:18] Mapeando STAT130[4] -> Spare3 (offset 300.0)
[00:51:18] Mapeando STAT130[5] -> Spare3 (offset 300.0)
[00:51:18] Mapeando STAT130[6] -> Spare3 (offset 300.0)
[00:51:18] Mapeando STAT130[7] -> Spare3 (offset 300.0)
[00:51:18] Mapeando STAT130[8] -> Spare3 (offset 300.0)
[00:51:18] Mapeando STAT130[9] -> Spare3 (offset 300.0)
[00:51:18] Mapeando STAT130[10] -> Spare3 (offset 300.0)
[00:51:18] Mapeando STAT130[11] -> Spare3 (offset 300.0)
[00:51:18] Mapeando STAT130[12] -> Spare3 (offset 300.0)
[00:51:18] Mapeando STAT130[13] -> Spare3 (offset 300.0)
[00:51:18] Mapeando STAT130[14] -> Spare3 (offset 300.0)
[00:51:18] Mapeando STAT130[15] -> Spare3 (offset 300.0)
[00:51:18] Mapeando STAT130[16] -> Spare3 (offset 300.0)
[00:51:18] Mapeando STAT130[17] -> Spare3 (offset 300.0)
[00:51:18] Mapeando STAT130[18] -> Spare3 (offset 300.0)
[00:51:18] Mapeando STAT131.STAT132 -> ProcessSetup.Spare000 (offset 336.0)
[00:51:18] Mapeando STAT131.STAT133 -> ProcessSetup.Spare040 (offset 340.0)
[00:51:18] Mapeando STAT131.STAT134 -> ProcessSetup._KWaterLoss (offset 344.0)
[00:51:18] Mapeando STAT131.STAT135 -> ProcessSetup._KSyrupLoss (offset 348.0)
[00:51:18] Mapeando STAT131.STAT136 -> ProcessSetup._KProdLoss (offset 352.0)
[00:51:18] Mapeando STAT131.STAT137 -> ProcessSetup._KPPM303 (offset 356.0)
[00:51:18] Mapeando STAT131.STAT138 -> ProcessSetup._BaialageRVM301OVMin (offset 360.0)
[00:51:18] Mapeando STAT131.STAT139 -> ProcessSetup._SyrupLinePressure (offset 364.0)
[00:51:18] Mapeando STAT131.STAT140 -> ProcessSetup._CIPRMM301OV (offset 368.0)
[00:51:18] Mapeando STAT131.STAT141 -> ProcessSetup._CIPRMP302OV (offset 372.0)
[00:51:18] Mapeando STAT131.STAT142 -> ProcessSetup._CIPTM301MinLevel (offset 376.0)
[00:51:18] Mapeando STAT131.STAT143 -> ProcessSetup._CIPTM301MaxLevel (offset 380.0)
[00:51:18] Mapeando STAT131.STAT144 -> ProcessSetup._CIPPPM303Freq (offset 384.0)
[00:51:18] Mapeando STAT131.STAT145 -> ProcessSetup._CIPTP301MinLevel (offset 388.0)
[00:51:18] Mapeando STAT131.STAT146 -> ProcessSetup._CIPTP301MaxLevel (offset 392.0)
[00:51:18] Mapeando STAT131.STAT147 -> ProcessSetup._RinseRMM301OV (offset 396.0)
[00:51:18] Mapeando STAT131.STAT148 -> ProcessSetup._RinseRMP302OV (offset 400.0)
[00:51:18] Mapeando STAT131.STAT149 -> ProcessSetup._RinseTM301Press (offset 404.0)
[00:51:18] Mapeando STAT131.STAT150 -> ProcessSetup._RinsePPM303Freq (offset 408.0)
[00:51:18] Mapeando STAT131.STAT151 -> ProcessSetup._DrainTM301Press (offset 412.0)
[00:51:18] Mapeando STAT131.STAT152 -> ProcessSetup._KRecBlendError (offset 416.0)
[00:51:18] Mapeando STAT131.STAT153 -> ProcessSetup._KRecCarboCO2Error (offset 420.0)
[00:51:18] Mapeando STAT131.STAT154 -> ProcessSetup._MaxBlendError (offset 424.0)
[00:51:18] Mapeando STAT131.STAT155 -> ProcessSetup._MaxCarboCO2Error (offset 428.0)
[00:51:18] Mapeando STAT131.STAT156 -> ProcessSetup._StartUpBrixExtraWater (offset 432.0)
[00:51:18] Mapeando STAT131.STAT157 -> ProcessSetup._StartUpCO2ExtraWater (offset 436.0)
[00:51:18] Mapeando STAT131.STAT158 -> ProcessSetup._StartUpPPM303Freq (offset 440.0)
[00:51:18] Mapeando STAT131.STAT159 -> ProcessSetup._SyrupRoomTank (offset 444.0)
[00:51:18] Mapeando STAT131.STAT160 -> ProcessSetup._SyrupRunOutLiters (offset 446.0)
[00:51:18] Mapeando STAT131.STAT161 -> ProcessSetup._InjCO2Press_Offset (offset 450.0)
[00:51:18] Mapeando STAT131.STAT162 -> ProcessSetup._InjCO2Press_MinFlow (offset 454.0)
[00:51:18] Mapeando STAT131.STAT163 -> ProcessSetup._InjCO2Press_MaxFlow (offset 458.0)
[00:51:18] Mapeando STAT131.STAT164 -> ProcessSetup._CarboCO2Pressure (offset 462.0)
[00:51:18] Mapeando STAT131.STAT165 -> ProcessSetup._N2MinPressure (offset 466.0)
[00:51:18] Mapeando STAT131.STAT166 -> ProcessSetup._DiffSensor_Height (offset 470.0)
[00:51:18] Mapeando STAT131.STAT167 -> ProcessSetup._DiffSensor_DeltaHeight (offset 474.0)
[00:51:18] Mapeando STAT131.STAT168 -> ProcessSetup._DiffSensor_Offset (offset 478.0)
[00:51:18] Mapeando STAT131.STAT169 -> ProcessSetup._FillingValveHeight (offset 482.0)
[00:51:18] Mapeando STAT131.STAT170 -> ProcessSetup._FillerDiameter (offset 486.0)
[00:51:18] Mapeando STAT131.STAT171 -> ProcessSetup._FillingValveNum (offset 490.0)
[00:51:18] Mapeando STAT131.STAT172 -> ProcessSetup._FillerProdPipeDN (offset 492.0)
[00:51:18] Mapeando STAT131.STAT173 -> ProcessSetup._FillerProdPipeMass (offset 496.0)
[00:51:18] Mapeando STAT131.STAT174 -> ProcessSetup._FillingTime (offset 500.0)
[00:51:18] Mapeando STAT131.STAT175 -> ProcessSetup._TM301Height_0 (offset 504.0)
[00:51:18] Mapeando STAT131.STAT176 -> ProcessSetup._TM301LevelPerc_2 (offset 508.0)
[00:51:18] Mapeando STAT131.STAT177 -> ProcessSetup._TM301Height_2 (offset 512.0)
[00:51:18] Mapeando STAT131.STAT178 -> ProcessSetup._RVN304Factor (offset 516.0)
[00:51:18] Mapeando STAT131.STAT179 -> ProcessSetup._DrainTM301Flushing (offset 520.0)
[00:51:18] Mapeando STAT131.STAT180 -> ProcessSetup._FirstProdExtraBrix (offset 524.0)
[00:51:18] Mapeando STAT131.STAT181 -> ProcessSetup._FirstProdDietExtraSyr (offset 528.0)
[00:51:18] Mapeando STAT131.STAT182 -> ProcessSetup._EndProdLastSyrlt (offset 532.0)
[00:51:18] Mapeando STAT131.STAT183 -> ProcessSetup._TM301DrainSt0Time (offset 536.0)
[00:51:18] Mapeando STAT131.STAT184 -> ProcessSetup._TM301DrainSt1Time (offset 538.0)
[00:51:18] Mapeando STAT131.STAT185 -> ProcessSetup._ProdPipeRunOutSt0Time (offset 540.0)
[00:51:18] Mapeando STAT131.STAT186 -> ProcessSetup._RMM301ProdPipeRunOu (offset 542.0)
[00:51:18] Mapeando STAT131.STAT187 -> ProcessSetup._RMP302ProdPipeRunOu (offset 546.0)
[00:51:18] Mapeando STAT131.STAT188 -> ProcessSetup._ProdPipeRunOutAmount (offset 550.0)
[00:51:18] Mapeando STAT131.STAT189 -> ProcessSetup._TM301RunOutChiller (offset 554.0)
[00:51:18] Mapeando STAT131.STAT190 -> ProcessSetup._MinSpeedNominalProd (offset 558.0)
[00:51:18] Mapeando STAT131.STAT191 -> ProcessSetup._MinSpeedSlowProd (offset 562.0)
[00:51:18] Mapeando STAT131.STAT192 -> ProcessSetup._FastChgOvrTM301DrnPrss (offset 566.0)
[00:51:18] Mapeando STAT131.STAT193 -> ProcessSetup._CIPTN301MinLevel (offset 570.0)
[00:51:18] Mapeando STAT131.STAT194 -> ProcessSetup._CIPTN301MaxLevel (offset 574.0)
[00:51:18] Mapeando STAT131.STAT195 -> ProcessSetup._ProdPPN304Freq (offset 578.0)
[00:51:18] Mapeando STAT131.STAT196 -> ProcessSetup._GAS2InjectionPress (offset 582.0)
[00:51:18] Mapeando STAT131.STAT197 -> ProcessSetup._BaialageRVM301OVMax (offset 586.0)
[00:51:18] Mapeando STAT131.STAT198 -> ProcessSetup._RinsePPN301Freq (offset 590.0)
[00:51:18] Mapeando STAT131.STAT199 -> ProcessSetup._CIPPPN301Freq (offset 594.0)
[00:51:18] Mapeando STAT131.STAT200 -> ProcessSetup._RinsePPP302Freq (offset 598.0)
[00:51:18] Mapeando STAT131.STAT201 -> ProcessSetup._CIPPPP302Freq (offset 602.0)
[00:51:18] Mapeando STAT131.STAT202 -> ProcessSetup._PercSyrupBrixSyrStarUp (offset 606.0)
[00:51:18] Mapeando STAT131.STAT203 -> ProcessSetup._RefTempCoolingCTRL (offset 610.0)
[00:51:18] Mapeando STAT131.STAT204 -> ProcessSetup._H2OSerpPrimingVolume (offset 614.0)
[00:51:18] Mapeando STAT131.STAT205 -> ProcessSetup._AVN301_Nozzle_Kv (offset 618.0)
[00:51:18] Mapeando STAT131.STAT206 -> ProcessSetup._AVN302_Nozzle_Kv (offset 622.0)
[00:51:18] Mapeando STAT131.STAT207 -> ProcessSetup._AVN303_Nozzle_Kv (offset 626.0)
[00:51:18] Mapeando STAT131.STAT208 -> ProcessSetup._DeoxSpryball_Kv (offset 630.0)
[00:51:18] Mapeando STAT131.STAT209 -> ProcessSetup._PremixedLineDrainTime (offset 634.0)
[00:51:18] Mapeando STAT131.STAT210 -> ProcessSetup._PPN301_H_MaxFlow (offset 636.0)
[00:51:18] Mapeando STAT131.STAT211 -> ProcessSetup._PPN301_H_MinFlow (offset 640.0)
[00:51:18] Mapeando STAT131.STAT212 -> ProcessSetup._PPN301_MaxFlow (offset 644.0)
[00:51:18] Mapeando STAT131.STAT213 -> ProcessSetup._PPN301_MinFlow (offset 648.0)
[00:51:18] Mapeando STAT131.STAT214 -> ProcessSetup._PPP302_H_MaxFlow (offset 652.0)
[00:51:18] Mapeando STAT131.STAT215 -> ProcessSetup._PPP302_H_MinFlow (offset 656.0)
[00:51:18] Mapeando STAT131.STAT216 -> ProcessSetup._PPP302_MaxFlow (offset 660.0)
[00:51:18] Mapeando STAT131.STAT217 -> ProcessSetup._PPP302_MinFlow (offset 664.0)
[00:51:18] Mapeando STAT131.STAT218 -> ProcessSetup._RinsePPM306Freq (offset 668.0)
[00:51:18] Mapeando STAT131.STAT219 -> ProcessSetup._CIPPPM306Freq (offset 672.0)
[00:51:18] Mapeando STAT131.STAT220 -> ProcessSetup._PPM307_H_MaxFlow (offset 676.0)
[00:51:18] Mapeando STAT131.STAT221 -> ProcessSetup._PPM307_H_MinFlow (offset 680.0)
[00:51:18] Mapeando STAT131.STAT222 -> ProcessSetup._PPM307_MaxFlow (offset 684.0)
[00:51:18] Mapeando STAT131.STAT223 -> ProcessSetup._PPM307_MinFlow (offset 688.0)
[00:51:18] Mapeando STAT131.STAT224 -> ProcessSetup._Temp0_VacuumCtrl (offset 692.0)
[00:51:18] Mapeando STAT131.STAT225 -> ProcessSetup._Temp1_VacuumCtrl (offset 696.0)
[00:51:18] Mapeando STAT131.STAT226 -> ProcessSetup._Temp2_VacuumCtrl (offset 700.0)
[00:51:18] Mapeando STAT131.STAT227 -> ProcessSetup._Temp3_VacuumCtrl (offset 704.0)
[00:51:18] Mapeando STAT131.STAT228 -> ProcessSetup._Temp4_VacuumCtrl (offset 708.0)
[00:51:18] Mapeando STAT131.STAT229 -> ProcessSetup._T1_VacuumCtrl (offset 712.0)
[00:51:18] Mapeando STAT131.STAT230 -> ProcessSetup._T2_VacuumCtrl (offset 716.0)
[00:51:18] Mapeando STAT131.STAT231 -> ProcessSetup._T3_VacuumCtrl (offset 720.0)
[00:51:18] Mapeando STAT131.STAT232 -> ProcessSetup._T4_VacuumCtrl (offset 724.0)
[00:51:18] Mapeando STAT131.STAT233 -> ProcessSetup._ICS_VolDosWorkTimePAA (offset 728.0)
[00:51:18] Mapeando STAT131.STAT234 -> ProcessSetup._ICS_VolPauseTimePAA (offset 730.0)
[00:51:18] Mapeando STAT131.STAT235 -> ProcessSetup._ICS_PAAPulseWeight (offset 732.0)
[00:51:18] Mapeando STAT131.STAT236 -> ProcessSetup._ICS_CausticPulseWeight (offset 734.0)
[00:51:18] Mapeando STAT131.STAT237 -> ProcessSetup._ICS_AcidPulseWeight (offset 736.0)
[00:51:18] Mapeando STAT131.STAT238 -> ProcessSetup._ICS_VolumeRestOfLine (offset 738.0)
[00:51:18] Mapeando STAT131.STAT239 -> ProcessSetup._ICS_VolDosWorkTimeCaus (offset 742.0)
[00:51:18] Mapeando STAT131.STAT240 -> ProcessSetup._ICS_VolDosPauseTimeCaus (offset 744.0)
[00:51:18] Mapeando STAT131.STAT241 -> ProcessSetup._ICS_VolDosWorkTimeAcid (offset 746.0)
[00:51:18] Mapeando STAT131.STAT242 -> ProcessSetup._ICS_VolDosPauseTimeAcid (offset 748.0)
[00:51:18] Mapeando STAT131.STAT243 -> ProcessSetup._ICS_ConcDosWorkTimeCaus (offset 750.0)
[00:51:18] Mapeando STAT131.STAT244 -> ProcessSetup._ICS_ConcDosPausTimeCaus (offset 752.0)
[00:51:18] Mapeando STAT131.STAT245 -> ProcessSetup._ICS_ConcDosWorkTimeAcid (offset 754.0)
[00:51:18] Mapeando STAT131.STAT246 -> ProcessSetup._ICS_ConcDosPausTimeAcid (offset 756.0)
[00:51:18] Mapeando STAT131.STAT247 -> ProcessSetup._RinsePPM307Freq (offset 758.0)
[00:51:18] Mapeando STAT131.STAT248 -> ProcessSetup._CIPPPM307Freq (offset 762.0)
[00:51:18] Mapeando STAT131.STAT249 -> ProcessSetup._CIP2StepTN301Lvl (offset 766.0)
[00:51:18] Mapeando STAT131.STAT250 -> ProcessSetup._CIP2StepTM301Lvl (offset 770.0)
[00:51:18] Mapeando STAT131.STAT251 -> ProcessSetup._CIP2StepTP301Lvl (offset 774.0)
[00:51:18] Mapeando STAT131.STAT252 -> ProcessSetup._PumpNominalFreq (offset 778.0)
[00:51:18] Mapeando STAT253 -> _SwitchOff_DensityOK (offset 782.0)
[00:51:18] Mapeando STAT254 -> STAT254 (offset 784.0)
[00:51:18] Archivo _updated generado: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\json\db1001_updated.json
[00:51:18] --- Proceso completado ---
[00:51:18] Ejecución de x7_value_updater.py finalizada (success). Duración: 0:00:00.223903.
[00:51:18] Log completo guardado en: D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\S7_DB_Utils\log_x7_value_updater.txt
[00:51:35] Iniciando ejecución de x4.py en C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001...
[00:51:35] Using working directory: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001
[00:51:35] Los archivos de documentación generados se guardarán en: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\documentation
[00:51:35] Archivos JSON encontrados para procesar: 3
[00:51:35] --- Procesando archivo JSON: db1001_data.json ---
[00:51:35] Archivo JSON 'db1001_data.json' cargado correctamente.
[00:51:35] INFO: Usando '_begin_block_assignments_ordered' para generar bloque BEGIN de DB 'HMI_Blender_Parameters'.
[00:51:35] Archivo S7 reconstruido generado: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\documentation\db1001_data.txt
[00:51:35] Archivo Markdown de documentación generado: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\documentation\db1001_data.md
[00:51:35] --- Procesando archivo JSON: db1001_format.json ---
[00:51:35] Archivo JSON 'db1001_format.json' cargado correctamente.
[00:51:35] INFO: Usando '_begin_block_assignments_ordered' para generar bloque BEGIN de DB 'HMI_Blender_Parameters'.
[00:51:35] Archivo S7 reconstruido generado: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\documentation\db1001_format.txt
[00:51:35] Archivo Markdown de documentación generado: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\documentation\db1001_format.md
[00:51:35] --- Procesando archivo JSON: db1001_updated.json ---
[00:51:35] Archivo JSON 'db1001_updated.json' cargado correctamente.
[00:51:35] INFO: Usando '_begin_block_assignments_ordered' para generar bloque BEGIN de DB 'HMI_Blender_Parameters'.
[00:51:35] Archivo S7 reconstruido generado: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\documentation\db1001_updated.txt
[00:51:35] Archivo Markdown de documentación generado: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\documentation\db1001_updated.md
[00:51:35] --- Proceso de generación de documentación completado ---
[00:51:35] Ejecución de x4.py finalizada (success). Duración: 0:00:00.110751.
[00:51:35] Log completo guardado en: D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\S7_DB_Utils\log_x4.txt