Add x4.py for S7 source code generation and documentation

- Implemented functions to format data types, generate variable declarations, and create S7 source code from JSON data.
- Added recursive functions to handle STRUCTs and UDTs, including generating assignments for the BEGIN block.
- Created a Markdown documentation generator for DBs.
- Enhanced error handling and logging in x3.py, addressing issues with missing attributes in the DB_Parser module.
- Updated log.txt to reflect the execution flow and errors encountered during the process.
This commit is contained in:
Miguel 2025-05-17 14:06:22 +02:00
parent 7f5d7ff033
commit a82ef44fb8
23 changed files with 8126 additions and 10 deletions

View File

@ -0,0 +1,808 @@
import re
import os
import pandas as pd
import tkinter as tk
from tkinter import filedialog
import subprocess
from openpyxl import Workbook, load_workbook
from openpyxl.utils import get_column_letter
from openpyxl.styles import Alignment, Font, Border, Side, PatternFill
from copy import deepcopy
# Constantes para los tamaños de tipos de datos
TYPE_SIZES = {
"Byte": 1,
"Char": 1,
"Int": 2,
"DInt": 4,
"Word": 2,
"DWord": 4,
"Real": 4,
"Date": 2,
"Time": 4,
"Time_Of_Day": 4,
"S5Time": 2,
"Bool": 0.125, # 1 bit, normalmente agrupado en 8 bits = 1 Byte
"String": 256, # String[256] serían 258 bytes (256 caracteres + 2 para longitud)
"WString": 512,
"LReal": 8, # Punto flotante de doble precisión
"UDInt": 4, # Entero sin signo de 32 bits
"USInt": 1, # Entero sin signo de 8 bits (Byte)
"UInt": 2, # Entero sin signo de 16 bits (Word)
"ULInt": 8, # Entero sin signo de 64 bits (Doble DWord)
"LWord": 8, # Entero sin signo de 64 bits (Doble DWord)
"LInt": 8, # Entero con signo de 64 bits
"Date_And_Time": 8, # Fecha y hora combinadas, 8 bytes
"DTL": 12, # Date and time long (fecha, hora y precisión a microsegundos, 12 bytes)
}
#=================================
# FUNCIONES DE PARSEO DE ARCHIVOS
#=================================
def clean_line(line):
"""Limpia la línea de BOM y espacios o comillas extra."""
# Elimina UTF-8 BOM si existe y elimina espacios iniciales/finales
line = line.replace("\ufeff", "").strip()
# Estandariza las definiciones TYPE y DATA_BLOCK
line = re.sub(r'\s*TYPE\s+"?', 'TYPE "', line)
line = re.sub(r'\s*DATA_BLOCK\s+"?', 'DATA_BLOCK "', line)
line = remove_text_inside_brackets(line)
return line
def remove_text_inside_brackets(text):
"""Elimina texto dentro de corchetes."""
pattern = r"\{.*?\}"
cleaned_text = re.sub(pattern, '', text)
return cleaned_text
def extract_name(line):
"""Extrae el nombre de una línea de definición TYPE o DATA_BLOCK."""
# Intenta encontrar un nombre entrecomillado primero
match = re.search(r'(TYPE|DATA_BLOCK)\s+"([^"]+)"', line)
if match:
return match.group(2).strip() # El nombre está entre comillas
# Si no hay nombre entrecomillado, busca un nombre sin comillas
match = re.search(r"(TYPE|DATA_BLOCK)\s+(\S+)", line)
if match:
return match.group(2).strip() # El nombre está sin comillas
def parse_udts(lines):
"""Parsea User Defined Types de las líneas de código."""
udt_json = {}
udt_name = None
nested_structs = []
current_struct = None
is_within_struct = False
for line in lines:
line = clean_line(line)
if "TYPE" in line and "END_TYPE" not in line:
udt_name = extract_name(line)
udt_json[udt_name] = {}
current_struct = udt_json[udt_name]
print(f"Creado UDT: {udt_name}")
elif "END_TYPE" in line:
print(f"Completado UDT: {udt_name}")
udt_name = None
nested_structs = []
current_struct = None
is_within_struct = False
elif "STRUCT" in line and "END_STRUCT" not in line and udt_name is not None:
struct_name = (
"Struct" if "STRUCT" == line.strip() else line.split(":")[0].strip()
)
new_struct = {}
current_struct[struct_name] = new_struct
nested_structs.append(current_struct)
current_struct = new_struct
is_within_struct = True
print(f"Creado STRUCT: {struct_name}")
elif "END_STRUCT" in line and udt_name is not None:
current_struct = nested_structs.pop() if nested_structs else None
is_within_struct = bool(nested_structs)
print(f"Cerrado STRUCT en UDT '{udt_name}'")
elif udt_name and ":" in line and is_within_struct:
parts = line.split(":")
field_name = parts[0].strip()
field_details = parts[1].strip().split("//")
field_type = (
field_details[0].replace(";", "").strip()
) # Eliminando ';' del tipo de campo
field_comment = parts[1].split("//")[1].strip() if "//" in parts[1] else ""
if "Struct" in field_type:
new_struct = {}
current_struct[field_name] = new_struct
nested_structs.append(current_struct)
current_struct = new_struct
print(f"Abierto STRUCT en línea en el campo '{field_name}'")
else:
current_struct[field_name] = {
"type": field_type,
"comment": field_comment,
}
print(
f"Añadido campo '{field_name}' a STRUCT: Tipo={field_type}, Comentario={field_comment}"
)
return udt_json
def parse_dbs(lines, udts):
"""Parsea Data Blocks de las líneas de código."""
db_json = {}
db_name = None
nested_structs = []
current_struct = None
is_within_struct = False
for line in lines:
line = clean_line(line)
if "DATA_BLOCK" in line and "END_DATA_BLOCK" not in line:
db_name = extract_name(line)
db_json[db_name] = {}
current_struct = db_json[db_name]
print(f"Creado DATA_BLOCK: {db_name}")
elif "END_DATA_BLOCK" in line:
print(f"Completado DATA_BLOCK: {db_name}")
db_name = None
nested_structs = []
current_struct = None
is_within_struct = False
elif "STRUCT" in line and "END_STRUCT" not in line and db_name is not None:
struct_name = (
"Struct" if "STRUCT" == line.strip() else line.split(":")[0].strip()
)
new_struct = {}
current_struct[struct_name] = new_struct
nested_structs.append(current_struct)
current_struct = new_struct
is_within_struct = True
print(f"Creado STRUCT en DB '{db_name}': {struct_name}")
elif "END_STRUCT" in line and db_name is not None:
current_struct = nested_structs.pop() if nested_structs else None
is_within_struct = bool(nested_structs)
print(f"Cerrado STRUCT en DB '{db_name}'")
elif db_name and ":" in line and is_within_struct:
parts = line.split(":")
field_name = parts[0].strip()
field_details = parts[1].strip().split("//")
field_type = (
field_details[0].replace(";", "").strip()
) # Eliminando ';' del tipo de campo
field_comment = parts[1].split("//")[1].strip() if "//" in parts[1] else ""
if "Struct" in field_type:
new_struct = {}
current_struct[field_name] = new_struct
nested_structs.append(current_struct)
current_struct = new_struct
print(f"Abierto STRUCT en línea en el campo '{field_name}' en DB '{db_name}'")
else:
current_struct[field_name] = {
"type": field_type,
"comment": field_comment,
}
print(
f"Añadido campo '{field_name}' a STRUCT en DB '{db_name}': Tipo={field_type}, Comentario={field_comment}"
)
return db_json
#=================================
# FUNCIONES DE EXPANSIÓN DE UDT
#=================================
def expand_udt_references(db_struct, udts):
"""
Expande recursivamente las referencias UDT en la estructura DB utilizando las definiciones UDT.
"""
if isinstance(db_struct, dict):
for key, value in list(db_struct.items()):
if isinstance(value, dict):
# Recursión en diccionarios
expand_udt_references(value, udts)
elif isinstance(value, str) and key == "type": # Solo expande campos 'type'
type_name = value.strip(
'"'
) # Elimina comillas que pueden envolver nombres UDT con espacios
if type_name in udts:
# Reemplaza la referencia UDT con su definición copiada en profundidad
db_struct["is_udt_definition"] = True
db_struct["fields"] = deepcopy(udts[type_name])
print(f"Expandido UDT '{type_name}' en el campo '{key}'")
elif isinstance(db_struct, list):
for item in db_struct:
expand_udt_references(item, udts)
def handle_array_types(db_struct):
"""
Maneja tipos de arrays para expandirlos en múltiples campos como sub-elementos.
Esta función procesa completamente los arrays expandiéndolos en elementos individuales.
"""
if isinstance(db_struct, dict):
# Lista para almacenar nuevas entradas de array a agregar
new_entries = {}
# Lista de claves a eliminar después de procesar
keys_to_remove = []
for key, value in list(db_struct.items()):
if isinstance(value, dict):
# Procesa recursivamente diccionarios anidados
handle_array_types(value)
# Verificar si es un tipo array
if "type" in value and isinstance(value["type"], str):
array_match = re.match(r"ARRAY\s*\[(\d+)\s*\.\.\s*(\d+)\]\s*OF\s*(\w+)", value["type"], re.IGNORECASE)
if array_match:
lower_bound = int(array_match.group(1))
upper_bound = int(array_match.group(2))
base_type = array_match.group(3).strip()
comment = value.get("comment", "")
print(f"Expandiendo array '{key}': {lower_bound}..{upper_bound} of {base_type}")
# Marcar para eliminar la definición original después
keys_to_remove.append(key)
# Crear entrada para la definición del array
new_entries[key] = {
"type": f"Array[{lower_bound}..{upper_bound}] of {base_type}",
"comment": comment,
"is_array_definition": True
}
# Crear elementos individuales del array
for i in range(lower_bound, upper_bound + 1):
array_key = f"{key}[{i}]"
new_entries[array_key] = {
"type": base_type,
"comment": comment,
"is_array_element": True
}
# Eliminar los originales y agregar los nuevos
for key in keys_to_remove:
if key in db_struct:
del db_struct[key]
# Agregar las nuevas entradas
db_struct.update(new_entries)
def expand_dbs(udts, dbs):
"""
Expande todas las referencias UDT en todos los DBs y luego maneja tipos de arrays.
"""
for db_name, db_content in dbs.items():
print(f"Expandiendo DB: {db_name}")
# Primero expandir las referencias UDT
expand_udt_references(db_content, udts)
# Luego, manejar y expandir los tipos de arrays
print(f"Procesando arrays en DB: {db_name}")
handle_array_types(db_content)
print(f"Completada expansión para DB: {db_name}")
# Registrar el resultado de la expansión para depuración
print("\nEstructura DB después de la expansión:")
for db_name, db_content in dbs.items():
print(f"DB: {db_name} - Número de campos: {count_fields(db_content)}")
def count_fields(struct):
"""Función auxiliar para contar campos en una estructura."""
count = 0
if isinstance(struct, dict):
for key, value in struct.items():
if isinstance(value, dict):
if "type" in value:
count += 1
else:
count += count_fields(value)
return count
#=================================
# FUNCIONES DE CÁLCULO DE OFFSET
#=================================
def calculate_plc_address(type_name, byte_offset):
"""
Calcula la notación de dirección PLC basada en el tipo y offset.
"""
byte_size = TYPE_SIZES.get(type_name, 0)
bit_offset = int((byte_offset - int(byte_offset)) * 8)
byte_offset = int(byte_offset)
if type_name == "Bool":
return f"DBX{byte_offset}.{bit_offset}" # Dirección para bits individuales
elif type_name == "Byte":
return f"DBB{byte_offset}" # Dirección para bytes individuales
elif byte_size == 2:
return f"DBW{byte_offset}" # Dirección para words de dos bytes
elif byte_size == 4:
return f"DBD{byte_offset}" # Dirección para double words de cuatro bytes
else:
return f"DBX{byte_offset}.0" # Por defecto a dirección de bit para tipos de más de 4 bytes
def calculate_plc_size(size):
"""Calcula la representación del tamaño PLC."""
byte_size = size
bit_offset = int((size - int(size)) * 8)
size = int(size)
if bit_offset > 0:
return f"{size}.{bit_offset}"
else:
return f"{size}"
class OffsetState:
"""Clase para mantener el estado durante el cálculo de offset."""
def __init__(self):
self.last_key_was_bool = False
self.last_bit_offset = 0 # Para rastrear offsets de bit dentro de un byte
self.current_offset = 0
def calculate_offsets(value, state, field_name="unknown"):
"""Calcula offsets de memoria para elementos DB."""
type_name = value["type"].strip() # Eliminar espacios en blanco
is_array_element = value.get("is_array_element", False)
is_array_definition = value.get("array_definition", False)
is_udt_definition = value.get("is_udt_definition", False)
# No calculamos offsets para definiciones de array, solo para sus elementos
if is_array_definition:
print(f"→ Definición de array '{field_name}': no calculando offset")
return state
print(f"Calculando offset para '{field_name}' (Tipo: {type_name}, Offset actual: {state.current_offset})")
if state.last_key_was_bool:
is_array_element = True
size = 0
# Alineación a boundaries de datos
if not is_array_element:
if state.current_offset % 2 != 0:
old_offset = state.current_offset
state.current_offset += 1 # Alinea al siguiente offset par si no es elemento de array
print(f" → Alineación: Offset ajustado de {old_offset} a {state.current_offset}")
# Ajustando tamaños Bool basados en agrupación
if type_name.upper() == "BOOL":
state.last_key_was_bool = True
size += 1 / 8
print(f" → Tipo Bool detectado: usando {size} bytes")
else:
if state.last_key_was_bool: # Después de bools
state.last_key_was_bool = False # No es Bool
if (
state.last_bit_offset > 0
or int(state.current_offset) != state.current_offset
):
state.last_bit_offset = 0
old_offset = state.current_offset
state.current_offset = int(state.current_offset) + 1
print(f" → Post-Bool: Ajustando offset de {old_offset} a {state.current_offset}")
if state.current_offset % 2 != 0:
old_offset = state.current_offset
state.current_offset += 1 # Alinea al siguiente offset par
print(f" → Post-Bool: Alineación a par: {old_offset}{state.current_offset}")
# Manejo especial para tipos String
if type_name.upper().startswith("STRING"):
match = re.match(r"String\[(\d+)\]", type_name, re.IGNORECASE)
state.last_bit_offset = 0
if match:
length = int(match.group(1))
size = length + 2 # Cuenta para terminación nula y prefijo de longitud de cadena
print(f" → String[{length}] detectado: usando {size} bytes")
else:
size = TYPE_SIZES.get("String", 0) # Tamaño estándar para strings
print(f" → String genérico detectado: usando {size} bytes")
else: # Otros Tipos de Datos
# Buscar el tipo ignorando mayúsculas/minúsculas
type_upper = type_name.upper()
type_size = None
for key, value_size in TYPE_SIZES.items():
if key.upper() == type_upper:
type_size = value_size
break
if type_size is not None:
size = type_size
print(f" → Tipo {type_name} encontrado: usando {size} bytes")
else:
print(f" → ADVERTENCIA: Tipo {type_name} no reconocido directamente")
# Para arrays, manejo especial
if "ARRAY" in type_upper:
print(f" → Array detectado pero no se procesa directamente aquí")
size = 0 # Los arrays se procesarán elemento por elemento
else:
size = 2 # Asumimos INT por defecto
print(f" → Asumiendo tamaño de 2 bytes como valor predeterminado para {type_name}")
if size == 0 and not is_array_definition and not is_udt_definition:
print(f"⚠️ ADVERTENCIA: Tipo '{type_name}' tiene tamaño cero. Asumiendo 2 bytes.")
size = 2 # Tamaño mínimo
# Calcular dirección PLC
plc_address = calculate_plc_address(type_name, state.current_offset)
value["offset"] = state.current_offset
value["plc_address"] = plc_address # Almacena la dirección PLC calculada
value["size"] = calculate_plc_size(size)
# Actualizar offset y mostrar resultado
old_offset = state.current_offset
state.current_offset += size
print(f" → Resultado: Dirección={plc_address}, Tamaño={size}, Nuevo offset={state.current_offset}")
return state
def collect_data_for_table(db_struct, offset_state, level=0, parent_prefix="", collected_data=None, relative_offset=0):
"""
Recoge datos recursivamente de la estructura DB para mostrar en formato tabular.
Añade soporte para offsets relativos dentro de estructuras.
"""
if collected_data is None:
collected_data = []
is_array_element = False
increase_level = 0
current_struct_base = offset_state.current_offset
if isinstance(db_struct, dict):
for key, value in db_struct.items():
# Omite claves 'fields' y 'Struct' en la ruta de nombre
if key == "fields" or key == "Struct":
next_prefix = parent_prefix # Continúa con el prefijo actual
collect_data_for_table(value, offset_state, level, next_prefix, collected_data, relative_offset)
continue
# Determinar el prefijo de nombre para este elemento
if isinstance(value, dict):
is_array_element = value.get("is_array_element", False)
is_array_definition = value.get("array_definition", False)
# Construir el nombre del campo
if not is_array_element:
next_prefix = f"{parent_prefix}.{key}" if parent_prefix else key
else:
next_prefix = f"{parent_prefix}{key}" if parent_prefix else key
# Si es una definición de array, añadirla a la tabla sin calcular offset
if isinstance(value, dict) and value.get("array_definition", False):
field_data = {
"Nombre": next_prefix,
"Tipo": value.get("type", "N/A"),
"Offset": relative_offset,
"Dirección PLC": "N/A",
"Comentario": value.get("comment", ""),
}
collected_data.append(field_data)
print(f"✓ Añadida definición de array: {next_prefix} - (sin dirección)")
# No incrementar offset para definiciones de array, continuar con siguiente elemento
continue
# Procesar campo normal con tipo
if isinstance(value, dict) and "type" in value:
# Calcular offset si no es una definición de array
if not value.get("array_definition", False):
# Pasar el nombre del campo para mejorar los logs
offset_state = calculate_offsets(value, offset_state, field_name=next_prefix)
# Calcular offset relativo si es necesario
element_relative_offset = value.get("offset", 0) - current_struct_base
if is_array_element:
element_relative_offset = value.get("offset", 0) - offset_state.current_offset + relative_offset
field_data = {
"Nombre": next_prefix,
"Tipo": value.get("type", "N/A"),
"Offset": element_relative_offset if is_array_element else value.get("offset", 0),
"Dirección PLC": value.get("plc_address", "N/A"),
"Comentario": value.get("comment", ""),
}
collected_data.append(field_data)
increase_level = 1
print(f"✓ Añadido a tabla: {next_prefix} - {value.get('plc_address', 'N/A')}")
# Maneja recursivamente diccionarios y listas anidados
if isinstance(value, dict) and not "type" in value:
new_relative = offset_state.current_offset if not is_array_element else relative_offset
collect_data_for_table(
value,
offset_state,
level + increase_level,
next_prefix,
collected_data,
new_relative
)
elif isinstance(db_struct, list):
for index, item in enumerate(db_struct):
item_prefix = f"{parent_prefix}[{index}]" if parent_prefix else f"[{index}]"
collect_data_for_table(
item, offset_state, level + increase_level, item_prefix, collected_data, relative_offset
)
return collected_data
def initiate_conversion_to_table(db_struct):
"""Inicia el proceso de conversión con un estado de offset nuevo."""
offset_state = OffsetState()
return collect_data_for_table(db_struct, offset_state)
def convert_to_table(dbs):
"""
Convierte los datos DB recogidos en un DataFrame de pandas.
"""
all_data = []
for db_name, db_content in dbs.items():
print(f"Procesando DB: {db_name}")
db_data = initiate_conversion_to_table(db_content)
all_data.extend(db_data)
df = pd.DataFrame(all_data)
# Reordenar las columnas al formato deseado
if not df.empty and all(col in df.columns for col in ["Nombre", "Tipo", "Offset", "Dirección PLC", "Comentario"]):
df = df[["Nombre", "Tipo", "Offset", "Dirección PLC", "Comentario"]]
return df
#=================================
# FUNCIONES DE EXCEL
#=================================
def format_excel_worksheet(worksheet):
"""
Formatea la hoja de cálculo de Excel con estilos profesionales.
"""
# Definir estilos
header_font = Font(name='Arial', size=11, bold=True, color="FFFFFF")
header_fill = PatternFill(start_color="4472C4", end_color="4472C4", fill_type="solid")
array_fill = PatternFill(start_color="E2EFDA", end_color="E2EFDA", fill_type="solid")
struct_fill = PatternFill(start_color="DEEBF7", end_color="DEEBF7", fill_type="solid")
thin_border = Border(
left=Side(style='thin'),
right=Side(style='thin'),
top=Side(style='thin'),
bottom=Side(style='thin')
)
# Aplicar estilos a la fila de encabezado
for cell in worksheet[1]:
cell.font = header_font
cell.fill = header_fill
cell.alignment = Alignment(horizontal='center', vertical='center')
cell.border = thin_border
# Obtener el número de filas y columnas
max_row = worksheet.max_row
max_col = worksheet.max_column
# Aplicar estilos a las filas de datos
for row in range(2, max_row + 1):
# Verificar si es una estructura o array
cell_name = worksheet.cell(row=row, column=1).value if worksheet.cell(row=row, column=1).value else ""
cell_type = worksheet.cell(row=row, column=2).value if worksheet.cell(row=row, column=2).value else ""
# Aplicar fondos especiales para estructuras y arrays
is_struct = "Struct" in str(cell_type)
is_array = "Array" in str(cell_type)
# Aplicar bordes y alineación a todas las celdas
for col in range(1, max_col + 1):
cell = worksheet.cell(row=row, column=col)
cell.border = thin_border
# Aplicar color de fondo según el tipo
if is_struct:
cell.fill = struct_fill
elif is_array:
cell.fill = array_fill
# Centrar columnas numéricas
if col in [3, 4]:
cell.alignment = Alignment(horizontal='center')
# Ajustar ancho de columnas
column_widths = {
1: 30, # Nombre
2: 15, # Tipo
3: 10, # Offset
4: 15, # Dirección PLC
5: 30 # Comentario
}
# Importamos get_column_letter directamente de openpyxl.utils en las importaciones del script
for col_num, width in column_widths.items():
if col_num <= max_col:
worksheet.column_dimensions[get_column_letter(col_num)].width = width
# Congelar la fila del encabezado
worksheet.freeze_panes = "A2"
def save_dataframe_to_excel(df, filename, sheet_name):
"""
Guarda el DataFrame proporcionado en un archivo Excel y lo formatea.
"""
# Guardar el DataFrame en Excel
df.to_excel(filename, index=False, sheet_name=sheet_name)
print(f"Datos guardados en {filename}")
# Abrir el archivo Excel guardado para aplicar formato
workbook = load_workbook(filename)
worksheet = workbook[sheet_name]
# Aplicar formato a la hoja de cálculo
format_excel_worksheet(worksheet)
# Guardar el libro de trabajo formateado
workbook.save(filename)
print(f"Formato aplicado a {filename}")
return workbook, worksheet
#=================================
# FUNCIONES DE UTILIDAD DE ARCHIVOS
#=================================
def select_file():
"""
Abre un diálogo de archivo para seleccionar un archivo .db y devuelve la ruta del archivo seleccionado.
"""
root = tk.Tk()
root.withdraw() # Oculta la ventana raíz de tkinter
# Abre el diálogo de archivo y devuelve la ruta del archivo seleccionado
file_path = filedialog.askopenfilename(
title="Selecciona un archivo .db",
filetypes=(("Archivos DB", "*.db"), ("Todos los archivos", "*.*"))
)
return file_path
def extract_file_details(file_path):
"""
Extrae y devuelve el nombre del archivo sin extensión, la extensión del archivo y la ruta del archivo.
"""
# Extrae la ruta completa del directorio
path_only = os.path.dirname(file_path)
# Extrae el nombre completo del archivo con extensión
full_file_name = os.path.basename(file_path)
# Separa la extensión del nombre del archivo
file_name_without_extension, file_extension = os.path.splitext(full_file_name)
return (file_name_without_extension, file_extension, path_only)
def build_file_path(base_path, file_name, extension):
"""
Construye una ruta de archivo completa dada una ruta base, un nombre de archivo y una extensión.
"""
# Asegúrese de que la extensión esté en el formato correcto (es decir, comience con un punto)
if not extension.startswith('.'):
extension = '.' + extension
# Separe el nombre base del archivo de su extensión si está presente
file_name_without_extension, _ = os.path.splitext(file_name)
# Reconstruir el nombre del archivo con la extensión correcta
file_name_corrected = file_name_without_extension + extension
# Construir la ruta completa del archivo
full_path = os.path.join(base_path, file_name_corrected)
return full_path
def open_file_explorer(path):
"""
Abre el explorador de archivos en la ruta dada.
"""
# Normaliza la ruta para asegurarse de que esté en el formato correcto
normalized_path = os.path.normpath(path)
# Comprueba si la ruta es un directorio o un archivo y formatea el comando en consecuencia
if os.path.isdir(normalized_path):
# Si es un directorio, usa el comando 'explorer' directamente
command = f'explorer "{normalized_path}"'
else:
# Si es un archivo, usa el comando 'explorer /select,' para resaltar el archivo en su carpeta
command = f'explorer /select,"{normalized_path}"'
# Ejecuta el comando usando subprocess.run
subprocess.run(command, shell=True)
#=================================
# FUNCIÓN PRINCIPAL
#=================================
def main():
"""
Función principal para ejecutar la conversión de DB a Excel.
"""
print("==================================================")
print(" Convertidor de DB a Excel para Siemens S7 PLC")
print("==================================================\n")
# Seleccionar archivo
print("Por favor, seleccione un archivo .db para procesar:")
file_path = select_file()
if not file_path: # No se seleccionó ningún archivo
print("❌ No se seleccionó ningún archivo. Operación cancelada.")
return
print(f"✓ Archivo seleccionado: {file_path}")
try:
# Leer el contenido del archivo
with open(file_path, "r", encoding="utf-8-sig") as file:
lines = file.readlines()
# Extraer detalles del archivo
file_name, extension, dest_path = extract_file_details(file_path)
# Crear ruta de salida
excel_path = build_file_path(dest_path, file_name, "xlsx")
log_path = build_file_path(dest_path, f"{file_name}_log", "txt")
print("\n▶ Iniciando procesamiento del archivo DB...")
print(f" Nombre del archivo: {file_name}")
print(f" Ruta de destino: {excel_path}")
# Configurar logging a archivo
import sys
import datetime
original_stdout = sys.stdout
log_file = open(log_path, 'w', encoding='utf-8')
sys.stdout = log_file
print("=== LOG DE PROCESAMIENTO ===")
print(f"Archivo procesado: {file_path}")
print(f"Fecha de procesamiento: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print("============================\n")
# Parsear UDTs y DBs
print("\n=== PARSEANDO UDTs Y DBs ===")
udt_json = parse_udts(lines)
db_json = parse_dbs(lines, udt_json)
# Expandir DBs con definiciones UDT
print("\n=== EXPANDIENDO ESTRUCTURAS ===")
expand_dbs(udt_json, db_json)
# Convertir a tabla
print("\n=== CALCULANDO OFFSETS Y DIRECCIONES ===")
df = convert_to_table(db_json)
# Restaurar stdout para mostrar mensajes en la consola
sys.stdout = original_stdout
log_file.close()
# Guardar en Excel
print("\n▶ Generando archivo Excel...")
workbook, worksheet = save_dataframe_to_excel(df, excel_path, file_name)
# Mostrar resumen
print("\n=== RESUMEN DE CONVERSIÓN ===")
print(f"✓ Total de variables procesadas: {len(df)}")
print(f"✓ Tamaño total del DB: {df['Offset'].max() if not df.empty else 0} bytes")
print(f"✓ Archivo Excel generado: {excel_path}")
print(f"✓ Archivo de log generado: {log_path}")
print("\n✅ ¡Conversión completada con éxito!")
# Abrir el archivo de salida en el Explorador
print("\n▶ Abriendo el archivo Excel en el Explorador...")
open_file_explorer(excel_path)
except Exception as e:
print(f"\n❌ ERROR: Se produjo un error durante la conversión:")
print(f" {str(e)}")
import traceback
traceback.print_exc()
print("\nPor favor, revise el archivo de entrada y vuelva a intentarlo.")
# Ejecutar la función principal cuando se ejecuta el script
if __name__ == "__main__":
main()

View File

@ -0,0 +1 @@
{}

View File

@ -0,0 +1,550 @@
DATA_BLOCK "HMI_Blender_Parameters"
TITLE =
{ S7_language := '28(1) Albanese 15.06.2005 17:07:04' }
FAMILY : Resource
VERSION : 0.0
STRUCT
STAT0 : STRUCT
STAT1 : STRUCT
STAT2 : INT := 6;
STAT3 : REAL := 2.000000e-01;
STAT4 : REAL := 8.000000e-01;
STAT5 : BOOL := TRUE;
STAT6 : BOOL ;
STAT7 : BOOL ;
STAT8 : BOOL ;
STAT9 : BOOL ;
STAT10 : BOOL ;
STAT11 : BOOL := TRUE;
STAT12 : BOOL ;
STAT13 : BOOL := TRUE;
STAT14 : BOOL ;
STAT15 : BOOL ;
STAT16 : BOOL ;
STAT17 : BOOL ;
STAT18 : BOOL := TRUE;
STAT19 : BOOL ;
STAT20 : BOOL ;
STAT21 : INT := 6;
STAT22 : BOOL ;
STAT23 : BOOL ;
STAT24 : BOOL ;
STAT25 : BOOL ;
STAT26 : BOOL ;
STAT27 : BOOL := TRUE;
STAT28 : BOOL := TRUE;
STAT29 : INT := 1;
STAT30 : BOOL := TRUE;
STAT31 : INT := 4;
STAT32 : INT ;
STAT33 : BOOL ;
STAT34 : BOOL ;
STAT35 : BOOL ;
STAT36 : BOOL ;
STAT37 : BOOL ;
STAT38 : BOOL := TRUE;
STAT39 : BOOL ;
STAT40 : BOOL ;
STAT41 : BOOL := TRUE;
STAT42 : BOOL ;
STAT43 : BOOL := TRUE;
STAT44 : BOOL ;
STAT45 : BOOL := TRUE;
STAT46 : BOOL ;
STAT47 : BOOL ;
STAT48 : BOOL := TRUE;
STAT49 : INT ;
STAT50 : INT := 2;
STAT51 : BOOL := TRUE;
STAT52 : BOOL ;
STAT53 : BOOL ;
STAT54 : BOOL ;
STAT55 : BOOL ;
STAT56 : BOOL ;
STAT57 : BOOL ;
STAT58 : BOOL := TRUE;
STAT59 : BOOL ;
STAT60 : BOOL ;
STAT61 : BOOL ;
STAT62 : BOOL ;
STAT63 : BOOL ;
STAT64 : BOOL := TRUE;
STAT65 : BOOL ;
STAT66 : BOOL ;
STAT67 : INT := 1;
STAT68 : INT ;
STAT69 : INT := 1;
STAT70 : INT ;
STAT71 : INT ;
STAT72 : INT := 6;
END_STRUCT ;
END_STRUCT ;
STAT73 : ARRAY [1 .. 9 ] OF INT ;
STAT74 : REAL := 5.000000e-02;
STAT75 : REAL := 6.500000e+01;
STAT76 : STRUCT
STAT77 : STRING [32 ] := ' ';
STAT78 : BOOL ;
STAT79 : BOOL ;
STAT80 : BOOL ;
STAT81 : BOOL ;
STAT82 : BOOL ;
STAT83 : BOOL ;
STAT84 : BOOL ;
STAT85 : BOOL ;
STAT86 : BYTE ;
STAT87 : BYTE ;
STAT88 : BYTE ;
STAT89 : INT := 1;
STAT90 : INT ;
STAT91 : REAL := 5.000000e+01;
STAT92 : REAL := 1.255800e+00;
STAT93 : REAL := 1.000000e+00;
STAT94 : REAL := 1.045000e+01;
STAT95 : REAL := 9.000000e+02;
STAT96 : REAL := 2.000000e+01;
STAT97 : REAL ;
STAT98 : REAL ;
STAT99 : REAL := 1.000000e+00;
STAT100 : REAL := 1.000000e+00;
STAT101 : REAL := 1.000000e+01;
STAT102 : REAL := 1.000000e+01;
STAT103 : REAL ;
STAT104 : REAL ;
STAT105 : REAL ;
STAT106 : REAL ;
STAT107 : REAL ;
STAT108 : REAL ;
STAT109 : REAL ;
STAT110 : REAL ;
STAT111 : REAL ;
STAT112 : REAL ;
STAT113 : REAL ;
STAT114 : REAL ;
STAT115 : REAL ;
STAT116 : REAL ;
STAT117 : REAL := 9.700000e-01;
STAT118 : REAL ;
STAT119 : REAL := 1.000000e+00;
STAT120 : REAL ;
STAT121 : REAL ;
STAT122 : INT ;
STAT123 : REAL ;
STAT124 : REAL ;
STAT125 : REAL ;
STAT126 : REAL ;
END_STRUCT ;
STAT127 : ARRAY [1 .. 5 ] OF INT ;
STAT128 : STRING [32 ] := ' ';
STAT129 : INT ;
STAT130 : ARRAY [1 .. 18 ] OF INT ;
STAT131 : STRUCT
STAT132 : REAL ;
STAT133 : REAL ;
STAT134 : REAL := 1.580000e-03;
STAT135 : REAL := 9.000000e-03;
STAT136 : REAL := 1.700000e-02;
STAT137 : REAL := 5.700000e+00;
STAT138 : REAL := 2.000000e+00;
STAT139 : REAL := 2.000000e+00;
STAT140 : REAL := 1.000000e+01;
STAT141 : REAL := 1.000000e+01;
STAT142 : REAL := 1.000000e+01;
STAT143 : REAL := 6.000000e+01;
STAT144 : REAL := 5.000000e+01;
STAT145 : REAL := 2.500000e+01;
STAT146 : REAL := 6.500000e+01;
STAT147 : REAL := 1.200000e+01;
STAT148 : REAL := 1.000000e+01;
STAT149 : REAL ;
STAT150 : REAL := 3.000000e+01;
STAT151 : REAL := 1.000000e+00;
STAT152 : REAL := 5.000000e+00;
STAT153 : REAL := 5.000000e+00;
STAT154 : REAL := 1.000000e+02;
STAT155 : REAL := 2.000000e+02;
STAT156 : REAL := 2.000000e+01;
STAT157 : REAL := 2.000000e+01;
STAT158 : REAL := 2.000000e+01;
STAT159 : INT := 1;
STAT160 : REAL := 2.000000e+01;
STAT161 : REAL := 7.000000e-01;
STAT162 : REAL := 4.250000e+02;
STAT163 : REAL := 2.550000e+03;
STAT164 : REAL := 9.000000e+00;
STAT165 : REAL ;
STAT166 : REAL := 1.600000e+03;
STAT167 : REAL := 2.000000e+01;
STAT168 : REAL := 1.400000e+01;
STAT169 : REAL := 1.610000e+03;
STAT170 : REAL := 2.877000e+03;
STAT171 : INT := 80;
STAT172 : REAL := 8.000000e+01;
STAT173 : REAL := 9.000000e+01;
STAT174 : REAL := 4.000000e+00;
STAT175 : REAL := 1.020000e+03;
STAT176 : REAL := 1.000000e+02;
STAT177 : REAL := 2.300000e+03;
STAT178 : REAL := 7.500000e-01;
STAT179 : REAL := 5.000000e-01;
STAT180 : REAL := 3.000000e-02;
STAT181 : REAL := 1.400000e-03;
STAT182 : REAL ;
STAT183 : WORD := W#16#6;
STAT184 : WORD := W#16#50;
STAT185 : WORD := W#16#1;
STAT186 : REAL := 3.000000e+01;
STAT187 : REAL := 4.000000e+01;
STAT188 : REAL := 9.000000e+01;
STAT189 : REAL := 2.500000e+02;
STAT190 : REAL := 5.500000e-01;
STAT191 : REAL := 4.000000e-01;
STAT192 : REAL := 9.000000e-01;
STAT193 : REAL := 1.500000e+01;
STAT194 : REAL := 4.500000e+01;
STAT195 : REAL := 5.000000e+01;
STAT196 : REAL := 4.000000e+00;
STAT197 : REAL := 2.000000e+01;
STAT198 : REAL := 5.000000e+00;
STAT199 : REAL := 5.000000e+00;
STAT200 : REAL := 5.000000e+00;
STAT201 : REAL := 5.000000e+00;
STAT202 : REAL := 1.000000e+01;
STAT203 : REAL ;
STAT204 : REAL := 1.150000e+02;
STAT205 : REAL := 1.650000e+02;
STAT206 : REAL := 2.600000e+02;
STAT207 : REAL := 1.650000e+02;
STAT208 : REAL := 6.700000e+01;
STAT209 : INT := 50;
STAT210 : REAL := 9.000000e+01;
STAT211 : REAL := 8.700000e+01;
STAT212 : REAL := 5.070000e+02;
STAT213 : REAL := 2.110000e+02;
STAT214 : REAL := 8.600000e+01;
STAT215 : REAL := 8.500000e+01;
STAT216 : REAL := 1.150000e+02;
STAT217 : REAL := 3.200000e+01;
STAT218 : REAL := 5.000000e+00;
STAT219 : REAL := 5.000000e+00;
STAT220 : REAL ;
STAT221 : REAL ;
STAT222 : REAL ;
STAT223 : REAL ;
STAT224 : REAL := 1.800000e+01;
STAT225 : REAL := 2.000000e+00;
STAT226 : REAL := 2.000000e+00;
STAT227 : REAL := 5.000000e+01;
STAT228 : REAL := 5.000000e+01;
STAT229 : DINT := L#1500;
STAT230 : DINT := L#1500;
STAT231 : DINT := L#1000;
STAT232 : DINT := L#1000;
STAT233 : INT := 30;
STAT234 : INT := 30;
STAT235 : INT := 10;
STAT236 : INT := 10;
STAT237 : INT := 10;
STAT238 : REAL := 3.500000e+02;
STAT239 : INT := 30;
STAT240 : INT := 30;
STAT241 : INT := 30;
STAT242 : INT := 30;
STAT243 : INT := 30;
STAT244 : INT := 30;
STAT245 : INT := 30;
STAT246 : INT := 30;
STAT247 : REAL := 3.000000e+01;
STAT248 : REAL := 3.000000e+01;
STAT249 : REAL ;
STAT250 : REAL ;
STAT251 : REAL ;
STAT252 : REAL := 5.000000e+01;
END_STRUCT ;
STAT253 : BOOL ;
STAT254 : REAL ;
END_STRUCT ;
BEGIN
STAT0.STAT1.STAT2 := 6;
STAT0.STAT1.STAT3 := 4.500000e-01;
STAT0.STAT1.STAT4 := 8.000000e-01;
STAT0.STAT1.STAT5 := TRUE;
STAT0.STAT1.STAT6 := FALSE;
STAT0.STAT1.STAT7 := FALSE;
STAT0.STAT1.STAT8 := FALSE;
STAT0.STAT1.STAT9 := TRUE;
STAT0.STAT1.STAT10 := FALSE;
STAT0.STAT1.STAT11 := TRUE;
STAT0.STAT1.STAT12 := FALSE;
STAT0.STAT1.STAT13 := TRUE;
STAT0.STAT1.STAT14 := FALSE;
STAT0.STAT1.STAT15 := FALSE;
STAT0.STAT1.STAT16 := FALSE;
STAT0.STAT1.STAT17 := FALSE;
STAT0.STAT1.STAT18 := TRUE;
STAT0.STAT1.STAT19 := FALSE;
STAT0.STAT1.STAT20 := FALSE;
STAT0.STAT1.STAT21 := 6;
STAT0.STAT1.STAT22 := FALSE;
STAT0.STAT1.STAT23 := FALSE;
STAT0.STAT1.STAT24 := FALSE;
STAT0.STAT1.STAT25 := TRUE;
STAT0.STAT1.STAT26 := FALSE;
STAT0.STAT1.STAT27 := TRUE;
STAT0.STAT1.STAT28 := TRUE;
STAT0.STAT1.STAT29 := 1;
STAT0.STAT1.STAT30 := TRUE;
STAT0.STAT1.STAT31 := 4;
STAT0.STAT1.STAT32 := 0;
STAT0.STAT1.STAT33 := FALSE;
STAT0.STAT1.STAT34 := FALSE;
STAT0.STAT1.STAT35 := FALSE;
STAT0.STAT1.STAT36 := FALSE;
STAT0.STAT1.STAT37 := FALSE;
STAT0.STAT1.STAT38 := TRUE;
STAT0.STAT1.STAT39 := FALSE;
STAT0.STAT1.STAT40 := FALSE;
STAT0.STAT1.STAT41 := TRUE;
STAT0.STAT1.STAT42 := FALSE;
STAT0.STAT1.STAT43 := TRUE;
STAT0.STAT1.STAT44 := FALSE;
STAT0.STAT1.STAT45 := TRUE;
STAT0.STAT1.STAT46 := FALSE;
STAT0.STAT1.STAT47 := FALSE;
STAT0.STAT1.STAT48 := TRUE;
STAT0.STAT1.STAT49 := 0;
STAT0.STAT1.STAT50 := 2;
STAT0.STAT1.STAT51 := TRUE;
STAT0.STAT1.STAT52 := FALSE;
STAT0.STAT1.STAT53 := FALSE;
STAT0.STAT1.STAT54 := FALSE;
STAT0.STAT1.STAT55 := FALSE;
STAT0.STAT1.STAT56 := FALSE;
STAT0.STAT1.STAT57 := FALSE;
STAT0.STAT1.STAT58 := TRUE;
STAT0.STAT1.STAT59 := TRUE;
STAT0.STAT1.STAT60 := FALSE;
STAT0.STAT1.STAT61 := FALSE;
STAT0.STAT1.STAT62 := FALSE;
STAT0.STAT1.STAT63 := FALSE;
STAT0.STAT1.STAT64 := TRUE;
STAT0.STAT1.STAT65 := FALSE;
STAT0.STAT1.STAT66 := FALSE;
STAT0.STAT1.STAT67 := 1;
STAT0.STAT1.STAT68 := 0;
STAT0.STAT1.STAT69 := 1;
STAT0.STAT1.STAT70 := 0;
STAT0.STAT1.STAT71 := 0;
STAT0.STAT1.STAT72 := 6;
STAT73[1] := 0;
STAT73[2] := 0;
STAT73[3] := 0;
STAT73[4] := 0;
STAT73[5] := 0;
STAT73[6] := 0;
STAT73[7] := 0;
STAT73[8] := 0;
STAT73[9] := 0;
STAT74 := 5.000000e-02;
STAT75 := 9.000000e+01;
STAT76.STAT77 := '';
STAT76.STAT78 := TRUE;
STAT76.STAT79 := FALSE;
STAT76.STAT80 := FALSE;
STAT76.STAT81 := FALSE;
STAT76.STAT82 := FALSE;
STAT76.STAT83 := TRUE;
STAT76.STAT84 := FALSE;
STAT76.STAT85 := FALSE;
STAT76.STAT86 := B#16#0;
STAT76.STAT87 := B#16#14;
STAT76.STAT88 := B#16#0;
STAT76.STAT89 := 2;
STAT76.STAT90 := 1;
STAT76.STAT91 := 3.935000e+01;
STAT76.STAT92 := 1.166600e+00;
STAT76.STAT93 := 1.000000e+00;
STAT76.STAT94 := 8.600000e+00;
STAT76.STAT95 := 2.500000e-01;
STAT76.STAT96 := 3.934034e+00;
STAT76.STAT97 := 4.000000e-01;
STAT76.STAT98 := 2.500000e+00;
STAT76.STAT99 := 9.000000e-01;
STAT76.STAT100 := 3.500000e+00;
STAT76.STAT101 := 1.600000e+01;
STAT76.STAT102 := 3.500000e+01;
STAT76.STAT103 := 0.000000e+00;
STAT76.STAT104 := 0.000000e+00;
STAT76.STAT105 := 0.000000e+00;
STAT76.STAT106 := 8.800000e+00;
STAT76.STAT107 := 8.400000e+00;
STAT76.STAT108 := 2.800000e+00;
STAT76.STAT109 := 2.200000e+00;
STAT76.STAT110 := 0.000000e+00;
STAT76.STAT111 := 0.000000e+00;
STAT76.STAT112 := 0.000000e+00;
STAT76.STAT113 := 0.000000e+00;
STAT76.STAT114 := 0.000000e+00;
STAT76.STAT115 := 0.000000e+00;
STAT76.STAT116 := 0.000000e+00;
STAT76.STAT117 := 8.500000e-01;
STAT76.STAT118 := 0.000000e+00;
STAT76.STAT119 := 0.000000e+00;
STAT76.STAT120 := 0.000000e+00;
STAT76.STAT121 := 0.000000e+00;
STAT76.STAT122 := 0;
STAT76.STAT123 := 0.000000e+00;
STAT76.STAT124 := 0.000000e+00;
STAT76.STAT125 := 0.000000e+00;
STAT76.STAT126 := 0.000000e+00;
STAT127[1] := 0;
STAT127[2] := 0;
STAT127[3] := 0;
STAT127[4] := 0;
STAT127[5] := 0;
STAT128 := '';
STAT129 := 0;
STAT130[1] := 0;
STAT130[2] := 0;
STAT130[3] := 0;
STAT130[4] := 0;
STAT130[5] := 0;
STAT130[6] := 0;
STAT130[7] := 0;
STAT130[8] := 0;
STAT130[9] := 0;
STAT130[10] := 0;
STAT130[11] := 0;
STAT130[12] := 0;
STAT130[13] := 0;
STAT130[14] := 0;
STAT130[15] := 0;
STAT130[16] := 0;
STAT130[17] := 0;
STAT130[18] := 0;
STAT131.STAT132 := 0.000000e+00;
STAT131.STAT133 := 0.000000e+00;
STAT131.STAT134 := 1.000000e-03;
STAT131.STAT135 := 7.800000e-03;
STAT131.STAT136 := 1.390000e-02;
STAT131.STAT137 := 5.700000e+00;
STAT131.STAT138 := 2.000000e+00;
STAT131.STAT139 := 2.200000e+00;
STAT131.STAT140 := 2.100000e+01;
STAT131.STAT141 := 2.000000e+01;
STAT131.STAT142 := 5.000000e+00;
STAT131.STAT143 := 6.000000e+01;
STAT131.STAT144 := 5.000000e+01;
STAT131.STAT145 := 2.500000e+01;
STAT131.STAT146 := 4.000000e+01;
STAT131.STAT147 := 2.400000e+01;
STAT131.STAT148 := 1.400000e+01;
STAT131.STAT149 := 3.000000e-01;
STAT131.STAT150 := 3.000000e+01;
STAT131.STAT151 := 1.000000e+00;
STAT131.STAT152 := 4.000000e+00;
STAT131.STAT153 := 2.000000e+00;
STAT131.STAT154 := 1.000000e+02;
STAT131.STAT155 := 5.000000e+02;
STAT131.STAT156 := 5.000000e+01;
STAT131.STAT157 := 8.000000e+00;
STAT131.STAT158 := 1.900000e+01;
STAT131.STAT159 := 1;
STAT131.STAT160 := 2.000000e+02;
STAT131.STAT161 := 5.000000e-01;
STAT131.STAT162 := 4.500000e+02;
STAT131.STAT163 := 2.500000e+03;
STAT131.STAT164 := 1.220000e+01;
STAT131.STAT165 := 1.000000e+00;
STAT131.STAT166 := 3.950000e+02;
STAT131.STAT167 := -2.500000e+01;
STAT131.STAT168 := 3.618000e+01;
STAT131.STAT169 := 1.400000e+03;
STAT131.STAT170 := 2.520000e+03;
STAT131.STAT171 := 91;
STAT131.STAT172 := 1.000000e+02;
STAT131.STAT173 := 1.600000e+02;
STAT131.STAT174 := 3.200000e+00;
STAT131.STAT175 := 1.050000e+03;
STAT131.STAT176 := 4.600000e+01;
STAT131.STAT177 := 1.625000e+03;
STAT131.STAT178 := 1.000000e+00;
STAT131.STAT179 := 1.300000e+00;
STAT131.STAT180 := 4.090000e-02;
STAT131.STAT181 := 1.400000e-03;
STAT131.STAT182 := 4.500000e+02;
STAT131.STAT183 := W#16#0;
STAT131.STAT184 := W#16#78;
STAT131.STAT185 := W#16#1;
STAT131.STAT186 := 3.000000e+01;
STAT131.STAT187 := 4.000000e+01;
STAT131.STAT188 := 3.000000e+01;
STAT131.STAT189 := 5.000000e+00;
STAT131.STAT190 := 4.900000e-01;
STAT131.STAT191 := 3.000000e-01;
STAT131.STAT192 := 9.000000e-01;
STAT131.STAT193 := 1.500000e+01;
STAT131.STAT194 := 3.500000e+01;
STAT131.STAT195 := 5.000000e+01;
STAT131.STAT196 := 4.000000e+00;
STAT131.STAT197 := 2.000000e+01;
STAT131.STAT198 := 5.000000e+00;
STAT131.STAT199 := 5.000000e+00;
STAT131.STAT200 := 5.000000e+00;
STAT131.STAT201 := 5.000000e+00;
STAT131.STAT202 := 6.000000e+01;
STAT131.STAT203 := 0.000000e+00;
STAT131.STAT204 := 1.500000e+02;
STAT131.STAT205 := 1.650000e+02;
STAT131.STAT206 := 2.600000e+02;
STAT131.STAT207 := 1.650000e+02;
STAT131.STAT208 := 6.700000e+01;
STAT131.STAT209 := 300;
STAT131.STAT210 := 9.000000e+01;
STAT131.STAT211 := 8.700000e+01;
STAT131.STAT212 := 5.070000e+02;
STAT131.STAT213 := 2.110000e+02;
STAT131.STAT214 := 8.600000e+01;
STAT131.STAT215 := 8.500000e+01;
STAT131.STAT216 := 1.150000e+02;
STAT131.STAT217 := 3.200000e+01;
STAT131.STAT218 := 5.000000e+00;
STAT131.STAT219 := 5.000000e+00;
STAT131.STAT220 := 0.000000e+00;
STAT131.STAT221 := 0.000000e+00;
STAT131.STAT222 := 0.000000e+00;
STAT131.STAT223 := 0.000000e+00;
STAT131.STAT224 := 2.000000e+01;
STAT131.STAT225 := 5.000000e+00;
STAT131.STAT226 := 1.000000e+01;
STAT131.STAT227 := 5.000000e+01;
STAT131.STAT228 := 5.000000e+01;
STAT131.STAT229 := L#1500;
STAT131.STAT230 := L#1500;
STAT131.STAT231 := L#1000;
STAT131.STAT232 := L#1000;
STAT131.STAT233 := 30;
STAT131.STAT234 := 30;
STAT131.STAT235 := 10;
STAT131.STAT236 := 10;
STAT131.STAT237 := 10;
STAT131.STAT238 := 3.500000e+02;
STAT131.STAT239 := 30;
STAT131.STAT240 := 30;
STAT131.STAT241 := 30;
STAT131.STAT242 := 30;
STAT131.STAT243 := 30;
STAT131.STAT244 := 30;
STAT131.STAT245 := 30;
STAT131.STAT246 := 30;
STAT131.STAT247 := 3.000000e+01;
STAT131.STAT248 := 3.000000e+01;
STAT131.STAT249 := 0.000000e+00;
STAT131.STAT250 := 0.000000e+00;
STAT131.STAT251 := 0.000000e+00;
STAT131.STAT252 := 5.000000e+01;
STAT253 := FALSE;
STAT254 := 0.000000e+00;
END_DATA_BLOCK

View File

@ -0,0 +1,467 @@
Address;Name;;Type;Initial value;Actual value;Comment
0.0;Processor_Options.Blender_OPT._ModelNum;;INT;6;6;
2.0;Processor_Options.Blender_OPT._CO2_Offset;;REAL;4.500000e-01;4.500000e-01;
6.0;Processor_Options.Blender_OPT._MaxSyrDeltaBrix;;REAL;8.000000e-01;8.000000e-01;
10.0;Processor_Options.Blender_OPT._BrixMeter;;BOOL;TRUE;TRUE;
10.1;Processor_Options.Blender_OPT.Spare101;;BOOL;FALSE;FALSE;
10.2;Processor_Options.Blender_OPT._TrackH2OEnable;;BOOL;FALSE;FALSE;
10.3;Processor_Options.Blender_OPT._PAmPDSType;;BOOL;FALSE;FALSE;"0)Cobrix 200
0 1)Carbo 2 000"
10.4;Processor_Options.Blender_OPT._HistoricalTrends;;BOOL;TRUE;TRUE;"0)Not Presen
t 1)Present"
10.5;Processor_Options.Blender_OPT._PowerMeter;;BOOL;FALSE;FALSE;"0)Not Presen
t 1)Present"
10.6;Processor_Options.Blender_OPT._Report;;BOOL;TRUE;TRUE;"0)Not Presen
t 1)Present"
10.7;Processor_Options.Blender_OPT._Balaiage;;BOOL;FALSE;FALSE;
11.0;Processor_Options.Blender_OPT._Valves_FullFeedback;;BOOL;TRUE;TRUE;"Valves contr
ol Full feed back"
11.1;Processor_Options.Blender_OPT._Valves_SingleFeedback;;BOOL;FALSE;FALSE;"Valves contr
ol Single fe edback"
11.2;Processor_Options.Blender_OPT._PumpsSafetySwitches;;BOOL;FALSE;FALSE;"Pumps with S
afety Switch es"
11.3;Processor_Options.Blender_OPT._SurgeProtectionAct;;BOOL;FALSE;FALSE;
11.4;Processor_Options.Blender_OPT._DBC_Type;;BOOL;FALSE;FALSE;"0) Deox,Carb
o,Blend 1)D eox,Blend,Ca rbo"
11.5;Processor_Options.Blender_OPT._CO2InletMeter;;BOOL;TRUE;TRUE;"0)Not Presen
t 1)Present"
11.6;Processor_Options.Blender_OPT._ProductO2Meter;;BOOL;FALSE;FALSE;"0)Not Presen
t 1)Present"
11.7;Processor_Options.Blender_OPT._CopressedAirInletMeter;;BOOL;FALSE;FALSE;"0)Not Presen
t 1)Present"
12.0;Processor_Options.Blender_OPT._MeterType;;INT;6;6;"1)Maselli 2)
AntoonPaar 3
)4-20mA 4)UC 05 UR22 5)mP DSPA 6)MR02"
14.0;Processor_Options.Blender_OPT._MeterReceiveOnly;;BOOL;FALSE;FALSE;
14.1;Processor_Options.Blender_OPT._SyrBrixMeter;;BOOL;FALSE;FALSE;
14.2;Processor_Options.Blender_OPT._Flooding_Start_Up;;BOOL;FALSE;FALSE;"0)Not Select
ed 1)Sele cted"
14.3;Processor_Options.Blender_OPT._FastChangeOverEnabled;;BOOL;TRUE;TRUE;
14.4;Processor_Options.Blender_OPT._WaterInletMeter;;BOOL;FALSE;FALSE;"0)Not Presen
t 1)Present"
14.5;Processor_Options.Blender_OPT._BlendFillSystem;;BOOL;TRUE;TRUE;
14.6;Processor_Options.Blender_OPT._TrackFillerSpeed;;BOOL;TRUE;TRUE;
16.0;Processor_Options.Blender_OPT._SignalExchange;;INT;1;1;"FILLER - 0=
Hardwire; 1= Ethernet"
18.0;Processor_Options.Blender_OPT._CoolerPresent;;BOOL;TRUE;TRUE;
20.0;Processor_Options.Blender_OPT._CoolerControl;;INT;4;4;"0)External 1
)Water 2)Pro duct 3)Water
+Product-2 C trl 4)Water+ Product-1 Ct
rl"
22.0;Processor_Options.Blender_OPT._CoolerType;;INT;0;0;"0)Glycol 1)A
mmonia"
24.0;Processor_Options.Blender_OPT._LocalCIP;;BOOL;FALSE;FALSE;
24.1;Processor_Options.Blender_OPT._ICS_CustomerHotWater;;BOOL;FALSE;FALSE;"0)No Hot Wat
er from Cust omer 1)Hot W ater from Cu stomer Avail able"
24.2;Processor_Options.Blender_OPT._ICS_CustomerChemRecov;;BOOL;FALSE;FALSE;"0)No Custome
r's Chemical s Recovery 1
)Customer's Chemicals Re covery Avail
able"
24.3;Processor_Options.Blender_OPT._CIPSignalExchange;;BOOL;FALSE;FALSE;"CIP - 0= Har
dwire; 1= Et hernet"
24.4;Processor_Options.Blender_OPT._ICS_CustomerChemicals;;BOOL;FALSE;FALSE;"0)Chemicals
from ICS 1)C hemicals fro m Customer"
24.5;Processor_Options.Blender_OPT._CarboPresent;;BOOL;TRUE;TRUE;
24.6;Processor_Options.Blender_OPT._InverterSyrupPumpPPP302;;BOOL;FALSE;FALSE;"0)Not Presen
t 1)Present"
24.7;Processor_Options.Blender_OPT._InverterWaterPumpPPN301;;BOOL;FALSE;FALSE;"0)Not Presen
t 1)Present"
25.0;Processor_Options.Blender_OPT._DoubleDeair;;BOOL;TRUE;TRUE;
25.1;Processor_Options.Blender_OPT._DeairPreMixed;;BOOL;FALSE;FALSE;"Deox Premixe
d Inlet"
25.2;Processor_Options.Blender_OPT._Deaireation;;BOOL;TRUE;TRUE;"0)SAG 1)SAE/
SAF"
25.3;Processor_Options.Blender_OPT._StillWaterByPass;;BOOL;FALSE;FALSE;
25.4;Processor_Options.Blender_OPT._ManifoldSetting;;BOOL;TRUE;TRUE;"0)Manual 1)A
utomatic"
25.5;Processor_Options.Blender_OPT._InverterProdPumpPPM303;;BOOL;FALSE;FALSE;
25.6;Processor_Options.Blender_OPT._SidelCip;;BOOL;FALSE;FALSE;
25.7;Processor_Options.Blender_OPT._EthernetCom_CpuPN_CP;;BOOL;TRUE;TRUE;"0)Comunicati
on with CP 1)Comunicat
ion with CPU
PN"
26.0;Processor_Options.Blender_OPT._2ndOutlet;;INT;0;0;"0)No 2nd Out
let 1)2nd O utlet No Sta ndalone 2)2 nd Outlet St andalone"
28.0;Processor_Options.Blender_OPT._Promass;;INT;2;2;
30.0;Processor_Options.Blender_OPT._WaterPromass;;BOOL;TRUE;TRUE;"0)Promag 1)P
romass"
30.1;Processor_Options.Blender_OPT._ProductConductimeter;;BOOL;FALSE;FALSE;
30.2;Processor_Options.Blender_OPT._ICS_CustomerH2ORecov;;BOOL;FALSE;FALSE;"0)No Custome
r's H2O Reco very 1)Custo mer's H2O Re covery Avail able"
30.3;Processor_Options.Blender_OPT.Spare303;;BOOL;FALSE;FALSE;
30.4;Processor_Options.Blender_OPT._CO2_GAS2_Injection;;BOOL;FALSE;FALSE;"0)Only CO2 I
njection 1)G AS2 Injectio n"
30.5;Processor_Options.Blender_OPT._InverterVacuuPumpPPN304;;BOOL;FALSE;FALSE;"0)Not Presen
t 1)Present"
30.6;Processor_Options.Blender_OPT._InverterBoostPumpPPM307;;BOOL;FALSE;FALSE;"0)Not Presen
t 1)Present"
30.7;Processor_Options.Blender_OPT._RunOut_Water;;BOOL;TRUE;TRUE;"0)Syrup Runo
ut without W ater 1)Syrup runout with Water pushi
ng"
31.0;Processor_Options.Blender_OPT._FlowMeterType;;BOOL;FALSE;TRUE;"0)Endrees Ha
user -- 1)Mi cromotion"
31.1;Processor_Options.Blender_OPT._SidelFiller;;BOOL;FALSE;FALSE;"0)Filler Sim
onazzi -- 1)Filler Sid el Filling"
31.2;Processor_Options.Blender_OPT._Simulation;;BOOL;FALSE;FALSE;
31.3;Processor_Options.Blender_OPT._ProductCoolingCTRL;;BOOL;FALSE;FALSE;"0)none 1) TT
M307"
31.4;Processor_Options.Blender_OPT._ChillerCTRL;;BOOL;FALSE;FALSE;"Chiller Pres
sure Cross C ontrol"
31.5;Processor_Options.Blender_OPT._CO2_SterileFilter;;BOOL;TRUE;TRUE;"CO2 Inlet wi
th Steril Fi lter"
31.6;Processor_Options.Blender_OPT._InverterRecirPumpPPM306;;BOOL;FALSE;FALSE;"0)Not Presen
t 1)Present"
31.7;Processor_Options.Blender_OPT._ProdPressReleaseRVM304;;BOOL;FALSE;FALSE;"0)Not Presen
t 1)Present"
32.0;Processor_Options.Blender_OPT._VacuumPump;;INT;1;1;"0)None 1)Ste
rling 2)Nash Elmo"
34.0;Processor_Options.Blender_OPT._GAS2InjectionType;;INT;0;0;"0)None 1)N2
2)Steril Air"
36.0;Processor_Options.Blender_OPT._InjectionPress_Ctrl;;INT;1;1;"0)Manual 1)N
orgren v1 2) Norgren v2"
38.0;Processor_Options.Blender_OPT._ProdPressureType;;INT;0;0;"0)Only CO2 1
)CO2+SterilA ir 2)CO2+N2"
40.0;Processor_Options.Blender_OPT._CIPHeatType;;INT;0;0;"0)Steam 1)El
ectric"
42.0;Processor_Options.Blender_OPT._EHS_NrRes;;INT;6;6;"Number of He
at Resistanc es"
44.0;Spare1[1];;INT;0;0;
46.0;Spare1[2];;INT;0;0;
48.0;Spare1[3];;INT;0;0;
50.0;Spare1[4];;INT;0;0;
52.0;Spare1[5];;INT;0;0;
54.0;Spare1[6];;INT;0;0;
56.0;Spare1[7];;INT;0;0;
58.0;Spare1[8];;INT;0;0;
60.0;Spare1[9];;INT;0;0;
62.0;_RVM301_DeadBand;;REAL;5.000000e-02;5.000000e-02;
66.0;_RVM301_Kp;;REAL;9.000000e+01;9.000000e+01;
70.0;Actual_Recipe_Parameters._Name;;STRING [ 32 ];"'
'";'';
104.0;Actual_Recipe_Parameters._EnProdTemp;;BOOL;FALSE;TRUE;
104.1;Actual_Recipe_Parameters._SyrFlushing;;BOOL;FALSE;FALSE;"Ex_EnDeairea
tion --> DEL ETED - AVP32
0 VALVE OPEN"
104.2;Actual_Recipe_Parameters._GAS2_Injection;;BOOL;FALSE;FALSE;"0 = GAS2 not
present; 1
= GAS2 prese nt"
104.3;Actual_Recipe_Parameters._Eq_Pression_Selected;;BOOL;FALSE;FALSE;
104.4;Actual_Recipe_Parameters._DeoxStripEn;;BOOL;FALSE;FALSE;"******Deaira
tion with St rip Enable"
104.5;Actual_Recipe_Parameters._DeoxVacuumEn;;BOOL;FALSE;TRUE;"******Deaira
tion with Va cuum"
104.6;Actual_Recipe_Parameters._DeoxPreMixed;;BOOL;FALSE;FALSE;"******Deaira
tion of Prem ixed Product"
104.7;Actual_Recipe_Parameters._EnBlowOffProdPipeCO2Fil;;BOOL;FALSE;FALSE;
105.0;Actual_Recipe_Parameters._WaterSelection;;BYTE;B#16#0;B#16#0;
106.0;Actual_Recipe_Parameters._FillerNextRecipeNum;;BYTE;B#16#0;B#16#0;
107.0;Actual_Recipe_Parameters._BottleShape;;BYTE;B#16#0;B#16#0;
108.0;Actual_Recipe_Parameters._Type;;INT;1;2;"1= DIET; 2=
REGULAR; 3=
RATIO; 4= WA TER"
110.0;Actual_Recipe_Parameters._ProdMeterRecipeNum;;INT;0;1;
112.0;Actual_Recipe_Parameters._SyrupBrix;;REAL;5.000000e+01;4.625000e+01;
116.0;Actual_Recipe_Parameters._SyrupDensity;;REAL;1.255800e+00;1.206908e+00;
120.0;Actual_Recipe_Parameters._SyrupFactor;;REAL;1.000000e+00;1.000000e+00;
124.0;Actual_Recipe_Parameters._ProductBrix;;REAL;1.045000e+01;1.000000e+01;
128.0;Actual_Recipe_Parameters._ProductionRate;;REAL;9.000000e+02;3.800000e+02;
132.0;Actual_Recipe_Parameters._Ratio;;REAL;2.000000e+01;4.238896e+00;
136.0;Actual_Recipe_Parameters._ProdBrixOffset;;REAL;0.000000e+00;2.500000e-01;
140.0;Actual_Recipe_Parameters._CO2Vols;;REAL;0.000000e+00;2.550000e+00;
144.0;Actual_Recipe_Parameters._CO2Fact;;REAL;1.000000e+00;9.400000e-01;
148.0;Actual_Recipe_Parameters._ProdTankPress;;REAL;1.000000e+00;4.400000e+00;
152.0;Actual_Recipe_Parameters._SP_ProdTemp;;REAL;1.000000e+01;1.700000e+01;
156.0;Actual_Recipe_Parameters._PrdTankMinLevel;;REAL;1.000000e+01;3.500000e+01;
160.0;Actual_Recipe_Parameters._WaterValveSave;;REAL;0.000000e+00;0.000000e+00;
164.0;Actual_Recipe_Parameters._SyrupValveSave;;REAL;0.000000e+00;0.000000e+00;
168.0;Actual_Recipe_Parameters._CarboCO2ValveSave;;REAL;0.000000e+00;0.000000e+00;
172.0;Actual_Recipe_Parameters._ProdMeterHighBrix;;REAL;0.000000e+00;1.030000e+01;
176.0;Actual_Recipe_Parameters._ProdMeterLowBrix;;REAL;0.000000e+00;9.830000e+00;
180.0;Actual_Recipe_Parameters._ProdMeterHighCO2;;REAL;0.000000e+00;2.900000e+00;
184.0;Actual_Recipe_Parameters._ProdMeterLowCO2;;REAL;0.000000e+00;2.300000e+00;
188.0;Actual_Recipe_Parameters._ProdMeter_ZeroCO2;;REAL;0.000000e+00;0.000000e+00;
192.0;Actual_Recipe_Parameters._ProdMeter_ZeroBrix;;REAL;0.000000e+00;0.000000e+00;
196.0;Actual_Recipe_Parameters._ProdHighCond;;REAL;0.000000e+00;0.000000e+00;
200.0;Actual_Recipe_Parameters._ProdLowCond;;REAL;0.000000e+00;0.000000e+00;
204.0;Actual_Recipe_Parameters._BottleSize;;REAL;0.000000e+00;0.000000e+00;
208.0;Actual_Recipe_Parameters._FillingValveHead_SP;;REAL;0.000000e+00;0.000000e+00;
212.0;Actual_Recipe_Parameters._SyrMeter_ZeroBrix;;REAL;0.000000e+00;0.000000e+00;
216.0;Actual_Recipe_Parameters._FirstProdExtraCO2Fact;;REAL;9.700000e-01;1.020000e+00;
220.0;Actual_Recipe_Parameters._Gas2Vols;;REAL;0.000000e+00;0.000000e+00;
224.0;Actual_Recipe_Parameters._Gas2Fact;;REAL;1.000000e+00;0.000000e+00;
228.0;Actual_Recipe_Parameters._SyrupPumpPressure;;REAL;0.000000e+00;0.000000e+00;"******Syrup
Pump Pressur e SP"
232.0;Actual_Recipe_Parameters._WaterPumpPressure;;REAL;0.000000e+00;0.000000e+00;"******Water
Pump Pressur e SP"
236.0;Actual_Recipe_Parameters._CO2_Air_N2_PressSelect;;INT;0;0;"1=CO2; 2=CO2
+SterilAir; 3=CO2+N2 - P
ressure Tank
Selection"
238.0;Actual_Recipe_Parameters._KFactRVM304BlowOff;;REAL;0.000000e+00;0.000000e+00;
242.0;Actual_Recipe_Parameters._ProdRecircPumpFreq;;REAL;0.000000e+00;0.000000e+00;
246.0;Actual_Recipe_Parameters._ProdBoosterPumpPress;;REAL;0.000000e+00;0.000000e+00;
250.0;Actual_Recipe_Parameters._ProdSendPumpFreq;;REAL;0.000000e+00;0.000000e+00;"******Produc
t Sending Pu mp Frequency
SP"
254.0;Spare2[1];;INT;0;0;
256.0;Spare2[2];;INT;0;0;
258.0;Spare2[3];;INT;0;0;
260.0;Spare2[4];;INT;0;0;
262.0;Spare2[5];;INT;0;0;
264.0;Next_Recipe_Name;;STRING [ 32 ];"'
'";"'cambio 1$00$00$
00$00$00$00$00$0
0$00$00$00$00$00
$00$00$00$00$00$ 00$00$00$00'";
298.0;Next_Recipe_Number;;INT;0;0;
300.0;Spare3[1];;INT;0;0;
302.0;Spare3[2];;INT;0;0;
304.0;Spare3[3];;INT;0;0;
306.0;Spare3[4];;INT;0;0;
308.0;Spare3[5];;INT;0;0;
310.0;Spare3[6];;INT;0;0;
312.0;Spare3[7];;INT;0;0;
314.0;Spare3[8];;INT;0;0;
316.0;Spare3[9];;INT;0;0;
318.0;Spare3[10];;INT;0;0;
320.0;Spare3[11];;INT;0;0;
322.0;Spare3[12];;INT;0;0;
324.0;Spare3[13];;INT;0;0;
326.0;Spare3[14];;INT;0;0;
328.0;Spare3[15];;INT;0;0;
330.0;Spare3[16];;INT;0;0;
332.0;Spare3[17];;INT;0;0;
334.0;Spare3[18];;INT;0;0;
336.0;ProcessSetup.Spare000;;REAL;0.000000e+00;0.000000e+00;
340.0;ProcessSetup.Spare040;;REAL;0.000000e+00;0.000000e+00;
344.0;ProcessSetup._KWaterLoss;;REAL;1.000000e-03;1.000000e-03;"Friction Los
s Constant i n Serpentine"
348.0;ProcessSetup._KSyrupLoss;;REAL;7.800000e-03;7.800000e-03;"Friction Los
s Constant i n Syrup Pipe"
352.0;ProcessSetup._KProdLoss;;REAL;1.390000e-02;1.390000e-02;"Pressure Los
s Factor"
356.0;ProcessSetup._KPPM303;;REAL;5.700000e+00;5.700000e+00;"Frequency Ov
erpressure P ump P3 Const ant [Hz/mm]"
360.0;ProcessSetup._BaialageRVM301OVMin;;REAL;2.000000e+00;2.000000e+00;"Baialage Min
imum Flow (N m3/h)"
364.0;ProcessSetup._SyrupLinePressure;;REAL;2.200000e+00;2.200000e+00;"Syrup Line p
ressure at V EP2 valve"
368.0;ProcessSetup._CIPRMM301OV;;REAL;1.000000e+01;1.000000e+01;"Water Valve
Opening Duri ng CIP"
372.0;ProcessSetup._CIPRMP302OV;;REAL;1.500000e+01;1.500000e+01;"Syrup Valve
Opening Duri ng CIP"
376.0;ProcessSetup._CIPTM301MinLevel;;REAL;3.500000e+01;3.500000e+01;"Product Tank
Minimum Lev el In CIP"
380.0;ProcessSetup._CIPTM301MaxLevel;;REAL;5.500000e+01;5.500000e+01;"Product Tank
Maximum Lev el In CIP"
384.0;ProcessSetup._CIPPPM303Freq;;REAL;5.000000e+01;5.000000e+01;"CIP frequenc
y Value [Hz]"
388.0;ProcessSetup._CIPTP301MinLevel;;REAL;2.500000e+01;2.500000e+01;"Syrup Tank M
inimum Level In CIP"
392.0;ProcessSetup._CIPTP301MaxLevel;;REAL;4.500000e+01;4.500000e+01;"Syrup Tank M
aximum Level In CIP"
396.0;ProcessSetup._RinseRMM301OV;;REAL;1.000000e+01;1.000000e+01;"Water Valve
Opening Duri ng Rinse"
400.0;ProcessSetup._RinseRMP302OV;;REAL;1.400000e+01;1.400000e+01;"Syrup Valve
Opening Duri ng Rinse"
404.0;ProcessSetup._RinseTM301Press;;REAL;3.000000e-01;3.000000e-01;"Product Tank
Pressure In Rinse"
408.0;ProcessSetup._RinsePPM303Freq;;REAL;5.000000e+01;5.000000e+01;"Rinse freque
ncy Value [H z]"
412.0;ProcessSetup._DrainTM301Press;;REAL;1.000000e+00;1.000000e+00;"Buffer Tank
Draining Pre ssure"
416.0;ProcessSetup._KRecBlendError;;REAL;2.000000e+00;2.000000e+00;"Blend Error
Recovery CON STANT"
420.0;ProcessSetup._KRecCarboCO2Error;;REAL;2.000000e+00;2.000000e+00;"Carbonation
Error Recove ry Constant"
424.0;ProcessSetup._MaxBlendError;;REAL;1.000000e+02;1.000000e+02;"Blend Error
Maximum Valu e"
428.0;ProcessSetup._MaxCarboCO2Error;;REAL;5.000000e+02;5.000000e+02;"Carbonation
Error Maximu m Value"
432.0;ProcessSetup._StartUpBrixExtraWater;;REAL;4.700000e+01;4.700000e+01;
436.0;ProcessSetup._StartUpCO2ExtraWater;;REAL;8.000000e+00;8.000000e+00;
440.0;ProcessSetup._StartUpPPM303Freq;;REAL;2.000000e+01;2.000000e+01;"Start Up fre
quency Value [Hz]"
444.0;ProcessSetup._SyrupRoomTank;;INT;1;1;
446.0;ProcessSetup._SyrupRunOutLiters;;REAL;2.900000e+02;2.900000e+02;
450.0;ProcessSetup._InjCO2Press_Offset;;REAL;5.000000e-01;5.000000e-01;
454.0;ProcessSetup._InjCO2Press_MinFlow;;REAL;4.500000e+02;4.500000e+02;
458.0;ProcessSetup._InjCO2Press_MaxFlow;;REAL;2.500000e+03;2.500000e+03;
462.0;ProcessSetup._CarboCO2Pressure;;REAL;1.250000e+01;1.250000e+01;"CO2 Pressure
Infeed Line"
466.0;ProcessSetup._N2MinPressure;;REAL;1.000000e+00;1.000000e+00;"N2 Minimum P
ressure Infe ed Line"
470.0;ProcessSetup._DiffSensor_Height;;REAL;3.950000e+02;3.950000e+02;"Sensor Heigh
t from Soil [mm]"
474.0;ProcessSetup._DiffSensor_DeltaHeight;;REAL;-2.500000e+01;-2.500000e+01;"Sensor Plate
s Height Dif ference [mm]"
478.0;ProcessSetup._DiffSensor_Offset;;REAL;3.618000e+01;3.618000e+01;"Sensor Offse
t Read with zero pressur e (all valve s open) in [ mm]"
482.0;ProcessSetup._FillingValveHeight;;REAL;1.400000e+03;1.400000e+03;"Filling Valv
e Height fro m soil [mm]"
486.0;ProcessSetup._FillerDiameter;;REAL;2.520000e+03;2.520000e+03;"Filler Carou
sel Diameter [mm]"
490.0;ProcessSetup._FillingValveNum;;INT;91;91;"Filling Valv
es Number"
492.0;ProcessSetup._FillerProdPipeDN;;REAL;1.000000e+02;1.000000e+02;
496.0;ProcessSetup._FillerProdPipeMass;;REAL;1.600000e+02;1.600000e+02;
500.0;ProcessSetup._FillingTime;;REAL;3.200000e+00;3.200000e+00;
504.0;ProcessSetup._TM301Height_0;;REAL;1.050000e+03;1.050000e+03;"Level at 0%
Tank Level Height in mm"
508.0;ProcessSetup._TM301LevelPerc_2;;REAL;4.600000e+01;4.600000e+01;"Second level
percentage"
512.0;ProcessSetup._TM301Height_2;;REAL;1.625000e+03;1.625000e+03;"Second level
Height in m m"
516.0;ProcessSetup._RVN304Factor;;REAL;1.000000e+00;1.000000e+00;"DeareationFl
ow/WaterFlow"
520.0;ProcessSetup._DrainTM301Flushing;;REAL;1.300000e+00;1.300000e+00;
524.0;ProcessSetup._FirstProdExtraBrix;;REAL;5.000000e-02;5.000000e-02;
528.0;ProcessSetup._FirstProdDietExtraSyr;;REAL;1.400000e-03;1.400000e-03;
532.0;ProcessSetup._EndProdLastSyrlt;;REAL;0.000000e+00;0.000000e+00;"End Producti
on Last syru p liters"
536.0;ProcessSetup._TM301DrainSt0Time;;WORD;W#16#A;W#16#A;sec
538.0;ProcessSetup._TM301DrainSt1Time;;WORD;W#16#50;W#16#50;sec
540.0;ProcessSetup._ProdPipeRunOutSt0Time;;WORD;W#16#1;W#16#1;sec
542.0;ProcessSetup._RMM301ProdPipeRunOu;;REAL;3.000000e+01;3.000000e+01;
546.0;ProcessSetup._RMP302ProdPipeRunOu;;REAL;4.000000e+01;4.000000e+01;
550.0;ProcessSetup._ProdPipeRunOutAmount;;REAL;3.000000e+01;3.000000e+01;
554.0;ProcessSetup._TM301RunOutChiller;;REAL;5.000000e+00;5.000000e+00;
558.0;ProcessSetup._MinSpeedNominalProd;;REAL;4.000000e-01;4.000000e-01;"Min Speed fo
r Nominal Pr oduction"
562.0;ProcessSetup._MinSpeedSlowProd;;REAL;3.000000e-01;3.000000e-01;"Min Speed fo
r Very Low P roduction"
566.0;ProcessSetup._FastChgOvrTM301DrnPrss;;REAL;9.000000e-01;9.000000e-01;"Fast Change
Over Product Tank Draini
ng Pressure
in Blendfill"
570.0;ProcessSetup._CIPTN301MinLevel;;REAL;3.500000e+01;3.500000e+01;"Deaireator T
ank Minimum Level In CIP"
574.0;ProcessSetup._CIPTN301MaxLevel;;REAL;6.000000e+01;6.000000e+01;"Deaireator T
ank Maximum Level In CIP"
578.0;ProcessSetup._ProdPPN304Freq;;REAL;5.000000e+01;5.000000e+01;
582.0;ProcessSetup._GAS2InjectionPress;;REAL;4.000000e+00;4.000000e+00;
586.0;ProcessSetup._BaialageRVM301OVMax;;REAL;2.000000e+01;2.000000e+01;"Baialage Pro
duction Flow Multiplier"
590.0;ProcessSetup._RinsePPN301Freq;;REAL;5.000000e+00;5.000000e+00;
594.0;ProcessSetup._CIPPPN301Freq;;REAL;5.000000e+00;5.000000e+00;
598.0;ProcessSetup._RinsePPP302Freq;;REAL;5.000000e+00;5.000000e+00;
602.0;ProcessSetup._CIPPPP302Freq;;REAL;5.000000e+00;5.000000e+00;
606.0;ProcessSetup._PercSyrupBrixSyrStarUp;;REAL;2.500000e+01;2.500000e+01;
610.0;ProcessSetup._RefTempCoolingCTRL;;REAL;0.000000e+00;0.000000e+00;
614.0;ProcessSetup._H2OSerpPrimingVolume;;REAL;1.500000e+02;1.500000e+02;"Water Serpen
tine Volume
+ Water Chil ler Volume"
618.0;ProcessSetup._AVN301_Nozzle_Kv;;REAL;1.650000e+02;1.650000e+02;"AVN301 Nozzl
e Kv"
622.0;ProcessSetup._AVN302_Nozzle_Kv;;REAL;2.600000e+02;2.600000e+02;"AVN302 Nozzl
e Kv"
626.0;ProcessSetup._AVN303_Nozzle_Kv;;REAL;1.650000e+02;1.650000e+02;"AVN303 Nozzl
e Kv"
630.0;ProcessSetup._DeoxSpryball_Kv;;REAL;6.700000e+01;6.700000e+01;"Deox Sprybal
l Kv"
634.0;ProcessSetup._PremixedLineDrainTime;;INT;300;300;"Premixed Pro
duct Line Dr ain Time"
636.0;ProcessSetup._PPN301_H_MaxFlow;;REAL;9.000000e+01;9.000000e+01;"PPN301 Pump
Head with Ma x Flow [m]"
640.0;ProcessSetup._PPN301_H_MinFlow;;REAL;8.700000e+01;8.700000e+01;"PPN301 Pump
Head with Mi n Flow [m]"
644.0;ProcessSetup._PPN301_MaxFlow;;REAL;5.070000e+02;5.070000e+02;"PPN301 Max F
low [l/min]"
648.0;ProcessSetup._PPN301_MinFlow;;REAL;2.110000e+02;2.110000e+02;"PPN301 Min F
low [l/min]"
652.0;ProcessSetup._PPP302_H_MaxFlow;;REAL;8.600000e+01;8.600000e+01;"PPP302 Pump
Head with Ma x Flow [m]"
656.0;ProcessSetup._PPP302_H_MinFlow;;REAL;8.500000e+01;8.500000e+01;"PPP302 Pump
Head with Mi n Flow [m]"
660.0;ProcessSetup._PPP302_MaxFlow;;REAL;1.150000e+02;1.150000e+02;"PPP302 Max F
low [l/min]"
664.0;ProcessSetup._PPP302_MinFlow;;REAL;3.200000e+01;3.200000e+01;"PPP302 Min F
low [l/min]"
668.0;ProcessSetup._RinsePPM306Freq;;REAL;5.000000e+00;5.000000e+00;
672.0;ProcessSetup._CIPPPM306Freq;;REAL;5.000000e+00;5.000000e+00;
676.0;ProcessSetup._PPM307_H_MaxFlow;;REAL;0.000000e+00;0.000000e+00;"PPM307 Pump
Head with Ma x Flow [m]"
680.0;ProcessSetup._PPM307_H_MinFlow;;REAL;0.000000e+00;0.000000e+00;"PPM307 Pump
Head with Mi n Flow [m]"
684.0;ProcessSetup._PPM307_MaxFlow;;REAL;0.000000e+00;0.000000e+00;"PPM307 Max F
low [l/min]"
688.0;ProcessSetup._PPM307_MinFlow;;REAL;0.000000e+00;0.000000e+00;"PPM307 Min F
low [l/min]"
692.0;ProcessSetup._Temp0_VacuumCtrl;;REAL;1.800000e+01;1.800000e+01;"PPN304 Targe
t Temperatur e
- OPTION
PPN304 Sterl ing Type"
696.0;ProcessSetup._Temp1_VacuumCtrl;;REAL;2.000000e+00;2.000000e+00;"PPN304 High
Treshold Tem perature Del ta - OPTION
PPN304 Sterl
ing Type"
700.0;ProcessSetup._Temp2_VacuumCtrl;;REAL;2.000000e+00;2.000000e+00;"PPN304 Low T
reshold Temp erature Delt a - OPTION
PPN304 Sterl
ing Type"
704.0;ProcessSetup._Temp3_VacuumCtrl;;REAL;5.000000e+01;5.000000e+01;"PPN304 Warni
ng Temperatu re
- OPTION
PPN304 Sterl ing Type"
708.0;ProcessSetup._Temp4_VacuumCtrl;;REAL;5.000000e+01;5.000000e+01;"PPN304 Alarm
Temperature
- OPTION
PPN304 Sterl ing Type"
712.0;ProcessSetup._T1_VacuumCtrl;;DINT;L#1500;L#1500;"PPN304 Time
1 [msec]
- OPTION
PPN304 Sterl ing Type"
716.0;ProcessSetup._T2_VacuumCtrl;;DINT;L#1500;L#1500;"PPN304 Time
2 [msec]
- OPTION
PPN304 Sterl ing Type"
720.0;ProcessSetup._T3_VacuumCtrl;;DINT;L#1000;L#1000;"PPN304 Time
3 [msec]
- OPTION
PPN304 Sterl ing Type"
724.0;ProcessSetup._T4_VacuumCtrl;;DINT;L#1000;L#1000;"PPN304 Time
4 [msec]
- OPTION
PPN304 Sterl ing Type"
728.0;ProcessSetup._ICS_VolDosWorkTimePAA;;INT;30;30;"ICS - DS - D
osing Workin g Time [sec]"
730.0;ProcessSetup._ICS_VolPauseTimePAA;;INT;30;30;"ICS - DS - D
osing Pause Time [sec]"
732.0;ProcessSetup._ICS_PAAPulseWeight;;INT;10;10;"ICS - DS - P
AA Pulse Wei ght [(L/Puls e)/100]"
734.0;ProcessSetup._ICS_CausticPulseWeight;;INT;10;10;"ICS - DS - C
austic Pulse Weight [(L/
Pulse)/100]"
736.0;ProcessSetup._ICS_AcidPulseWeight;;INT;10;10;"ICS - DS - A
cid Pulse We ight [(L/Pul se)/100]"
738.0;ProcessSetup._ICS_VolumeRestOfLine;;REAL;3.500000e+02;3.500000e+02;"ICS - DS - V
olume of the Rest of the Line (Fille
r + Piping)
[L]"
742.0;ProcessSetup._ICS_VolDosWorkTimeCaus;;INT;30;30;"ICS - DS - D
osing Workin g Time [sec]"
744.0;ProcessSetup._ICS_VolDosPauseTimeCaus;;INT;30;30;"ICS - DS - D
osing Pause Time [sec]"
746.0;ProcessSetup._ICS_VolDosWorkTimeAcid;;INT;30;30;"ICS - DS - D
osing Workin g Time [sec]"
748.0;ProcessSetup._ICS_VolDosPauseTimeAcid;;INT;30;30;"ICS - DS - D
osing Pause Time [sec]"
750.0;ProcessSetup._ICS_ConcDosWorkTimeCaus;;INT;30;30;"ICS - DS - D
osing Workin g Time [sec]"
752.0;ProcessSetup._ICS_ConcDosPausTimeCaus;;INT;30;30;"ICS - DS - D
osing Pause Time [sec]"
754.0;ProcessSetup._ICS_ConcDosWorkTimeAcid;;INT;30;30;"ICS - DS - D
osing Workin g Time [sec]"
756.0;ProcessSetup._ICS_ConcDosPausTimeAcid;;INT;30;30;"ICS - DS - D
osing Pause Time [sec]"
758.0;ProcessSetup._RinsePPM307Freq;;REAL;3.000000e+01;3.000000e+01;
762.0;ProcessSetup._CIPPPM307Freq;;REAL;3.000000e+01;3.000000e+01;
766.0;ProcessSetup._CIP2StepTN301Lvl;;REAL;0.000000e+00;0.000000e+00;"Local CIP -
2 Step loadi ng TN301 Lev el"
770.0;ProcessSetup._CIP2StepTM301Lvl;;REAL;0.000000e+00;0.000000e+00;"Local CIP -
2 Step loadi ng TM301 Lev el"
774.0;ProcessSetup._CIP2StepTP301Lvl;;REAL;0.000000e+00;0.000000e+00;"Local CIP -
2 Step loadi ng TP301 Lev el"
778.0;ProcessSetup._PumpNominalFreq;;REAL;5.000000e+01;5.000000e+01;"50.0 Hz or 6
0.0 Hz"
782.0;_SwitchOff_DensityOK;;BOOL;FALSE;FALSE;
1 Address Name Type Initial value Actual value Comment
2 0.0 Processor_Options.Blender_OPT._ModelNum INT 6 6
3 2.0 Processor_Options.Blender_OPT._CO2_Offset REAL 4.500000e-01 4.500000e-01
4 6.0 Processor_Options.Blender_OPT._MaxSyrDeltaBrix REAL 8.000000e-01 8.000000e-01
5 10.0 Processor_Options.Blender_OPT._BrixMeter BOOL TRUE TRUE
6 10.1 Processor_Options.Blender_OPT.Spare101 BOOL FALSE FALSE
7 10.2 Processor_Options.Blender_OPT._TrackH2OEnable BOOL FALSE FALSE
8 10.3 Processor_Options.Blender_OPT._PAmPDSType BOOL FALSE FALSE 0)Cobrix 200 0 1)Carbo 2 000
9 10.4 Processor_Options.Blender_OPT._HistoricalTrends BOOL TRUE TRUE 0)Not Presen t 1)Present
10 10.5 Processor_Options.Blender_OPT._PowerMeter BOOL FALSE FALSE 0)Not Presen t 1)Present
11 10.6 Processor_Options.Blender_OPT._Report BOOL TRUE TRUE 0)Not Presen t 1)Present
12 10.7 Processor_Options.Blender_OPT._Balaiage BOOL FALSE FALSE
13 11.0 Processor_Options.Blender_OPT._Valves_FullFeedback BOOL TRUE TRUE Valves contr ol Full feed back
14 11.1 Processor_Options.Blender_OPT._Valves_SingleFeedback BOOL FALSE FALSE Valves contr ol Single fe edback
15 11.2 Processor_Options.Blender_OPT._PumpsSafetySwitches BOOL FALSE FALSE Pumps with S afety Switch es
16 11.3 Processor_Options.Blender_OPT._SurgeProtectionAct BOOL FALSE FALSE
17 11.4 Processor_Options.Blender_OPT._DBC_Type BOOL FALSE FALSE 0) Deox,Carb o,Blend 1)D eox,Blend,Ca rbo
18 11.5 Processor_Options.Blender_OPT._CO2InletMeter BOOL TRUE TRUE 0)Not Presen t 1)Present
19 11.6 Processor_Options.Blender_OPT._ProductO2Meter BOOL FALSE FALSE 0)Not Presen t 1)Present
20 11.7 Processor_Options.Blender_OPT._CopressedAirInletMeter BOOL FALSE FALSE 0)Not Presen t 1)Present
21 12.0 Processor_Options.Blender_OPT._MeterType INT 6 6 1)Maselli 2) AntoonPaar 3 )4-20mA 4)UC 05 UR22 5)mP DSPA 6)MR02
22 14.0 Processor_Options.Blender_OPT._MeterReceiveOnly BOOL FALSE FALSE
23 14.1 Processor_Options.Blender_OPT._SyrBrixMeter BOOL FALSE FALSE
24 14.2 Processor_Options.Blender_OPT._Flooding_Start_Up BOOL FALSE FALSE 0)Not Select ed 1)Sele cted
25 14.3 Processor_Options.Blender_OPT._FastChangeOverEnabled BOOL TRUE TRUE
26 14.4 Processor_Options.Blender_OPT._WaterInletMeter BOOL FALSE FALSE 0)Not Presen t 1)Present
27 14.5 Processor_Options.Blender_OPT._BlendFillSystem BOOL TRUE TRUE
28 14.6 Processor_Options.Blender_OPT._TrackFillerSpeed BOOL TRUE TRUE
29 16.0 Processor_Options.Blender_OPT._SignalExchange INT 1 1 FILLER - 0= Hardwire; 1= Ethernet
30 18.0 Processor_Options.Blender_OPT._CoolerPresent BOOL TRUE TRUE
31 20.0 Processor_Options.Blender_OPT._CoolerControl INT 4 4 0)External 1 )Water 2)Pro duct 3)Water +Product-2 C trl 4)Water+ Product-1 Ct rl
32 22.0 Processor_Options.Blender_OPT._CoolerType INT 0 0 0)Glycol 1)A mmonia
33 24.0 Processor_Options.Blender_OPT._LocalCIP BOOL FALSE FALSE
34 24.1 Processor_Options.Blender_OPT._ICS_CustomerHotWater BOOL FALSE FALSE 0)No Hot Wat er from Cust omer 1)Hot W ater from Cu stomer Avail able
35 24.2 Processor_Options.Blender_OPT._ICS_CustomerChemRecov BOOL FALSE FALSE 0)No Custome r's Chemical s Recovery 1 )Customer's Chemicals Re covery Avail able
36 24.3 Processor_Options.Blender_OPT._CIPSignalExchange BOOL FALSE FALSE CIP - 0= Har dwire; 1= Et hernet
37 24.4 Processor_Options.Blender_OPT._ICS_CustomerChemicals BOOL FALSE FALSE 0)Chemicals from ICS 1)C hemicals fro m Customer
38 24.5 Processor_Options.Blender_OPT._CarboPresent BOOL TRUE TRUE
39 24.6 Processor_Options.Blender_OPT._InverterSyrupPumpPPP302 BOOL FALSE FALSE 0)Not Presen t 1)Present
40 24.7 Processor_Options.Blender_OPT._InverterWaterPumpPPN301 BOOL FALSE FALSE 0)Not Presen t 1)Present
41 25.0 Processor_Options.Blender_OPT._DoubleDeair BOOL TRUE TRUE
42 25.1 Processor_Options.Blender_OPT._DeairPreMixed BOOL FALSE FALSE Deox Premixe d Inlet
43 25.2 Processor_Options.Blender_OPT._Deaireation BOOL TRUE TRUE 0)SAG 1)SAE/ SAF
44 25.3 Processor_Options.Blender_OPT._StillWaterByPass BOOL FALSE FALSE
45 25.4 Processor_Options.Blender_OPT._ManifoldSetting BOOL TRUE TRUE 0)Manual 1)A utomatic
46 25.5 Processor_Options.Blender_OPT._InverterProdPumpPPM303 BOOL FALSE FALSE
47 25.6 Processor_Options.Blender_OPT._SidelCip BOOL FALSE FALSE
48 25.7 Processor_Options.Blender_OPT._EthernetCom_CpuPN_CP BOOL TRUE TRUE 0)Comunicati on with CP 1)Comunicat ion with CPU PN
49 26.0 Processor_Options.Blender_OPT._2ndOutlet INT 0 0 0)No 2nd Out let 1)2nd O utlet No Sta ndalone 2)2 nd Outlet St andalone
50 28.0 Processor_Options.Blender_OPT._Promass INT 2 2
51 30.0 Processor_Options.Blender_OPT._WaterPromass BOOL TRUE TRUE 0)Promag 1)P romass
52 30.1 Processor_Options.Blender_OPT._ProductConductimeter BOOL FALSE FALSE
53 30.2 Processor_Options.Blender_OPT._ICS_CustomerH2ORecov BOOL FALSE FALSE 0)No Custome r's H2O Reco very 1)Custo mer's H2O Re covery Avail able
54 30.3 Processor_Options.Blender_OPT.Spare303 BOOL FALSE FALSE
55 30.4 Processor_Options.Blender_OPT._CO2_GAS2_Injection BOOL FALSE FALSE 0)Only CO2 I njection 1)G AS2 Injectio n
56 30.5 Processor_Options.Blender_OPT._InverterVacuuPumpPPN304 BOOL FALSE FALSE 0)Not Presen t 1)Present
57 30.6 Processor_Options.Blender_OPT._InverterBoostPumpPPM307 BOOL FALSE FALSE 0)Not Presen t 1)Present
58 30.7 Processor_Options.Blender_OPT._RunOut_Water BOOL TRUE TRUE 0)Syrup Runo ut without W ater 1)Syrup runout with Water pushi ng
59 31.0 Processor_Options.Blender_OPT._FlowMeterType BOOL FALSE TRUE 0)Endrees Ha user -- 1)Mi cromotion
60 31.1 Processor_Options.Blender_OPT._SidelFiller BOOL FALSE FALSE 0)Filler Sim onazzi -- 1)Filler Sid el Filling
61 31.2 Processor_Options.Blender_OPT._Simulation BOOL FALSE FALSE
62 31.3 Processor_Options.Blender_OPT._ProductCoolingCTRL BOOL FALSE FALSE 0)none 1) TT M307
63 31.4 Processor_Options.Blender_OPT._ChillerCTRL BOOL FALSE FALSE Chiller Pres sure Cross C ontrol
64 31.5 Processor_Options.Blender_OPT._CO2_SterileFilter BOOL TRUE TRUE CO2 Inlet wi th Steril Fi lter
65 31.6 Processor_Options.Blender_OPT._InverterRecirPumpPPM306 BOOL FALSE FALSE 0)Not Presen t 1)Present
66 31.7 Processor_Options.Blender_OPT._ProdPressReleaseRVM304 BOOL FALSE FALSE 0)Not Presen t 1)Present
67 32.0 Processor_Options.Blender_OPT._VacuumPump INT 1 1 0)None 1)Ste rling 2)Nash Elmo
68 34.0 Processor_Options.Blender_OPT._GAS2InjectionType INT 0 0 0)None 1)N2 2)Steril Air
69 36.0 Processor_Options.Blender_OPT._InjectionPress_Ctrl INT 1 1 0)Manual 1)N orgren v1 2) Norgren v2
70 38.0 Processor_Options.Blender_OPT._ProdPressureType INT 0 0 0)Only CO2 1 )CO2+SterilA ir 2)CO2+N2
71 40.0 Processor_Options.Blender_OPT._CIPHeatType INT 0 0 0)Steam 1)El ectric
72 42.0 Processor_Options.Blender_OPT._EHS_NrRes INT 6 6 Number of He at Resistanc es
73 44.0 Spare1[1] INT 0 0
74 46.0 Spare1[2] INT 0 0
75 48.0 Spare1[3] INT 0 0
76 50.0 Spare1[4] INT 0 0
77 52.0 Spare1[5] INT 0 0
78 54.0 Spare1[6] INT 0 0
79 56.0 Spare1[7] INT 0 0
80 58.0 Spare1[8] INT 0 0
81 60.0 Spare1[9] INT 0 0
82 62.0 _RVM301_DeadBand REAL 5.000000e-02 5.000000e-02
83 66.0 _RVM301_Kp REAL 9.000000e+01 9.000000e+01
84 70.0 Actual_Recipe_Parameters._Name STRING [ 32 ] ' ' ''
85 104.0 Actual_Recipe_Parameters._EnProdTemp BOOL FALSE TRUE
86 104.1 Actual_Recipe_Parameters._SyrFlushing BOOL FALSE FALSE Ex_EnDeairea tion --> DEL ETED - AVP32 0 VALVE OPEN
87 104.2 Actual_Recipe_Parameters._GAS2_Injection BOOL FALSE FALSE 0 = GAS2 not present; 1 = GAS2 prese nt
88 104.3 Actual_Recipe_Parameters._Eq_Pression_Selected BOOL FALSE FALSE
89 104.4 Actual_Recipe_Parameters._DeoxStripEn BOOL FALSE FALSE ******Deaira tion with St rip Enable
90 104.5 Actual_Recipe_Parameters._DeoxVacuumEn BOOL FALSE TRUE ******Deaira tion with Va cuum
91 104.6 Actual_Recipe_Parameters._DeoxPreMixed BOOL FALSE FALSE ******Deaira tion of Prem ixed Product
92 104.7 Actual_Recipe_Parameters._EnBlowOffProdPipeCO2Fil BOOL FALSE FALSE
93 105.0 Actual_Recipe_Parameters._WaterSelection BYTE B#16#0 B#16#0
94 106.0 Actual_Recipe_Parameters._FillerNextRecipeNum BYTE B#16#0 B#16#0
95 107.0 Actual_Recipe_Parameters._BottleShape BYTE B#16#0 B#16#0
96 108.0 Actual_Recipe_Parameters._Type INT 1 2 1= DIET; 2= REGULAR; 3= RATIO; 4= WA TER
97 110.0 Actual_Recipe_Parameters._ProdMeterRecipeNum INT 0 1
98 112.0 Actual_Recipe_Parameters._SyrupBrix REAL 5.000000e+01 4.625000e+01
99 116.0 Actual_Recipe_Parameters._SyrupDensity REAL 1.255800e+00 1.206908e+00
100 120.0 Actual_Recipe_Parameters._SyrupFactor REAL 1.000000e+00 1.000000e+00
101 124.0 Actual_Recipe_Parameters._ProductBrix REAL 1.045000e+01 1.000000e+01
102 128.0 Actual_Recipe_Parameters._ProductionRate REAL 9.000000e+02 3.800000e+02
103 132.0 Actual_Recipe_Parameters._Ratio REAL 2.000000e+01 4.238896e+00
104 136.0 Actual_Recipe_Parameters._ProdBrixOffset REAL 0.000000e+00 2.500000e-01
105 140.0 Actual_Recipe_Parameters._CO2Vols REAL 0.000000e+00 2.550000e+00
106 144.0 Actual_Recipe_Parameters._CO2Fact REAL 1.000000e+00 9.400000e-01
107 148.0 Actual_Recipe_Parameters._ProdTankPress REAL 1.000000e+00 4.400000e+00
108 152.0 Actual_Recipe_Parameters._SP_ProdTemp REAL 1.000000e+01 1.700000e+01
109 156.0 Actual_Recipe_Parameters._PrdTankMinLevel REAL 1.000000e+01 3.500000e+01
110 160.0 Actual_Recipe_Parameters._WaterValveSave REAL 0.000000e+00 0.000000e+00
111 164.0 Actual_Recipe_Parameters._SyrupValveSave REAL 0.000000e+00 0.000000e+00
112 168.0 Actual_Recipe_Parameters._CarboCO2ValveSave REAL 0.000000e+00 0.000000e+00
113 172.0 Actual_Recipe_Parameters._ProdMeterHighBrix REAL 0.000000e+00 1.030000e+01
114 176.0 Actual_Recipe_Parameters._ProdMeterLowBrix REAL 0.000000e+00 9.830000e+00
115 180.0 Actual_Recipe_Parameters._ProdMeterHighCO2 REAL 0.000000e+00 2.900000e+00
116 184.0 Actual_Recipe_Parameters._ProdMeterLowCO2 REAL 0.000000e+00 2.300000e+00
117 188.0 Actual_Recipe_Parameters._ProdMeter_ZeroCO2 REAL 0.000000e+00 0.000000e+00
118 192.0 Actual_Recipe_Parameters._ProdMeter_ZeroBrix REAL 0.000000e+00 0.000000e+00
119 196.0 Actual_Recipe_Parameters._ProdHighCond REAL 0.000000e+00 0.000000e+00
120 200.0 Actual_Recipe_Parameters._ProdLowCond REAL 0.000000e+00 0.000000e+00
121 204.0 Actual_Recipe_Parameters._BottleSize REAL 0.000000e+00 0.000000e+00
122 208.0 Actual_Recipe_Parameters._FillingValveHead_SP REAL 0.000000e+00 0.000000e+00
123 212.0 Actual_Recipe_Parameters._SyrMeter_ZeroBrix REAL 0.000000e+00 0.000000e+00
124 216.0 Actual_Recipe_Parameters._FirstProdExtraCO2Fact REAL 9.700000e-01 1.020000e+00
125 220.0 Actual_Recipe_Parameters._Gas2Vols REAL 0.000000e+00 0.000000e+00
126 224.0 Actual_Recipe_Parameters._Gas2Fact REAL 1.000000e+00 0.000000e+00
127 228.0 Actual_Recipe_Parameters._SyrupPumpPressure REAL 0.000000e+00 0.000000e+00 ******Syrup Pump Pressur e SP
128 232.0 Actual_Recipe_Parameters._WaterPumpPressure REAL 0.000000e+00 0.000000e+00 ******Water Pump Pressur e SP
129 236.0 Actual_Recipe_Parameters._CO2_Air_N2_PressSelect INT 0 0 1=CO2; 2=CO2 +SterilAir; 3=CO2+N2 - P ressure Tank Selection
130 238.0 Actual_Recipe_Parameters._KFactRVM304BlowOff REAL 0.000000e+00 0.000000e+00
131 242.0 Actual_Recipe_Parameters._ProdRecircPumpFreq REAL 0.000000e+00 0.000000e+00
132 246.0 Actual_Recipe_Parameters._ProdBoosterPumpPress REAL 0.000000e+00 0.000000e+00
133 250.0 Actual_Recipe_Parameters._ProdSendPumpFreq REAL 0.000000e+00 0.000000e+00 ******Produc t Sending Pu mp Frequency SP
134 254.0 Spare2[1] INT 0 0
135 256.0 Spare2[2] INT 0 0
136 258.0 Spare2[3] INT 0 0
137 260.0 Spare2[4] INT 0 0
138 262.0 Spare2[5] INT 0 0
139 264.0 Next_Recipe_Name STRING [ 32 ] ' ' 'cambio 1$00$00$ 00$00$00$00$00$0 0$00$00$00$00$00 $00$00$00$00$00$ 00$00$00$00'
140 298.0 Next_Recipe_Number INT 0 0
141 300.0 Spare3[1] INT 0 0
142 302.0 Spare3[2] INT 0 0
143 304.0 Spare3[3] INT 0 0
144 306.0 Spare3[4] INT 0 0
145 308.0 Spare3[5] INT 0 0
146 310.0 Spare3[6] INT 0 0
147 312.0 Spare3[7] INT 0 0
148 314.0 Spare3[8] INT 0 0
149 316.0 Spare3[9] INT 0 0
150 318.0 Spare3[10] INT 0 0
151 320.0 Spare3[11] INT 0 0
152 322.0 Spare3[12] INT 0 0
153 324.0 Spare3[13] INT 0 0
154 326.0 Spare3[14] INT 0 0
155 328.0 Spare3[15] INT 0 0
156 330.0 Spare3[16] INT 0 0
157 332.0 Spare3[17] INT 0 0
158 334.0 Spare3[18] INT 0 0
159 336.0 ProcessSetup.Spare000 REAL 0.000000e+00 0.000000e+00
160 340.0 ProcessSetup.Spare040 REAL 0.000000e+00 0.000000e+00
161 344.0 ProcessSetup._KWaterLoss REAL 1.000000e-03 1.000000e-03 Friction Los s Constant i n Serpentine
162 348.0 ProcessSetup._KSyrupLoss REAL 7.800000e-03 7.800000e-03 Friction Los s Constant i n Syrup Pipe
163 352.0 ProcessSetup._KProdLoss REAL 1.390000e-02 1.390000e-02 Pressure Los s Factor
164 356.0 ProcessSetup._KPPM303 REAL 5.700000e+00 5.700000e+00 Frequency Ov erpressure P ump P3 Const ant [Hz/mm]
165 360.0 ProcessSetup._BaialageRVM301OVMin REAL 2.000000e+00 2.000000e+00 Baialage Min imum Flow (N m3/h)
166 364.0 ProcessSetup._SyrupLinePressure REAL 2.200000e+00 2.200000e+00 Syrup Line p ressure at V EP2 valve
167 368.0 ProcessSetup._CIPRMM301OV REAL 1.000000e+01 1.000000e+01 Water Valve Opening Duri ng CIP
168 372.0 ProcessSetup._CIPRMP302OV REAL 1.500000e+01 1.500000e+01 Syrup Valve Opening Duri ng CIP
169 376.0 ProcessSetup._CIPTM301MinLevel REAL 3.500000e+01 3.500000e+01 Product Tank Minimum Lev el In CIP
170 380.0 ProcessSetup._CIPTM301MaxLevel REAL 5.500000e+01 5.500000e+01 Product Tank Maximum Lev el In CIP
171 384.0 ProcessSetup._CIPPPM303Freq REAL 5.000000e+01 5.000000e+01 CIP frequenc y Value [Hz]
172 388.0 ProcessSetup._CIPTP301MinLevel REAL 2.500000e+01 2.500000e+01 Syrup Tank M inimum Level In CIP
173 392.0 ProcessSetup._CIPTP301MaxLevel REAL 4.500000e+01 4.500000e+01 Syrup Tank M aximum Level In CIP
174 396.0 ProcessSetup._RinseRMM301OV REAL 1.000000e+01 1.000000e+01 Water Valve Opening Duri ng Rinse
175 400.0 ProcessSetup._RinseRMP302OV REAL 1.400000e+01 1.400000e+01 Syrup Valve Opening Duri ng Rinse
176 404.0 ProcessSetup._RinseTM301Press REAL 3.000000e-01 3.000000e-01 Product Tank Pressure In Rinse
177 408.0 ProcessSetup._RinsePPM303Freq REAL 5.000000e+01 5.000000e+01 Rinse freque ncy Value [H z]
178 412.0 ProcessSetup._DrainTM301Press REAL 1.000000e+00 1.000000e+00 Buffer Tank Draining Pre ssure
179 416.0 ProcessSetup._KRecBlendError REAL 2.000000e+00 2.000000e+00 Blend Error Recovery CON STANT
180 420.0 ProcessSetup._KRecCarboCO2Error REAL 2.000000e+00 2.000000e+00 Carbonation Error Recove ry Constant
181 424.0 ProcessSetup._MaxBlendError REAL 1.000000e+02 1.000000e+02 Blend Error Maximum Valu e
182 428.0 ProcessSetup._MaxCarboCO2Error REAL 5.000000e+02 5.000000e+02 Carbonation Error Maximu m Value
183 432.0 ProcessSetup._StartUpBrixExtraWater REAL 4.700000e+01 4.700000e+01
184 436.0 ProcessSetup._StartUpCO2ExtraWater REAL 8.000000e+00 8.000000e+00
185 440.0 ProcessSetup._StartUpPPM303Freq REAL 2.000000e+01 2.000000e+01 Start Up fre quency Value [Hz]
186 444.0 ProcessSetup._SyrupRoomTank INT 1 1
187 446.0 ProcessSetup._SyrupRunOutLiters REAL 2.900000e+02 2.900000e+02
188 450.0 ProcessSetup._InjCO2Press_Offset REAL 5.000000e-01 5.000000e-01
189 454.0 ProcessSetup._InjCO2Press_MinFlow REAL 4.500000e+02 4.500000e+02
190 458.0 ProcessSetup._InjCO2Press_MaxFlow REAL 2.500000e+03 2.500000e+03
191 462.0 ProcessSetup._CarboCO2Pressure REAL 1.250000e+01 1.250000e+01 CO2 Pressure Infeed Line
192 466.0 ProcessSetup._N2MinPressure REAL 1.000000e+00 1.000000e+00 N2 Minimum P ressure Infe ed Line
193 470.0 ProcessSetup._DiffSensor_Height REAL 3.950000e+02 3.950000e+02 Sensor Heigh t from Soil [mm]
194 474.0 ProcessSetup._DiffSensor_DeltaHeight REAL -2.500000e+01 -2.500000e+01 Sensor Plate s Height Dif ference [mm]
195 478.0 ProcessSetup._DiffSensor_Offset REAL 3.618000e+01 3.618000e+01 Sensor Offse t Read with zero pressur e (all valve s open) in [ mm]
196 482.0 ProcessSetup._FillingValveHeight REAL 1.400000e+03 1.400000e+03 Filling Valv e Height fro m soil [mm]
197 486.0 ProcessSetup._FillerDiameter REAL 2.520000e+03 2.520000e+03 Filler Carou sel Diameter [mm]
198 490.0 ProcessSetup._FillingValveNum INT 91 91 Filling Valv es Number
199 492.0 ProcessSetup._FillerProdPipeDN REAL 1.000000e+02 1.000000e+02
200 496.0 ProcessSetup._FillerProdPipeMass REAL 1.600000e+02 1.600000e+02
201 500.0 ProcessSetup._FillingTime REAL 3.200000e+00 3.200000e+00
202 504.0 ProcessSetup._TM301Height_0 REAL 1.050000e+03 1.050000e+03 Level at 0% Tank Level Height in mm
203 508.0 ProcessSetup._TM301LevelPerc_2 REAL 4.600000e+01 4.600000e+01 Second level percentage
204 512.0 ProcessSetup._TM301Height_2 REAL 1.625000e+03 1.625000e+03 Second level Height in m m
205 516.0 ProcessSetup._RVN304Factor REAL 1.000000e+00 1.000000e+00 DeareationFl ow/WaterFlow
206 520.0 ProcessSetup._DrainTM301Flushing REAL 1.300000e+00 1.300000e+00
207 524.0 ProcessSetup._FirstProdExtraBrix REAL 5.000000e-02 5.000000e-02
208 528.0 ProcessSetup._FirstProdDietExtraSyr REAL 1.400000e-03 1.400000e-03
209 532.0 ProcessSetup._EndProdLastSyrlt REAL 0.000000e+00 0.000000e+00 End Producti on Last syru p liters
210 536.0 ProcessSetup._TM301DrainSt0Time WORD W#16#A W#16#A sec
211 538.0 ProcessSetup._TM301DrainSt1Time WORD W#16#50 W#16#50 sec
212 540.0 ProcessSetup._ProdPipeRunOutSt0Time WORD W#16#1 W#16#1 sec
213 542.0 ProcessSetup._RMM301ProdPipeRunOu REAL 3.000000e+01 3.000000e+01
214 546.0 ProcessSetup._RMP302ProdPipeRunOu REAL 4.000000e+01 4.000000e+01
215 550.0 ProcessSetup._ProdPipeRunOutAmount REAL 3.000000e+01 3.000000e+01
216 554.0 ProcessSetup._TM301RunOutChiller REAL 5.000000e+00 5.000000e+00
217 558.0 ProcessSetup._MinSpeedNominalProd REAL 4.000000e-01 4.000000e-01 Min Speed fo r Nominal Pr oduction
218 562.0 ProcessSetup._MinSpeedSlowProd REAL 3.000000e-01 3.000000e-01 Min Speed fo r Very Low P roduction
219 566.0 ProcessSetup._FastChgOvrTM301DrnPrss REAL 9.000000e-01 9.000000e-01 Fast Change Over Product Tank Draini ng Pressure in Blendfill
220 570.0 ProcessSetup._CIPTN301MinLevel REAL 3.500000e+01 3.500000e+01 Deaireator T ank Minimum Level In CIP
221 574.0 ProcessSetup._CIPTN301MaxLevel REAL 6.000000e+01 6.000000e+01 Deaireator T ank Maximum Level In CIP
222 578.0 ProcessSetup._ProdPPN304Freq REAL 5.000000e+01 5.000000e+01
223 582.0 ProcessSetup._GAS2InjectionPress REAL 4.000000e+00 4.000000e+00
224 586.0 ProcessSetup._BaialageRVM301OVMax REAL 2.000000e+01 2.000000e+01 Baialage Pro duction Flow Multiplier
225 590.0 ProcessSetup._RinsePPN301Freq REAL 5.000000e+00 5.000000e+00
226 594.0 ProcessSetup._CIPPPN301Freq REAL 5.000000e+00 5.000000e+00
227 598.0 ProcessSetup._RinsePPP302Freq REAL 5.000000e+00 5.000000e+00
228 602.0 ProcessSetup._CIPPPP302Freq REAL 5.000000e+00 5.000000e+00
229 606.0 ProcessSetup._PercSyrupBrixSyrStarUp REAL 2.500000e+01 2.500000e+01
230 610.0 ProcessSetup._RefTempCoolingCTRL REAL 0.000000e+00 0.000000e+00
231 614.0 ProcessSetup._H2OSerpPrimingVolume REAL 1.500000e+02 1.500000e+02 Water Serpen tine Volume + Water Chil ler Volume
232 618.0 ProcessSetup._AVN301_Nozzle_Kv REAL 1.650000e+02 1.650000e+02 AVN301 Nozzl e Kv
233 622.0 ProcessSetup._AVN302_Nozzle_Kv REAL 2.600000e+02 2.600000e+02 AVN302 Nozzl e Kv
234 626.0 ProcessSetup._AVN303_Nozzle_Kv REAL 1.650000e+02 1.650000e+02 AVN303 Nozzl e Kv
235 630.0 ProcessSetup._DeoxSpryball_Kv REAL 6.700000e+01 6.700000e+01 Deox Sprybal l Kv
236 634.0 ProcessSetup._PremixedLineDrainTime INT 300 300 Premixed Pro duct Line Dr ain Time
237 636.0 ProcessSetup._PPN301_H_MaxFlow REAL 9.000000e+01 9.000000e+01 PPN301 Pump Head with Ma x Flow [m]
238 640.0 ProcessSetup._PPN301_H_MinFlow REAL 8.700000e+01 8.700000e+01 PPN301 Pump Head with Mi n Flow [m]
239 644.0 ProcessSetup._PPN301_MaxFlow REAL 5.070000e+02 5.070000e+02 PPN301 Max F low [l/min]
240 648.0 ProcessSetup._PPN301_MinFlow REAL 2.110000e+02 2.110000e+02 PPN301 Min F low [l/min]
241 652.0 ProcessSetup._PPP302_H_MaxFlow REAL 8.600000e+01 8.600000e+01 PPP302 Pump Head with Ma x Flow [m]
242 656.0 ProcessSetup._PPP302_H_MinFlow REAL 8.500000e+01 8.500000e+01 PPP302 Pump Head with Mi n Flow [m]
243 660.0 ProcessSetup._PPP302_MaxFlow REAL 1.150000e+02 1.150000e+02 PPP302 Max F low [l/min]
244 664.0 ProcessSetup._PPP302_MinFlow REAL 3.200000e+01 3.200000e+01 PPP302 Min F low [l/min]
245 668.0 ProcessSetup._RinsePPM306Freq REAL 5.000000e+00 5.000000e+00
246 672.0 ProcessSetup._CIPPPM306Freq REAL 5.000000e+00 5.000000e+00
247 676.0 ProcessSetup._PPM307_H_MaxFlow REAL 0.000000e+00 0.000000e+00 PPM307 Pump Head with Ma x Flow [m]
248 680.0 ProcessSetup._PPM307_H_MinFlow REAL 0.000000e+00 0.000000e+00 PPM307 Pump Head with Mi n Flow [m]
249 684.0 ProcessSetup._PPM307_MaxFlow REAL 0.000000e+00 0.000000e+00 PPM307 Max F low [l/min]
250 688.0 ProcessSetup._PPM307_MinFlow REAL 0.000000e+00 0.000000e+00 PPM307 Min F low [l/min]
251 692.0 ProcessSetup._Temp0_VacuumCtrl REAL 1.800000e+01 1.800000e+01 PPN304 Targe t Temperatur e - OPTION PPN304 Sterl ing Type
252 696.0 ProcessSetup._Temp1_VacuumCtrl REAL 2.000000e+00 2.000000e+00 PPN304 High Treshold Tem perature Del ta - OPTION PPN304 Sterl ing Type
253 700.0 ProcessSetup._Temp2_VacuumCtrl REAL 2.000000e+00 2.000000e+00 PPN304 Low T reshold Temp erature Delt a - OPTION PPN304 Sterl ing Type
254 704.0 ProcessSetup._Temp3_VacuumCtrl REAL 5.000000e+01 5.000000e+01 PPN304 Warni ng Temperatu re - OPTION PPN304 Sterl ing Type
255 708.0 ProcessSetup._Temp4_VacuumCtrl REAL 5.000000e+01 5.000000e+01 PPN304 Alarm Temperature - OPTION PPN304 Sterl ing Type
256 712.0 ProcessSetup._T1_VacuumCtrl DINT L#1500 L#1500 PPN304 Time 1 [msec] - OPTION PPN304 Sterl ing Type
257 716.0 ProcessSetup._T2_VacuumCtrl DINT L#1500 L#1500 PPN304 Time 2 [msec] - OPTION PPN304 Sterl ing Type
258 720.0 ProcessSetup._T3_VacuumCtrl DINT L#1000 L#1000 PPN304 Time 3 [msec] - OPTION PPN304 Sterl ing Type
259 724.0 ProcessSetup._T4_VacuumCtrl DINT L#1000 L#1000 PPN304 Time 4 [msec] - OPTION PPN304 Sterl ing Type
260 728.0 ProcessSetup._ICS_VolDosWorkTimePAA INT 30 30 ICS - DS - D osing Workin g Time [sec]
261 730.0 ProcessSetup._ICS_VolPauseTimePAA INT 30 30 ICS - DS - D osing Pause Time [sec]
262 732.0 ProcessSetup._ICS_PAAPulseWeight INT 10 10 ICS - DS - P AA Pulse Wei ght [(L/Puls e)/100]
263 734.0 ProcessSetup._ICS_CausticPulseWeight INT 10 10 ICS - DS - C austic Pulse Weight [(L/ Pulse)/100]
264 736.0 ProcessSetup._ICS_AcidPulseWeight INT 10 10 ICS - DS - A cid Pulse We ight [(L/Pul se)/100]
265 738.0 ProcessSetup._ICS_VolumeRestOfLine REAL 3.500000e+02 3.500000e+02 ICS - DS - V olume of the Rest of the Line (Fille r + Piping) [L]
266 742.0 ProcessSetup._ICS_VolDosWorkTimeCaus INT 30 30 ICS - DS - D osing Workin g Time [sec]
267 744.0 ProcessSetup._ICS_VolDosPauseTimeCaus INT 30 30 ICS - DS - D osing Pause Time [sec]
268 746.0 ProcessSetup._ICS_VolDosWorkTimeAcid INT 30 30 ICS - DS - D osing Workin g Time [sec]
269 748.0 ProcessSetup._ICS_VolDosPauseTimeAcid INT 30 30 ICS - DS - D osing Pause Time [sec]
270 750.0 ProcessSetup._ICS_ConcDosWorkTimeCaus INT 30 30 ICS - DS - D osing Workin g Time [sec]
271 752.0 ProcessSetup._ICS_ConcDosPausTimeCaus INT 30 30 ICS - DS - D osing Pause Time [sec]
272 754.0 ProcessSetup._ICS_ConcDosWorkTimeAcid INT 30 30 ICS - DS - D osing Workin g Time [sec]
273 756.0 ProcessSetup._ICS_ConcDosPausTimeAcid INT 30 30 ICS - DS - D osing Pause Time [sec]
274 758.0 ProcessSetup._RinsePPM307Freq REAL 3.000000e+01 3.000000e+01
275 762.0 ProcessSetup._CIPPPM307Freq REAL 3.000000e+01 3.000000e+01
276 766.0 ProcessSetup._CIP2StepTN301Lvl REAL 0.000000e+00 0.000000e+00 Local CIP - 2 Step loadi ng TN301 Lev el
277 770.0 ProcessSetup._CIP2StepTM301Lvl REAL 0.000000e+00 0.000000e+00 Local CIP - 2 Step loadi ng TM301 Lev el
278 774.0 ProcessSetup._CIP2StepTP301Lvl REAL 0.000000e+00 0.000000e+00 Local CIP - 2 Step loadi ng TP301 Lev el
279 778.0 ProcessSetup._PumpNominalFreq REAL 5.000000e+01 5.000000e+01 50.0 Hz or 6 0.0 Hz
280 782.0 _SwitchOff_DensityOK BOOL FALSE FALSE

View File

@ -0,0 +1,557 @@
TYPE "Recipe_Prod"
FAMILY : DataType
VERSION : 0.1
STRUCT
_Name : STRING [32 ] := ' ';
_EnProdTemp : BOOL ;
_SyrFlushing : BOOL ; //Ex_EnDeaireation --> DELETED - AVP320 VALVE OPEN
_GAS2_Injection : BOOL ; //0 = GAS2 not present; 1 = GAS2 present
_Eq_Pression_Selected : BOOL ;
_DeoxStripEn : BOOL ; //******Deairation with Strip Enable
_DeoxVacuumEn : BOOL ; //******Deairation with Vacuum
_DeoxPreMixed : BOOL ; //******Deairation of Premixed Product
_EnBlowOffProdPipeCO2Fil : BOOL ;
_WaterSelection : BYTE ;
_FillerNextRecipeNum : BYTE ;
_BottleShape : BYTE ;
_Type : INT := 1; //1= DIET; 2= REGULAR; 3= RATIO; 4= WATER
_ProdMeterRecipeNum : INT ;
_SyrupBrix : REAL := 5.000000e+01;
_SyrupDensity : REAL := 1.255800e+00;
_SyrupFactor : REAL := 1.000000e+00;
_ProductBrix : REAL := 1.045000e+01;
_ProductionRate : REAL := 9.000000e+02;
_Ratio : REAL := 2.000000e+01;
_ProdBrixOffset : REAL ;
_CO2Vols : REAL ;
_CO2Fact : REAL := 1.000000e+00;
_ProdTankPress : REAL := 1.000000e+00;
_SP_ProdTemp : REAL := 1.000000e+01;
_PrdTankMinLevel : REAL := 1.000000e+01;
_WaterValveSave : REAL ;
_SyrupValveSave : REAL ;
_CarboCO2ValveSave : REAL ;
_ProdMeterHighBrix : REAL ;
_ProdMeterLowBrix : REAL ;
_ProdMeterHighCO2 : REAL ;
_ProdMeterLowCO2 : REAL ;
_ProdMeter_ZeroCO2 : REAL ;
_ProdMeter_ZeroBrix : REAL ;
_ProdHighCond : REAL ;
_ProdLowCond : REAL ;
_BottleSize : REAL ;
_FillingValveHead_SP : REAL ;
_SyrMeter_ZeroBrix : REAL ;
_FirstProdExtraCO2Fact : REAL := 9.700000e-01;
_Gas2Vols : REAL ;
_Gas2Fact : REAL := 1.000000e+00;
_SyrupPumpPressure : REAL ; //******Syrup Pump Pressure SP
_WaterPumpPressure : REAL ; //******Water Pump Pressure SP
_CO2_Air_N2_PressSelect : INT ; //1=CO2; 2=CO2+SterilAir; 3=CO2+N2 - Pressure Tank Selection
_KFactRVM304BlowOff : REAL ;
_ProdRecircPumpFreq : REAL ;
_ProdBoosterPumpPress : REAL ;
_ProdSendPumpFreq : REAL ; //******Product Sending Pump Frequency SP
END_STRUCT ;
END_TYPE
DATA_BLOCK "HMI_Blender_Parameters"
TITLE =
{ S7_language := '28(1) Albanese 15.06.2005 17:07:04' }
FAMILY : Resource
VERSION : 0.0
STRUCT
Processor_Options : STRUCT
Blender_OPT : STRUCT
_ModelNum : INT := 6;
_CO2_Offset : REAL := 4.500000e-01;
_MaxSyrDeltaBrix : REAL := 8.000000e-01;
_BrixMeter : BOOL := TRUE;
Spare101 : BOOL ;
_TrackH2OEnable : BOOL ;
_PAmPDSType : BOOL ; //0)Cobrix 2000 1)Carbo 2000
_HistoricalTrends : BOOL := TRUE; //0)Not Present 1)Present
_PowerMeter : BOOL ; //0)Not Present 1)Present
_Report : BOOL := TRUE; //0)Not Present 1)Present
_Balaiage : BOOL ;
_Valves_FullFeedback : BOOL := TRUE; //Valves control Full feedback
_Valves_SingleFeedback : BOOL ; //Valves control Single feedback
_PumpsSafetySwitches : BOOL ; //Pumps with Safety Switches
_SurgeProtectionAct : BOOL ;
_DBC_Type : BOOL ; //0) Deox,Carbo,Blend 1)Deox,Blend,Carbo
_CO2InletMeter : BOOL := TRUE; //0)Not Present 1)Present
_ProductO2Meter : BOOL ; //0)Not Present 1)Present
_CopressedAirInletMeter : BOOL ; //0)Not Present 1)Present
_MeterType : INT := 6; //1)Maselli 2)AntoonPaar 3)4-20mA 4)UC05 UR22 5)mPDSPA 6)MR02
_MeterReceiveOnly : BOOL ;
_SyrBrixMeter : BOOL ;
_Flooding_Start_Up : BOOL ; //0)Not Selected 1)Selected
_FastChangeOverEnabled : BOOL := TRUE;
_WaterInletMeter : BOOL ; //0)Not Present 1)Present
_BlendFillSystem : BOOL := TRUE;
_TrackFillerSpeed : BOOL := TRUE;
_SignalExchange : INT := 1; //FILLER - 0= Hardwire; 1= Ethernet
_CoolerPresent : BOOL := TRUE;
_CoolerControl : INT := 4; //0)External 1)Water 2)Product 3)Water+Product-2 Ctrl 4)Water+Product-1 Ctrl
_CoolerType : INT ; //0)Glycol 1)Ammonia
_LocalCIP : BOOL ;
_ICS_CustomerHotWater : BOOL ; //0)No Hot Water from Customer 1)Hot Water from Customer Available
_ICS_CustomerChemRecov : BOOL ; //0)No Customer's Chemicals Recovery 1)Customer's Chemicals Recovery Available
_CIPSignalExchange : BOOL ; //CIP - 0= Hardwire; 1= Ethernet
_ICS_CustomerChemicals : BOOL ; //0)Chemicals from ICS 1)Chemicals from Customer
_CarboPresent : BOOL := TRUE;
_InverterSyrupPumpPPP302 : BOOL ; //0)Not Present 1)Present
_InverterWaterPumpPPN301 : BOOL ; //0)Not Present 1)Present
_DoubleDeair : BOOL := TRUE;
_DeairPreMixed : BOOL ; //Deox Premixed Inlet
_Deaireation : BOOL := TRUE; //0)SAG 1)SAE/SAF
_StillWaterByPass : BOOL ;
_ManifoldSetting : BOOL := TRUE; //0)Manual 1)Automatic
_InverterProdPumpPPM303 : BOOL ;
_SidelCip : BOOL ;
_EthernetCom_CpuPN_CP : BOOL := TRUE; //0)Comunication with CP 1)Comunication with CPU PN
_2ndOutlet : INT ; //0)No 2nd Outlet 1)2nd Outlet No Standalone 2)2nd Outlet Standalone
_Promass : INT := 2;
_WaterPromass : BOOL := TRUE; //0)Promag 1)Promass
_ProductConductimeter : BOOL ;
_ICS_CustomerH2ORecov : BOOL ; //0)No Customer's H2O Recovery 1)Customer's H2O Recovery Available
Spare303 : BOOL ;
_CO2_GAS2_Injection : BOOL ; //0)Only CO2 Injection 1)GAS2 Injection
_InverterVacuuPumpPPN304 : BOOL ; //0)Not Present 1)Present
_InverterBoostPumpPPM307 : BOOL ; //0)Not Present 1)Present
_RunOut_Water : BOOL := TRUE; //0)Syrup Runout without Water 1)Syrup runout with Water pushing
_FlowMeterType : BOOL ; //0)Endrees Hauser -- 1)Micromotion
_SidelFiller : BOOL ; //0)Filler Simonazzi -- 1)Filler Sidel Filling
_Simulation : BOOL ;
_ProductCoolingCTRL : BOOL ; //0)none 1) TTM307
_ChillerCTRL : BOOL ; //Chiller Pressure Cross Control
_CO2_SterileFilter : BOOL := TRUE; //CO2 Inlet with Steril Filter
_InverterRecirPumpPPM306 : BOOL ; //0)Not Present 1)Present
_ProdPressReleaseRVM304 : BOOL ; //0)Not Present 1)Present
_VacuumPump : INT := 1; //0)None 1)Sterling 2)Nash Elmo
_GAS2InjectionType : INT ; //0)None 1)N2 2)Steril Air
_InjectionPress_Ctrl : INT := 1; //0)Manual 1)Norgren v1 2)Norgren v2
_ProdPressureType : INT ; //0)Only CO2 1)CO2+SterilAir 2)CO2+N2
_CIPHeatType : INT ; //0)Steam 1)Electric
_EHS_NrRes : INT := 6; //Number of Heat Resistances
END_STRUCT ;
END_STRUCT ;
Spare1 : ARRAY [1 .. 9 ] OF INT ;
_RVM301_DeadBand : REAL := 5.000000e-02;
_RVM301_Kp : REAL := 9.000000e+01;
Actual_Recipe_Parameters : "Recipe_Prod";
Spare2 : ARRAY [1 .. 5 ] OF INT ;
Next_Recipe_Name : STRING [32 ] := ' ';
Next_Recipe_Number : INT ;
Spare3 : ARRAY [1 .. 18 ] OF INT ;
ProcessSetup : STRUCT
Spare000 : REAL ;
Spare040 : REAL ;
_KWaterLoss : REAL := 1.000000e-03; //Friction Loss Constant in Serpentine
_KSyrupLoss : REAL := 7.800000e-03; //Friction Loss Constant in Syrup Pipe
_KProdLoss : REAL := 1.390000e-02; //Pressure Loss Factor
_KPPM303 : REAL := 5.700000e+00; //Frequency Overpressure Pump P3 Constant [Hz/mm]
_BaialageRVM301OVMin : REAL := 2.000000e+00; //Baialage Minimum Flow (Nm3/h)
_SyrupLinePressure : REAL := 2.200000e+00; //Syrup Line pressure at VEP2 valve
_CIPRMM301OV : REAL := 1.000000e+01; //Water Valve Opening During CIP
_CIPRMP302OV : REAL := 1.500000e+01; //Syrup Valve Opening During CIP
_CIPTM301MinLevel : REAL := 3.500000e+01; //Product Tank Minimum Level In CIP
_CIPTM301MaxLevel : REAL := 5.500000e+01; //Product Tank Maximum Level In CIP
_CIPPPM303Freq : REAL := 5.000000e+01; //CIP frequency Value [Hz]
_CIPTP301MinLevel : REAL := 2.500000e+01; //Syrup Tank Minimum Level In CIP
_CIPTP301MaxLevel : REAL := 4.500000e+01; //Syrup Tank Maximum Level In CIP
_RinseRMM301OV : REAL := 1.000000e+01; //Water Valve Opening During Rinse
_RinseRMP302OV : REAL := 1.400000e+01; //Syrup Valve Opening During Rinse
_RinseTM301Press : REAL := 3.000000e-01; //Product Tank Pressure In Rinse
_RinsePPM303Freq : REAL := 5.000000e+01; //Rinse frequency Value [Hz]
_DrainTM301Press : REAL := 1.000000e+00; //Buffer Tank Draining Pressure
_KRecBlendError : REAL := 2.000000e+00; //Blend Error Recovery CONSTANT
_KRecCarboCO2Error : REAL := 2.000000e+00; //Carbonation Error Recovery Constant
_MaxBlendError : REAL := 1.000000e+02; //Blend Error Maximum Value
_MaxCarboCO2Error : REAL := 5.000000e+02; //Carbonation Error Maximum Value
_StartUpBrixExtraWater : REAL := 4.700000e+01;
_StartUpCO2ExtraWater : REAL := 8.000000e+00;
_StartUpPPM303Freq : REAL := 2.000000e+01; //Start Up frequency Value [Hz]
_SyrupRoomTank : INT := 1;
_SyrupRunOutLiters : REAL := 2.900000e+02;
_InjCO2Press_Offset : REAL := 5.000000e-01;
_InjCO2Press_MinFlow : REAL := 4.500000e+02;
_InjCO2Press_MaxFlow : REAL := 2.500000e+03;
_CarboCO2Pressure : REAL := 1.250000e+01; //CO2 Pressure Infeed Line
_N2MinPressure : REAL := 1.000000e+00; //N2 Minimum Pressure Infeed Line
_DiffSensor_Height : REAL := 3.950000e+02; //Sensor Height from Soil [mm]
_DiffSensor_DeltaHeight : REAL := -2.500000e+01; //Sensor Plates Height Difference [mm]
_DiffSensor_Offset : REAL := 3.618000e+01; //Sensor Offset Read with zero pressure (all valves open) in [mm]
_FillingValveHeight : REAL := 1.400000e+03; //Filling Valve Height from soil [mm]
_FillerDiameter : REAL := 2.520000e+03; //Filler Carousel Diameter [mm]
_FillingValveNum : INT := 91; //Filling Valves Number
_FillerProdPipeDN : REAL := 1.000000e+02;
_FillerProdPipeMass : REAL := 1.600000e+02;
_FillingTime : REAL := 3.200000e+00;
_TM301Height_0 : REAL := 1.050000e+03; //Level at 0% Tank Level Height in mm
_TM301LevelPerc_2 : REAL := 4.600000e+01; //Second level percentage
_TM301Height_2 : REAL := 1.625000e+03; //Second level Height in mm
_RVN304Factor : REAL := 1.000000e+00; //DeareationFlow/WaterFlow
_DrainTM301Flushing : REAL := 1.300000e+00;
_FirstProdExtraBrix : REAL := 5.000000e-02;
_FirstProdDietExtraSyr : REAL := 1.400000e-03;
_EndProdLastSyrlt : REAL ; //End Production Last syrup liters
_TM301DrainSt0Time : WORD := W#16#A; //sec
_TM301DrainSt1Time : WORD := W#16#50; //sec
_ProdPipeRunOutSt0Time : WORD := W#16#1; //sec
_RMM301ProdPipeRunOu : REAL := 3.000000e+01;
_RMP302ProdPipeRunOu : REAL := 4.000000e+01;
_ProdPipeRunOutAmount : REAL := 3.000000e+01;
_TM301RunOutChiller : REAL := 5.000000e+00;
_MinSpeedNominalProd : REAL := 4.000000e-01; //Min Speed for Nominal Production
_MinSpeedSlowProd : REAL := 3.000000e-01; //Min Speed for Very Low Production
_FastChgOvrTM301DrnPrss : REAL := 9.000000e-01; //Fast Change Over Product Tank Draining Pressure in Blendfill
_CIPTN301MinLevel : REAL := 3.500000e+01; //Deaireator Tank Minimum Level In CIP
_CIPTN301MaxLevel : REAL := 6.000000e+01; //Deaireator Tank Maximum Level In CIP
_ProdPPN304Freq : REAL := 5.000000e+01;
_GAS2InjectionPress : REAL := 4.000000e+00;
_BaialageRVM301OVMax : REAL := 2.000000e+01; //Baialage Production Flow Multiplier
_RinsePPN301Freq : REAL := 5.000000e+00;
_CIPPPN301Freq : REAL := 5.000000e+00;
_RinsePPP302Freq : REAL := 5.000000e+00;
_CIPPPP302Freq : REAL := 5.000000e+00;
_PercSyrupBrixSyrStarUp : REAL := 2.500000e+01;
_RefTempCoolingCTRL : REAL ;
_H2OSerpPrimingVolume : REAL := 1.500000e+02; //Water Serpentine Volume + Water Chiller Volume
_AVN301_Nozzle_Kv : REAL := 1.650000e+02; //AVN301 Nozzle Kv
_AVN302_Nozzle_Kv : REAL := 2.600000e+02; //AVN302 Nozzle Kv
_AVN303_Nozzle_Kv : REAL := 1.650000e+02; //AVN303 Nozzle Kv
_DeoxSpryball_Kv : REAL := 6.700000e+01; //Deox Spryball Kv
_PremixedLineDrainTime : INT := 300; //Premixed Product Line Drain Time
_PPN301_H_MaxFlow : REAL := 9.000000e+01; //PPN301 Pump Head with Max Flow [m]
_PPN301_H_MinFlow : REAL := 8.700000e+01; //PPN301 Pump Head with Min Flow [m]
_PPN301_MaxFlow : REAL := 5.070000e+02; //PPN301 Max Flow [l/min]
_PPN301_MinFlow : REAL := 2.110000e+02; //PPN301 Min Flow [l/min]
_PPP302_H_MaxFlow : REAL := 8.600000e+01; //PPP302 Pump Head with Max Flow [m]
_PPP302_H_MinFlow : REAL := 8.500000e+01; //PPP302 Pump Head with Min Flow [m]
_PPP302_MaxFlow : REAL := 1.150000e+02; //PPP302 Max Flow [l/min]
_PPP302_MinFlow : REAL := 3.200000e+01; //PPP302 Min Flow [l/min]
_RinsePPM306Freq : REAL := 5.000000e+00;
_CIPPPM306Freq : REAL := 5.000000e+00;
_PPM307_H_MaxFlow : REAL ; //PPM307 Pump Head with Max Flow [m]
_PPM307_H_MinFlow : REAL ; //PPM307 Pump Head with Min Flow [m]
_PPM307_MaxFlow : REAL ; //PPM307 Max Flow [l/min]
_PPM307_MinFlow : REAL ; //PPM307 Min Flow [l/min]
_Temp0_VacuumCtrl : REAL := 1.800000e+01; //PPN304 Target Temperature - OPTION PPN304 Sterling Type
_Temp1_VacuumCtrl : REAL := 2.000000e+00; //PPN304 High Treshold Temperature Delta - OPTION PPN304 Sterling Type
_Temp2_VacuumCtrl : REAL := 2.000000e+00; //PPN304 Low Treshold Temperature Delta - OPTION PPN304 Sterling Type
_Temp3_VacuumCtrl : REAL := 5.000000e+01; //PPN304 Warning Temperature - OPTION PPN304 Sterling Type
_Temp4_VacuumCtrl : REAL := 5.000000e+01; //PPN304 Alarm Temperature - OPTION PPN304 Sterling Type
_T1_VacuumCtrl : DINT := L#1500; //PPN304 Time 1 [msec] - OPTION PPN304 Sterling Type
_T2_VacuumCtrl : DINT := L#1500; //PPN304 Time 2 [msec] - OPTION PPN304 Sterling Type
_T3_VacuumCtrl : DINT := L#1000; //PPN304 Time 3 [msec] - OPTION PPN304 Sterling Type
_T4_VacuumCtrl : DINT := L#1000; //PPN304 Time 4 [msec] - OPTION PPN304 Sterling Type
_ICS_VolDosWorkTimePAA : INT := 30; //ICS - DS - Dosing Working Time [sec]
_ICS_VolPauseTimePAA : INT := 30; //ICS - DS - Dosing Pause Time [sec]
_ICS_PAAPulseWeight : INT := 10; //ICS - DS - PAA Pulse Weight [(L/Pulse)/100]
_ICS_CausticPulseWeight : INT := 10; //ICS - DS - Caustic Pulse Weight [(L/Pulse)/100]
_ICS_AcidPulseWeight : INT := 10; //ICS - DS - Acid Pulse Weight [(L/Pulse)/100]
_ICS_VolumeRestOfLine : REAL := 3.500000e+02; //ICS - DS - Volume of the Rest of the Line (Filler + Piping) [L]
_ICS_VolDosWorkTimeCaus : INT := 30; //ICS - DS - Dosing Working Time [sec]
_ICS_VolDosPauseTimeCaus : INT := 30; //ICS - DS - Dosing Pause Time [sec]
_ICS_VolDosWorkTimeAcid : INT := 30; //ICS - DS - Dosing Working Time [sec]
_ICS_VolDosPauseTimeAcid : INT := 30; //ICS - DS - Dosing Pause Time [sec]
_ICS_ConcDosWorkTimeCaus : INT := 30; //ICS - DS - Dosing Working Time [sec]
_ICS_ConcDosPausTimeCaus : INT := 30; //ICS - DS - Dosing Pause Time [sec]
_ICS_ConcDosWorkTimeAcid : INT := 30; //ICS - DS - Dosing Working Time [sec]
_ICS_ConcDosPausTimeAcid : INT := 30; //ICS - DS - Dosing Pause Time [sec]
_RinsePPM307Freq : REAL := 3.000000e+01;
_CIPPPM307Freq : REAL := 3.000000e+01;
_CIP2StepTN301Lvl : REAL ; //Local CIP - 2 Step loading TN301 Level
_CIP2StepTM301Lvl : REAL ; //Local CIP - 2 Step loading TM301 Level
_CIP2StepTP301Lvl : REAL ; //Local CIP - 2 Step loading TP301 Level
_PumpNominalFreq : REAL := 5.000000e+01; //50.0 Hz or 60.0 Hz
END_STRUCT ;
_SwitchOff_DensityOK : BOOL ;
END_STRUCT ;
BEGIN
Processor_Options.Blender_OPT._ModelNum := 6;
Processor_Options.Blender_OPT._CO2_Offset := 4.500000e-01;
Processor_Options.Blender_OPT._MaxSyrDeltaBrix := 8.000000e-01;
Processor_Options.Blender_OPT._BrixMeter := TRUE;
Processor_Options.Blender_OPT.Spare101 := FALSE;
Processor_Options.Blender_OPT._TrackH2OEnable := FALSE;
Processor_Options.Blender_OPT._PAmPDSType := FALSE;
Processor_Options.Blender_OPT._HistoricalTrends := TRUE;
Processor_Options.Blender_OPT._PowerMeter := FALSE;
Processor_Options.Blender_OPT._Report := TRUE;
Processor_Options.Blender_OPT._Balaiage := FALSE;
Processor_Options.Blender_OPT._Valves_FullFeedback := TRUE;
Processor_Options.Blender_OPT._Valves_SingleFeedback := FALSE;
Processor_Options.Blender_OPT._PumpsSafetySwitches := FALSE;
Processor_Options.Blender_OPT._SurgeProtectionAct := FALSE;
Processor_Options.Blender_OPT._DBC_Type := FALSE;
Processor_Options.Blender_OPT._CO2InletMeter := TRUE;
Processor_Options.Blender_OPT._ProductO2Meter := FALSE;
Processor_Options.Blender_OPT._CopressedAirInletMeter := FALSE;
Processor_Options.Blender_OPT._MeterType := 6;
Processor_Options.Blender_OPT._MeterReceiveOnly := FALSE;
Processor_Options.Blender_OPT._SyrBrixMeter := FALSE;
Processor_Options.Blender_OPT._Flooding_Start_Up := FALSE;
Processor_Options.Blender_OPT._FastChangeOverEnabled := TRUE;
Processor_Options.Blender_OPT._WaterInletMeter := FALSE;
Processor_Options.Blender_OPT._BlendFillSystem := TRUE;
Processor_Options.Blender_OPT._TrackFillerSpeed := TRUE;
Processor_Options.Blender_OPT._SignalExchange := 1;
Processor_Options.Blender_OPT._CoolerPresent := TRUE;
Processor_Options.Blender_OPT._CoolerControl := 4;
Processor_Options.Blender_OPT._CoolerType := 0;
Processor_Options.Blender_OPT._LocalCIP := FALSE;
Processor_Options.Blender_OPT._ICS_CustomerHotWater := FALSE;
Processor_Options.Blender_OPT._ICS_CustomerChemRecov := FALSE;
Processor_Options.Blender_OPT._CIPSignalExchange := FALSE;
Processor_Options.Blender_OPT._ICS_CustomerChemicals := FALSE;
Processor_Options.Blender_OPT._CarboPresent := TRUE;
Processor_Options.Blender_OPT._InverterSyrupPumpPPP302 := FALSE;
Processor_Options.Blender_OPT._InverterWaterPumpPPN301 := FALSE;
Processor_Options.Blender_OPT._DoubleDeair := TRUE;
Processor_Options.Blender_OPT._DeairPreMixed := FALSE;
Processor_Options.Blender_OPT._Deaireation := TRUE;
Processor_Options.Blender_OPT._StillWaterByPass := FALSE;
Processor_Options.Blender_OPT._ManifoldSetting := TRUE;
Processor_Options.Blender_OPT._InverterProdPumpPPM303 := FALSE;
Processor_Options.Blender_OPT._SidelCip := FALSE;
Processor_Options.Blender_OPT._EthernetCom_CpuPN_CP := TRUE;
Processor_Options.Blender_OPT._2ndOutlet := 0;
Processor_Options.Blender_OPT._Promass := 2;
Processor_Options.Blender_OPT._WaterPromass := TRUE;
Processor_Options.Blender_OPT._ProductConductimeter := FALSE;
Processor_Options.Blender_OPT._ICS_CustomerH2ORecov := FALSE;
Processor_Options.Blender_OPT.Spare303 := FALSE;
Processor_Options.Blender_OPT._CO2_GAS2_Injection := FALSE;
Processor_Options.Blender_OPT._InverterVacuuPumpPPN304 := FALSE;
Processor_Options.Blender_OPT._InverterBoostPumpPPM307 := FALSE;
Processor_Options.Blender_OPT._RunOut_Water := TRUE;
Processor_Options.Blender_OPT._FlowMeterType := TRUE;
Processor_Options.Blender_OPT._SidelFiller := FALSE;
Processor_Options.Blender_OPT._Simulation := FALSE;
Processor_Options.Blender_OPT._ProductCoolingCTRL := FALSE;
Processor_Options.Blender_OPT._ChillerCTRL := FALSE;
Processor_Options.Blender_OPT._CO2_SterileFilter := TRUE;
Processor_Options.Blender_OPT._InverterRecirPumpPPM306 := FALSE;
Processor_Options.Blender_OPT._ProdPressReleaseRVM304 := FALSE;
Processor_Options.Blender_OPT._VacuumPump := 1;
Processor_Options.Blender_OPT._GAS2InjectionType := 0;
Processor_Options.Blender_OPT._InjectionPress_Ctrl := 1;
Processor_Options.Blender_OPT._ProdPressureType := 0;
Processor_Options.Blender_OPT._CIPHeatType := 0;
Processor_Options.Blender_OPT._EHS_NrRes := 6;
Spare1[1] := 0;
Spare1[2] := 0;
Spare1[3] := 0;
Spare1[4] := 0;
Spare1[5] := 0;
Spare1[6] := 0;
Spare1[7] := 0;
Spare1[8] := 0;
Spare1[9] := 0;
_RVM301_DeadBand := 5.000000e-02;
_RVM301_Kp := 9.000000e+01;
Actual_Recipe_Parameters._Name := '';
Actual_Recipe_Parameters._EnProdTemp := TRUE;
Actual_Recipe_Parameters._SyrFlushing := FALSE;
Actual_Recipe_Parameters._GAS2_Injection := FALSE;
Actual_Recipe_Parameters._Eq_Pression_Selected := FALSE;
Actual_Recipe_Parameters._DeoxStripEn := FALSE;
Actual_Recipe_Parameters._DeoxVacuumEn := TRUE;
Actual_Recipe_Parameters._DeoxPreMixed := FALSE;
Actual_Recipe_Parameters._EnBlowOffProdPipeCO2Fil := FALSE;
Actual_Recipe_Parameters._WaterSelection := B#16#0;
Actual_Recipe_Parameters._FillerNextRecipeNum := B#16#0;
Actual_Recipe_Parameters._BottleShape := B#16#0;
Actual_Recipe_Parameters._Type := 2;
Actual_Recipe_Parameters._ProdMeterRecipeNum := 1;
Actual_Recipe_Parameters._SyrupBrix := 4.625000e+01;
Actual_Recipe_Parameters._SyrupDensity := 1.206908e+00;
Actual_Recipe_Parameters._SyrupFactor := 1.000000e+00;
Actual_Recipe_Parameters._ProductBrix := 1.000000e+01;
Actual_Recipe_Parameters._ProductionRate := 3.800000e+02;
Actual_Recipe_Parameters._Ratio := 4.238896e+00;
Actual_Recipe_Parameters._ProdBrixOffset := 2.500000e-01;
Actual_Recipe_Parameters._CO2Vols := 2.550000e+00;
Actual_Recipe_Parameters._CO2Fact := 9.400000e-01;
Actual_Recipe_Parameters._ProdTankPress := 4.400000e+00;
Actual_Recipe_Parameters._SP_ProdTemp := 1.700000e+01;
Actual_Recipe_Parameters._PrdTankMinLevel := 3.500000e+01;
Actual_Recipe_Parameters._WaterValveSave := 0.000000e+00;
Actual_Recipe_Parameters._SyrupValveSave := 0.000000e+00;
Actual_Recipe_Parameters._CarboCO2ValveSave := 0.000000e+00;
Actual_Recipe_Parameters._ProdMeterHighBrix := 1.030000e+01;
Actual_Recipe_Parameters._ProdMeterLowBrix := 9.830000e+00;
Actual_Recipe_Parameters._ProdMeterHighCO2 := 2.900000e+00;
Actual_Recipe_Parameters._ProdMeterLowCO2 := 2.300000e+00;
Actual_Recipe_Parameters._ProdMeter_ZeroCO2 := 0.000000e+00;
Actual_Recipe_Parameters._ProdMeter_ZeroBrix := 0.000000e+00;
Actual_Recipe_Parameters._ProdHighCond := 0.000000e+00;
Actual_Recipe_Parameters._ProdLowCond := 0.000000e+00;
Actual_Recipe_Parameters._BottleSize := 0.000000e+00;
Actual_Recipe_Parameters._FillingValveHead_SP := 0.000000e+00;
Actual_Recipe_Parameters._SyrMeter_ZeroBrix := 0.000000e+00;
Actual_Recipe_Parameters._FirstProdExtraCO2Fact := 1.020000e+00;
Actual_Recipe_Parameters._Gas2Vols := 0.000000e+00;
Actual_Recipe_Parameters._Gas2Fact := 0.000000e+00;
Actual_Recipe_Parameters._SyrupPumpPressure := 0.000000e+00;
Actual_Recipe_Parameters._WaterPumpPressure := 0.000000e+00;
Actual_Recipe_Parameters._CO2_Air_N2_PressSelect := 0;
Actual_Recipe_Parameters._KFactRVM304BlowOff := 0.000000e+00;
Actual_Recipe_Parameters._ProdRecircPumpFreq := 0.000000e+00;
Actual_Recipe_Parameters._ProdBoosterPumpPress := 0.000000e+00;
Actual_Recipe_Parameters._ProdSendPumpFreq := 0.000000e+00;
Spare2[1] := 0;
Spare2[2] := 0;
Spare2[3] := 0;
Spare2[4] := 0;
Spare2[5] := 0;
Next_Recipe_Name := 'cambio 1$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00';
Next_Recipe_Number := 0;
Spare3[1] := 0;
Spare3[2] := 0;
Spare3[3] := 0;
Spare3[4] := 0;
Spare3[5] := 0;
Spare3[6] := 0;
Spare3[7] := 0;
Spare3[8] := 0;
Spare3[9] := 0;
Spare3[10] := 0;
Spare3[11] := 0;
Spare3[12] := 0;
Spare3[13] := 0;
Spare3[14] := 0;
Spare3[15] := 0;
Spare3[16] := 0;
Spare3[17] := 0;
Spare3[18] := 0;
ProcessSetup.Spare000 := 0.000000e+00;
ProcessSetup.Spare040 := 0.000000e+00;
ProcessSetup._KWaterLoss := 1.000000e-03;
ProcessSetup._KSyrupLoss := 7.800000e-03;
ProcessSetup._KProdLoss := 1.390000e-02;
ProcessSetup._KPPM303 := 5.700000e+00;
ProcessSetup._BaialageRVM301OVMin := 2.000000e+00;
ProcessSetup._SyrupLinePressure := 2.200000e+00;
ProcessSetup._CIPRMM301OV := 1.000000e+01;
ProcessSetup._CIPRMP302OV := 1.500000e+01;
ProcessSetup._CIPTM301MinLevel := 3.500000e+01;
ProcessSetup._CIPTM301MaxLevel := 5.500000e+01;
ProcessSetup._CIPPPM303Freq := 5.000000e+01;
ProcessSetup._CIPTP301MinLevel := 2.500000e+01;
ProcessSetup._CIPTP301MaxLevel := 4.500000e+01;
ProcessSetup._RinseRMM301OV := 1.000000e+01;
ProcessSetup._RinseRMP302OV := 1.400000e+01;
ProcessSetup._RinseTM301Press := 3.000000e-01;
ProcessSetup._RinsePPM303Freq := 5.000000e+01;
ProcessSetup._DrainTM301Press := 1.000000e+00;
ProcessSetup._KRecBlendError := 2.000000e+00;
ProcessSetup._KRecCarboCO2Error := 2.000000e+00;
ProcessSetup._MaxBlendError := 1.000000e+02;
ProcessSetup._MaxCarboCO2Error := 5.000000e+02;
ProcessSetup._StartUpBrixExtraWater := 4.700000e+01;
ProcessSetup._StartUpCO2ExtraWater := 8.000000e+00;
ProcessSetup._StartUpPPM303Freq := 2.000000e+01;
ProcessSetup._SyrupRoomTank := 1;
ProcessSetup._SyrupRunOutLiters := 2.900000e+02;
ProcessSetup._InjCO2Press_Offset := 5.000000e-01;
ProcessSetup._InjCO2Press_MinFlow := 4.500000e+02;
ProcessSetup._InjCO2Press_MaxFlow := 2.500000e+03;
ProcessSetup._CarboCO2Pressure := 1.250000e+01;
ProcessSetup._N2MinPressure := 1.000000e+00;
ProcessSetup._DiffSensor_Height := 3.950000e+02;
ProcessSetup._DiffSensor_DeltaHeight := -2.500000e+01;
ProcessSetup._DiffSensor_Offset := 3.618000e+01;
ProcessSetup._FillingValveHeight := 1.400000e+03;
ProcessSetup._FillerDiameter := 2.520000e+03;
ProcessSetup._FillingValveNum := 91;
ProcessSetup._FillerProdPipeDN := 1.000000e+02;
ProcessSetup._FillerProdPipeMass := 1.600000e+02;
ProcessSetup._FillingTime := 3.200000e+00;
ProcessSetup._TM301Height_0 := 1.050000e+03;
ProcessSetup._TM301LevelPerc_2 := 4.600000e+01;
ProcessSetup._TM301Height_2 := 1.625000e+03;
ProcessSetup._RVN304Factor := 1.000000e+00;
ProcessSetup._DrainTM301Flushing := 1.300000e+00;
ProcessSetup._FirstProdExtraBrix := 5.000000e-02;
ProcessSetup._FirstProdDietExtraSyr := 1.400000e-03;
ProcessSetup._EndProdLastSyrlt := 0.000000e+00;
ProcessSetup._TM301DrainSt0Time := W#16#A;
ProcessSetup._TM301DrainSt1Time := W#16#50;
ProcessSetup._ProdPipeRunOutSt0Time := W#16#1;
ProcessSetup._RMM301ProdPipeRunOu := 3.000000e+01;
ProcessSetup._RMP302ProdPipeRunOu := 4.000000e+01;
ProcessSetup._ProdPipeRunOutAmount := 3.000000e+01;
ProcessSetup._TM301RunOutChiller := 5.000000e+00;
ProcessSetup._MinSpeedNominalProd := 4.000000e-01;
ProcessSetup._MinSpeedSlowProd := 3.000000e-01;
ProcessSetup._FastChgOvrTM301DrnPrss := 9.000000e-01;
ProcessSetup._CIPTN301MinLevel := 3.500000e+01;
ProcessSetup._CIPTN301MaxLevel := 6.000000e+01;
ProcessSetup._ProdPPN304Freq := 5.000000e+01;
ProcessSetup._GAS2InjectionPress := 4.000000e+00;
ProcessSetup._BaialageRVM301OVMax := 2.000000e+01;
ProcessSetup._RinsePPN301Freq := 5.000000e+00;
ProcessSetup._CIPPPN301Freq := 5.000000e+00;
ProcessSetup._RinsePPP302Freq := 5.000000e+00;
ProcessSetup._CIPPPP302Freq := 5.000000e+00;
ProcessSetup._PercSyrupBrixSyrStarUp := 2.500000e+01;
ProcessSetup._RefTempCoolingCTRL := 0.000000e+00;
ProcessSetup._H2OSerpPrimingVolume := 1.500000e+02;
ProcessSetup._AVN301_Nozzle_Kv := 1.650000e+02;
ProcessSetup._AVN302_Nozzle_Kv := 2.600000e+02;
ProcessSetup._AVN303_Nozzle_Kv := 1.650000e+02;
ProcessSetup._DeoxSpryball_Kv := 6.700000e+01;
ProcessSetup._PremixedLineDrainTime := 300;
ProcessSetup._PPN301_H_MaxFlow := 9.000000e+01;
ProcessSetup._PPN301_H_MinFlow := 8.700000e+01;
ProcessSetup._PPN301_MaxFlow := 5.070000e+02;
ProcessSetup._PPN301_MinFlow := 2.110000e+02;
ProcessSetup._PPP302_H_MaxFlow := 8.600000e+01;
ProcessSetup._PPP302_H_MinFlow := 8.500000e+01;
ProcessSetup._PPP302_MaxFlow := 1.150000e+02;
ProcessSetup._PPP302_MinFlow := 3.200000e+01;
ProcessSetup._RinsePPM306Freq := 5.000000e+00;
ProcessSetup._CIPPPM306Freq := 5.000000e+00;
ProcessSetup._PPM307_H_MaxFlow := 0.000000e+00;
ProcessSetup._PPM307_H_MinFlow := 0.000000e+00;
ProcessSetup._PPM307_MaxFlow := 0.000000e+00;
ProcessSetup._PPM307_MinFlow := 0.000000e+00;
ProcessSetup._Temp0_VacuumCtrl := 1.800000e+01;
ProcessSetup._Temp1_VacuumCtrl := 2.000000e+00;
ProcessSetup._Temp2_VacuumCtrl := 2.000000e+00;
ProcessSetup._Temp3_VacuumCtrl := 5.000000e+01;
ProcessSetup._Temp4_VacuumCtrl := 5.000000e+01;
ProcessSetup._T1_VacuumCtrl := L#1500;
ProcessSetup._T2_VacuumCtrl := L#1500;
ProcessSetup._T3_VacuumCtrl := L#1000;
ProcessSetup._T4_VacuumCtrl := L#1000;
ProcessSetup._ICS_VolDosWorkTimePAA := 30;
ProcessSetup._ICS_VolPauseTimePAA := 30;
ProcessSetup._ICS_PAAPulseWeight := 10;
ProcessSetup._ICS_CausticPulseWeight := 10;
ProcessSetup._ICS_AcidPulseWeight := 10;
ProcessSetup._ICS_VolumeRestOfLine := 3.500000e+02;
ProcessSetup._ICS_VolDosWorkTimeCaus := 30;
ProcessSetup._ICS_VolDosPauseTimeCaus := 30;
ProcessSetup._ICS_VolDosWorkTimeAcid := 30;
ProcessSetup._ICS_VolDosPauseTimeAcid := 30;
ProcessSetup._ICS_ConcDosWorkTimeCaus := 30;
ProcessSetup._ICS_ConcDosPausTimeCaus := 30;
ProcessSetup._ICS_ConcDosWorkTimeAcid := 30;
ProcessSetup._ICS_ConcDosPausTimeAcid := 30;
ProcessSetup._RinsePPM307Freq := 3.000000e+01;
ProcessSetup._CIPPPM307Freq := 3.000000e+01;
ProcessSetup._CIP2StepTN301Lvl := 0.000000e+00;
ProcessSetup._CIP2StepTM301Lvl := 0.000000e+00;
ProcessSetup._CIP2StepTP301Lvl := 0.000000e+00;
ProcessSetup._PumpNominalFreq := 5.000000e+01;
_SwitchOff_DensityOK := FALSE;
END_DATA_BLOCK

View File

@ -0,0 +1,6 @@
{
"name": "S7 DB Utilities",
"description": "Utilidades para Trabajar con DBs de Siemens S7",
"version": "1.0",
"author": "Miguel"
}

View File

@ -0,0 +1,208 @@
# Documentación para DB: HMI_Blender_Parameters
| Address | Name | Type | Initial Value | Actual Value | Comment |
|---|---|---|---|---|---|
| 0.0 | Processor_Options | STRUCT | | | |
| 0.0 | Processor_Options.Blender_OPT | STRUCT | | | |
| 0.0 | Processor_Options.Blender_OPT._ModelNum | INT | 6 | 6 | |
| 2.0 | Processor_Options.Blender_OPT._CO2_Offset | REAL | 4.500000e-01 | 4.500000e-01 | |
| 6.0 | Processor_Options.Blender_OPT._MaxSyrDeltaBrix | REAL | 8.000000e-01 | 8.000000e-01 | |
| 10.0 | Processor_Options.Blender_OPT._BrixMeter | BOOL | TRUE | TRUE | |
| 10.1 | Processor_Options.Blender_OPT.Spare101 | BOOL | | FALSE | |
| 10.2 | Processor_Options.Blender_OPT._TrackH2OEnable | BOOL | | FALSE | |
| 10.3 | Processor_Options.Blender_OPT._PAmPDSType | BOOL | | FALSE | 0)Cobrix 2000 1)Carbo 2000 |
| 10.4 | Processor_Options.Blender_OPT._HistoricalTrends | BOOL | TRUE | TRUE | 0)Not Present 1)Present |
| 10.5 | Processor_Options.Blender_OPT._PowerMeter | BOOL | | FALSE | 0)Not Present 1)Present |
| 10.6 | Processor_Options.Blender_OPT._Report | BOOL | TRUE | TRUE | 0)Not Present 1)Present |
| 10.7 | Processor_Options.Blender_OPT._Balaiage | BOOL | | FALSE | |
| 11.0 | Processor_Options.Blender_OPT._Valves_FullFeedback | BOOL | TRUE | TRUE | Valves control Full feedback |
| 11.1 | Processor_Options.Blender_OPT._Valves_SingleFeedback | BOOL | | FALSE | Valves control Single feedback |
| 11.2 | Processor_Options.Blender_OPT._PumpsSafetySwitches | BOOL | | FALSE | Pumps with Safety Switches |
| 11.3 | Processor_Options.Blender_OPT._SurgeProtectionAct | BOOL | | FALSE | |
| 11.4 | Processor_Options.Blender_OPT._DBC_Type | BOOL | | FALSE | 0) Deox,Carbo,Blend 1)Deox,Blend,Carbo |
| 11.5 | Processor_Options.Blender_OPT._CO2InletMeter | BOOL | TRUE | TRUE | 0)Not Present 1)Present |
| 11.6 | Processor_Options.Blender_OPT._ProductO2Meter | BOOL | | FALSE | 0)Not Present 1)Present |
| 11.7 | Processor_Options.Blender_OPT._CopressedAirInletMeter | BOOL | | FALSE | 0)Not Present 1)Present |
| 12.0 | Processor_Options.Blender_OPT._MeterType | INT | 6 | 6 | 1)Maselli 2)AntoonPaar 3)4-20mA 4)UC05 UR22 5)mPDSPA 6)MR02 |
| 14.0 | Processor_Options.Blender_OPT._MeterReceiveOnly | BOOL | | FALSE | |
| 14.1 | Processor_Options.Blender_OPT._SyrBrixMeter | BOOL | | FALSE | |
| 14.2 | Processor_Options.Blender_OPT._Flooding_Start_Up | BOOL | | FALSE | 0)Not Selected 1)Selected |
| 14.3 | Processor_Options.Blender_OPT._FastChangeOverEnabled | BOOL | TRUE | TRUE | |
| 14.4 | Processor_Options.Blender_OPT._WaterInletMeter | BOOL | | FALSE | 0)Not Present 1)Present |
| 14.5 | Processor_Options.Blender_OPT._BlendFillSystem | BOOL | TRUE | TRUE | |
| 14.6 | Processor_Options.Blender_OPT._TrackFillerSpeed | BOOL | TRUE | TRUE | |
| 16.0 | Processor_Options.Blender_OPT._SignalExchange | INT | 1 | 1 | FILLER - 0= Hardwire; 1= Ethernet |
| 18.0 | Processor_Options.Blender_OPT._CoolerPresent | BOOL | TRUE | TRUE | |
| 20.0 | Processor_Options.Blender_OPT._CoolerControl | INT | 4 | 4 | 0)External 1)Water 2)Product 3)Water+Product-2 Ctrl 4)Water+Product-1 Ctrl |
| 22.0 | Processor_Options.Blender_OPT._CoolerType | INT | | 0 | 0)Glycol 1)Ammonia |
| 24.0 | Processor_Options.Blender_OPT._LocalCIP | BOOL | | FALSE | |
| 24.1 | Processor_Options.Blender_OPT._ICS_CustomerHotWater | BOOL | | FALSE | 0)No Hot Water from Customer 1)Hot Water from Customer Available |
| 24.2 | Processor_Options.Blender_OPT._ICS_CustomerChemRecov | BOOL | | FALSE | 0)No Customer's Chemicals Recovery 1)Customer's Chemicals Recovery Available |
| 24.3 | Processor_Options.Blender_OPT._CIPSignalExchange | BOOL | | FALSE | CIP - 0= Hardwire; 1= Ethernet |
| 24.4 | Processor_Options.Blender_OPT._ICS_CustomerChemicals | BOOL | | FALSE | 0)Chemicals from ICS 1)Chemicals from Customer |
| 24.5 | Processor_Options.Blender_OPT._CarboPresent | BOOL | TRUE | TRUE | |
| 24.6 | Processor_Options.Blender_OPT._InverterSyrupPumpPPP302 | BOOL | | FALSE | 0)Not Present 1)Present |
| 24.7 | Processor_Options.Blender_OPT._InverterWaterPumpPPN301 | BOOL | | FALSE | 0)Not Present 1)Present |
| 25.0 | Processor_Options.Blender_OPT._DoubleDeair | BOOL | TRUE | TRUE | |
| 25.1 | Processor_Options.Blender_OPT._DeairPreMixed | BOOL | | FALSE | Deox Premixed Inlet |
| 25.2 | Processor_Options.Blender_OPT._Deaireation | BOOL | TRUE | TRUE | 0)SAG 1)SAE/SAF |
| 25.3 | Processor_Options.Blender_OPT._StillWaterByPass | BOOL | | FALSE | |
| 25.4 | Processor_Options.Blender_OPT._ManifoldSetting | BOOL | TRUE | TRUE | 0)Manual 1)Automatic |
| 25.5 | Processor_Options.Blender_OPT._InverterProdPumpPPM303 | BOOL | | FALSE | |
| 25.6 | Processor_Options.Blender_OPT._SidelCip | BOOL | | FALSE | |
| 25.7 | Processor_Options.Blender_OPT._EthernetCom_CpuPN_CP | BOOL | TRUE | TRUE | 0)Comunication with CP 1)Comunication with CPU PN |
| 26.0 | Processor_Options.Blender_OPT._2ndOutlet | INT | | 0 | 0)No 2nd Outlet 1)2nd Outlet No Standalone 2)2nd Outlet Standalone |
| 28.0 | Processor_Options.Blender_OPT._Promass | INT | 2 | 2 | |
| 30.0 | Processor_Options.Blender_OPT._WaterPromass | BOOL | TRUE | TRUE | 0)Promag 1)Promass |
| 30.1 | Processor_Options.Blender_OPT._ProductConductimeter | BOOL | | FALSE | |
| 30.2 | Processor_Options.Blender_OPT._ICS_CustomerH2ORecov | BOOL | | FALSE | 0)No Customer's H2O Recovery 1)Customer's H2O Recovery Available |
| 30.3 | Processor_Options.Blender_OPT.Spare303 | BOOL | | FALSE | |
| 30.4 | Processor_Options.Blender_OPT._CO2_GAS2_Injection | BOOL | | FALSE | 0)Only CO2 Injection 1)GAS2 Injection |
| 30.5 | Processor_Options.Blender_OPT._InverterVacuuPumpPPN304 | BOOL | | FALSE | 0)Not Present 1)Present |
| 30.6 | Processor_Options.Blender_OPT._InverterBoostPumpPPM307 | BOOL | | FALSE | 0)Not Present 1)Present |
| 30.7 | Processor_Options.Blender_OPT._RunOut_Water | BOOL | TRUE | TRUE | 0)Syrup Runout without Water 1)Syrup runout with Water pushing |
| 31.0 | Processor_Options.Blender_OPT._FlowMeterType | BOOL | | TRUE | 0)Endrees Hauser -- 1)Micromotion |
| 31.1 | Processor_Options.Blender_OPT._SidelFiller | BOOL | | FALSE | 0)Filler Simonazzi -- 1)Filler Sidel Filling |
| 31.2 | Processor_Options.Blender_OPT._Simulation | BOOL | | FALSE | |
| 31.3 | Processor_Options.Blender_OPT._ProductCoolingCTRL | BOOL | | FALSE | 0)none 1) TTM307 |
| 31.4 | Processor_Options.Blender_OPT._ChillerCTRL | BOOL | | FALSE | Chiller Pressure Cross Control |
| 31.5 | Processor_Options.Blender_OPT._CO2_SterileFilter | BOOL | TRUE | TRUE | CO2 Inlet with Steril Filter |
| 31.6 | Processor_Options.Blender_OPT._InverterRecirPumpPPM306 | BOOL | | FALSE | 0)Not Present 1)Present |
| 31.7 | Processor_Options.Blender_OPT._ProdPressReleaseRVM304 | BOOL | | FALSE | 0)Not Present 1)Present |
| 32.0 | Processor_Options.Blender_OPT._VacuumPump | INT | 1 | 1 | 0)None 1)Sterling 2)Nash Elmo |
| 34.0 | Processor_Options.Blender_OPT._GAS2InjectionType | INT | | 0 | 0)None 1)N2 2)Steril Air |
| 36.0 | Processor_Options.Blender_OPT._InjectionPress_Ctrl | INT | 1 | 1 | 0)Manual 1)Norgren v1 2)Norgren v2 |
| 38.0 | Processor_Options.Blender_OPT._ProdPressureType | INT | | 0 | 0)Only CO2 1)CO2+SterilAir 2)CO2+N2 |
| 40.0 | Processor_Options.Blender_OPT._CIPHeatType | INT | | 0 | 0)Steam 1)Electric |
| 42.0 | Processor_Options.Blender_OPT._EHS_NrRes | INT | 6 | 6 | Number of Heat Resistances |
| 44.0 | Spare1 | ARRAY [1..9] OF INT | | | |
| 62.0 | _RVM301_DeadBand | REAL | 5.000000e-02 | 5.000000e-02 | |
| 66.0 | _RVM301_Kp | REAL | 9.000000e+01 | 9.000000e+01 | |
| 70.0 | Actual_Recipe_Parameters | "Recipe_Prod" | | | |
| 254.0 | Spare2 | ARRAY [1..5] OF INT | | | |
| 264.0 | Next_Recipe_Name | STRING[32] | ' ' | 'cambio 1$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00' | |
| 298.0 | Next_Recipe_Number | INT | | 0 | |
| 300.0 | Spare3 | ARRAY [1..18] OF INT | | | |
| 336.0 | ProcessSetup | STRUCT | | | |
| 336.0 | ProcessSetup.Spare000 | REAL | | 0.000000e+00 | |
| 340.0 | ProcessSetup.Spare040 | REAL | | 0.000000e+00 | |
| 344.0 | ProcessSetup._KWaterLoss | REAL | 1.000000e-03 | 1.000000e-03 | Friction Loss Constant in Serpentine |
| 348.0 | ProcessSetup._KSyrupLoss | REAL | 7.800000e-03 | 7.800000e-03 | Friction Loss Constant in Syrup Pipe |
| 352.0 | ProcessSetup._KProdLoss | REAL | 1.390000e-02 | 1.390000e-02 | Pressure Loss Factor |
| 356.0 | ProcessSetup._KPPM303 | REAL | 5.700000e+00 | 5.700000e+00 | Frequency Overpressure Pump P3 Constant [Hz/mm] |
| 360.0 | ProcessSetup._BaialageRVM301OVMin | REAL | 2.000000e+00 | 2.000000e+00 | Baialage Minimum Flow (Nm3/h) |
| 364.0 | ProcessSetup._SyrupLinePressure | REAL | 2.200000e+00 | 2.200000e+00 | Syrup Line pressure at VEP2 valve |
| 368.0 | ProcessSetup._CIPRMM301OV | REAL | 1.000000e+01 | 1.000000e+01 | Water Valve Opening During CIP |
| 372.0 | ProcessSetup._CIPRMP302OV | REAL | 1.500000e+01 | 1.500000e+01 | Syrup Valve Opening During CIP |
| 376.0 | ProcessSetup._CIPTM301MinLevel | REAL | 3.500000e+01 | 3.500000e+01 | Product Tank Minimum Level In CIP |
| 380.0 | ProcessSetup._CIPTM301MaxLevel | REAL | 5.500000e+01 | 5.500000e+01 | Product Tank Maximum Level In CIP |
| 384.0 | ProcessSetup._CIPPPM303Freq | REAL | 5.000000e+01 | 5.000000e+01 | CIP frequency Value [Hz] |
| 388.0 | ProcessSetup._CIPTP301MinLevel | REAL | 2.500000e+01 | 2.500000e+01 | Syrup Tank Minimum Level In CIP |
| 392.0 | ProcessSetup._CIPTP301MaxLevel | REAL | 4.500000e+01 | 4.500000e+01 | Syrup Tank Maximum Level In CIP |
| 396.0 | ProcessSetup._RinseRMM301OV | REAL | 1.000000e+01 | 1.000000e+01 | Water Valve Opening During Rinse |
| 400.0 | ProcessSetup._RinseRMP302OV | REAL | 1.400000e+01 | 1.400000e+01 | Syrup Valve Opening During Rinse |
| 404.0 | ProcessSetup._RinseTM301Press | REAL | 3.000000e-01 | 3.000000e-01 | Product Tank Pressure In Rinse |
| 408.0 | ProcessSetup._RinsePPM303Freq | REAL | 5.000000e+01 | 5.000000e+01 | Rinse frequency Value [Hz] |
| 412.0 | ProcessSetup._DrainTM301Press | REAL | 1.000000e+00 | 1.000000e+00 | Buffer Tank Draining Pressure |
| 416.0 | ProcessSetup._KRecBlendError | REAL | 2.000000e+00 | 2.000000e+00 | Blend Error Recovery CONSTANT |
| 420.0 | ProcessSetup._KRecCarboCO2Error | REAL | 2.000000e+00 | 2.000000e+00 | Carbonation Error Recovery Constant |
| 424.0 | ProcessSetup._MaxBlendError | REAL | 1.000000e+02 | 1.000000e+02 | Blend Error Maximum Value |
| 428.0 | ProcessSetup._MaxCarboCO2Error | REAL | 5.000000e+02 | 5.000000e+02 | Carbonation Error Maximum Value |
| 432.0 | ProcessSetup._StartUpBrixExtraWater | REAL | 4.700000e+01 | 4.700000e+01 | |
| 436.0 | ProcessSetup._StartUpCO2ExtraWater | REAL | 8.000000e+00 | 8.000000e+00 | |
| 440.0 | ProcessSetup._StartUpPPM303Freq | REAL | 2.000000e+01 | 2.000000e+01 | Start Up frequency Value [Hz] |
| 444.0 | ProcessSetup._SyrupRoomTank | INT | 1 | 1 | |
| 446.0 | ProcessSetup._SyrupRunOutLiters | REAL | 2.900000e+02 | 2.900000e+02 | |
| 450.0 | ProcessSetup._InjCO2Press_Offset | REAL | 5.000000e-01 | 5.000000e-01 | |
| 454.0 | ProcessSetup._InjCO2Press_MinFlow | REAL | 4.500000e+02 | 4.500000e+02 | |
| 458.0 | ProcessSetup._InjCO2Press_MaxFlow | REAL | 2.500000e+03 | 2.500000e+03 | |
| 462.0 | ProcessSetup._CarboCO2Pressure | REAL | 1.250000e+01 | 1.250000e+01 | CO2 Pressure Infeed Line |
| 466.0 | ProcessSetup._N2MinPressure | REAL | 1.000000e+00 | 1.000000e+00 | N2 Minimum Pressure Infeed Line |
| 470.0 | ProcessSetup._DiffSensor_Height | REAL | 3.950000e+02 | 3.950000e+02 | Sensor Height from Soil [mm] |
| 474.0 | ProcessSetup._DiffSensor_DeltaHeight | REAL | -2.500000e+01 | -2.500000e+01 | Sensor Plates Height Difference [mm] |
| 478.0 | ProcessSetup._DiffSensor_Offset | REAL | 3.618000e+01 | 3.618000e+01 | Sensor Offset Read with zero pressure (all valves open) in [mm] |
| 482.0 | ProcessSetup._FillingValveHeight | REAL | 1.400000e+03 | 1.400000e+03 | Filling Valve Height from soil [mm] |
| 486.0 | ProcessSetup._FillerDiameter | REAL | 2.520000e+03 | 2.520000e+03 | Filler Carousel Diameter [mm] |
| 490.0 | ProcessSetup._FillingValveNum | INT | 91 | 91 | Filling Valves Number |
| 492.0 | ProcessSetup._FillerProdPipeDN | REAL | 1.000000e+02 | 1.000000e+02 | |
| 496.0 | ProcessSetup._FillerProdPipeMass | REAL | 1.600000e+02 | 1.600000e+02 | |
| 500.0 | ProcessSetup._FillingTime | REAL | 3.200000e+00 | 3.200000e+00 | |
| 504.0 | ProcessSetup._TM301Height_0 | REAL | 1.050000e+03 | 1.050000e+03 | Level at 0% Tank Level Height in mm |
| 508.0 | ProcessSetup._TM301LevelPerc_2 | REAL | 4.600000e+01 | 4.600000e+01 | Second level percentage |
| 512.0 | ProcessSetup._TM301Height_2 | REAL | 1.625000e+03 | 1.625000e+03 | Second level Height in mm |
| 516.0 | ProcessSetup._RVN304Factor | REAL | 1.000000e+00 | 1.000000e+00 | DeareationFlow/WaterFlow |
| 520.0 | ProcessSetup._DrainTM301Flushing | REAL | 1.300000e+00 | 1.300000e+00 | |
| 524.0 | ProcessSetup._FirstProdExtraBrix | REAL | 5.000000e-02 | 5.000000e-02 | |
| 528.0 | ProcessSetup._FirstProdDietExtraSyr | REAL | 1.400000e-03 | 1.400000e-03 | |
| 532.0 | ProcessSetup._EndProdLastSyrlt | REAL | | 0.000000e+00 | End Production Last syrup liters |
| 536.0 | ProcessSetup._TM301DrainSt0Time | WORD | W#16#A | W#16#A | sec |
| 538.0 | ProcessSetup._TM301DrainSt1Time | WORD | W#16#50 | W#16#50 | sec |
| 540.0 | ProcessSetup._ProdPipeRunOutSt0Time | WORD | W#16#1 | W#16#1 | sec |
| 542.0 | ProcessSetup._RMM301ProdPipeRunOu | REAL | 3.000000e+01 | 3.000000e+01 | |
| 546.0 | ProcessSetup._RMP302ProdPipeRunOu | REAL | 4.000000e+01 | 4.000000e+01 | |
| 550.0 | ProcessSetup._ProdPipeRunOutAmount | REAL | 3.000000e+01 | 3.000000e+01 | |
| 554.0 | ProcessSetup._TM301RunOutChiller | REAL | 5.000000e+00 | 5.000000e+00 | |
| 558.0 | ProcessSetup._MinSpeedNominalProd | REAL | 4.000000e-01 | 4.000000e-01 | Min Speed for Nominal Production |
| 562.0 | ProcessSetup._MinSpeedSlowProd | REAL | 3.000000e-01 | 3.000000e-01 | Min Speed for Very Low Production |
| 566.0 | ProcessSetup._FastChgOvrTM301DrnPrss | REAL | 9.000000e-01 | 9.000000e-01 | Fast Change Over Product Tank Draining Pressure in Blendfill |
| 570.0 | ProcessSetup._CIPTN301MinLevel | REAL | 3.500000e+01 | 3.500000e+01 | Deaireator Tank Minimum Level In CIP |
| 574.0 | ProcessSetup._CIPTN301MaxLevel | REAL | 6.000000e+01 | 6.000000e+01 | Deaireator Tank Maximum Level In CIP |
| 578.0 | ProcessSetup._ProdPPN304Freq | REAL | 5.000000e+01 | 5.000000e+01 | |
| 582.0 | ProcessSetup._GAS2InjectionPress | REAL | 4.000000e+00 | 4.000000e+00 | |
| 586.0 | ProcessSetup._BaialageRVM301OVMax | REAL | 2.000000e+01 | 2.000000e+01 | Baialage Production Flow Multiplier |
| 590.0 | ProcessSetup._RinsePPN301Freq | REAL | 5.000000e+00 | 5.000000e+00 | |
| 594.0 | ProcessSetup._CIPPPN301Freq | REAL | 5.000000e+00 | 5.000000e+00 | |
| 598.0 | ProcessSetup._RinsePPP302Freq | REAL | 5.000000e+00 | 5.000000e+00 | |
| 602.0 | ProcessSetup._CIPPPP302Freq | REAL | 5.000000e+00 | 5.000000e+00 | |
| 606.0 | ProcessSetup._PercSyrupBrixSyrStarUp | REAL | 2.500000e+01 | 2.500000e+01 | |
| 610.0 | ProcessSetup._RefTempCoolingCTRL | REAL | | 0.000000e+00 | |
| 614.0 | ProcessSetup._H2OSerpPrimingVolume | REAL | 1.500000e+02 | 1.500000e+02 | Water Serpentine Volume + Water Chiller Volume |
| 618.0 | ProcessSetup._AVN301_Nozzle_Kv | REAL | 1.650000e+02 | 1.650000e+02 | AVN301 Nozzle Kv |
| 622.0 | ProcessSetup._AVN302_Nozzle_Kv | REAL | 2.600000e+02 | 2.600000e+02 | AVN302 Nozzle Kv |
| 626.0 | ProcessSetup._AVN303_Nozzle_Kv | REAL | 1.650000e+02 | 1.650000e+02 | AVN303 Nozzle Kv |
| 630.0 | ProcessSetup._DeoxSpryball_Kv | REAL | 6.700000e+01 | 6.700000e+01 | Deox Spryball Kv |
| 634.0 | ProcessSetup._PremixedLineDrainTime | INT | 300 | 300 | Premixed Product Line Drain Time |
| 636.0 | ProcessSetup._PPN301_H_MaxFlow | REAL | 9.000000e+01 | 9.000000e+01 | PPN301 Pump Head with Max Flow [m] |
| 640.0 | ProcessSetup._PPN301_H_MinFlow | REAL | 8.700000e+01 | 8.700000e+01 | PPN301 Pump Head with Min Flow [m] |
| 644.0 | ProcessSetup._PPN301_MaxFlow | REAL | 5.070000e+02 | 5.070000e+02 | PPN301 Max Flow [l/min] |
| 648.0 | ProcessSetup._PPN301_MinFlow | REAL | 2.110000e+02 | 2.110000e+02 | PPN301 Min Flow [l/min] |
| 652.0 | ProcessSetup._PPP302_H_MaxFlow | REAL | 8.600000e+01 | 8.600000e+01 | PPP302 Pump Head with Max Flow [m] |
| 656.0 | ProcessSetup._PPP302_H_MinFlow | REAL | 8.500000e+01 | 8.500000e+01 | PPP302 Pump Head with Min Flow [m] |
| 660.0 | ProcessSetup._PPP302_MaxFlow | REAL | 1.150000e+02 | 1.150000e+02 | PPP302 Max Flow [l/min] |
| 664.0 | ProcessSetup._PPP302_MinFlow | REAL | 3.200000e+01 | 3.200000e+01 | PPP302 Min Flow [l/min] |
| 668.0 | ProcessSetup._RinsePPM306Freq | REAL | 5.000000e+00 | 5.000000e+00 | |
| 672.0 | ProcessSetup._CIPPPM306Freq | REAL | 5.000000e+00 | 5.000000e+00 | |
| 676.0 | ProcessSetup._PPM307_H_MaxFlow | REAL | | 0.000000e+00 | PPM307 Pump Head with Max Flow [m] |
| 680.0 | ProcessSetup._PPM307_H_MinFlow | REAL | | 0.000000e+00 | PPM307 Pump Head with Min Flow [m] |
| 684.0 | ProcessSetup._PPM307_MaxFlow | REAL | | 0.000000e+00 | PPM307 Max Flow [l/min] |
| 688.0 | ProcessSetup._PPM307_MinFlow | REAL | | 0.000000e+00 | PPM307 Min Flow [l/min] |
| 692.0 | ProcessSetup._Temp0_VacuumCtrl | REAL | 1.800000e+01 | 1.800000e+01 | PPN304 Target Temperature - OPTION PPN304 Sterling Type |
| 696.0 | ProcessSetup._Temp1_VacuumCtrl | REAL | 2.000000e+00 | 2.000000e+00 | PPN304 High Treshold Temperature Delta - OPTION PPN304 Sterling Type |
| 700.0 | ProcessSetup._Temp2_VacuumCtrl | REAL | 2.000000e+00 | 2.000000e+00 | PPN304 Low Treshold Temperature Delta - OPTION PPN304 Sterling Type |
| 704.0 | ProcessSetup._Temp3_VacuumCtrl | REAL | 5.000000e+01 | 5.000000e+01 | PPN304 Warning Temperature - OPTION PPN304 Sterling Type |
| 708.0 | ProcessSetup._Temp4_VacuumCtrl | REAL | 5.000000e+01 | 5.000000e+01 | PPN304 Alarm Temperature - OPTION PPN304 Sterling Type |
| 712.0 | ProcessSetup._T1_VacuumCtrl | DINT | L#1500 | L#1500 | PPN304 Time 1 [msec] - OPTION PPN304 Sterling Type |
| 716.0 | ProcessSetup._T2_VacuumCtrl | DINT | L#1500 | L#1500 | PPN304 Time 2 [msec] - OPTION PPN304 Sterling Type |
| 720.0 | ProcessSetup._T3_VacuumCtrl | DINT | L#1000 | L#1000 | PPN304 Time 3 [msec] - OPTION PPN304 Sterling Type |
| 724.0 | ProcessSetup._T4_VacuumCtrl | DINT | L#1000 | L#1000 | PPN304 Time 4 [msec] - OPTION PPN304 Sterling Type |
| 728.0 | ProcessSetup._ICS_VolDosWorkTimePAA | INT | 30 | 30 | ICS - DS - Dosing Working Time [sec] |
| 730.0 | ProcessSetup._ICS_VolPauseTimePAA | INT | 30 | 30 | ICS - DS - Dosing Pause Time [sec] |
| 732.0 | ProcessSetup._ICS_PAAPulseWeight | INT | 10 | 10 | ICS - DS - PAA Pulse Weight [(L/Pulse)/100] |
| 734.0 | ProcessSetup._ICS_CausticPulseWeight | INT | 10 | 10 | ICS - DS - Caustic Pulse Weight [(L/Pulse)/100] |
| 736.0 | ProcessSetup._ICS_AcidPulseWeight | INT | 10 | 10 | ICS - DS - Acid Pulse Weight [(L/Pulse)/100] |
| 738.0 | ProcessSetup._ICS_VolumeRestOfLine | REAL | 3.500000e+02 | 3.500000e+02 | ICS - DS - Volume of the Rest of the Line (Filler + Piping) [L] |
| 742.0 | ProcessSetup._ICS_VolDosWorkTimeCaus | INT | 30 | 30 | ICS - DS - Dosing Working Time [sec] |
| 744.0 | ProcessSetup._ICS_VolDosPauseTimeCaus | INT | 30 | 30 | ICS - DS - Dosing Pause Time [sec] |
| 746.0 | ProcessSetup._ICS_VolDosWorkTimeAcid | INT | 30 | 30 | ICS - DS - Dosing Working Time [sec] |
| 748.0 | ProcessSetup._ICS_VolDosPauseTimeAcid | INT | 30 | 30 | ICS - DS - Dosing Pause Time [sec] |
| 750.0 | ProcessSetup._ICS_ConcDosWorkTimeCaus | INT | 30 | 30 | ICS - DS - Dosing Working Time [sec] |
| 752.0 | ProcessSetup._ICS_ConcDosPausTimeCaus | INT | 30 | 30 | ICS - DS - Dosing Pause Time [sec] |
| 754.0 | ProcessSetup._ICS_ConcDosWorkTimeAcid | INT | 30 | 30 | ICS - DS - Dosing Working Time [sec] |
| 756.0 | ProcessSetup._ICS_ConcDosPausTimeAcid | INT | 30 | 30 | ICS - DS - Dosing Pause Time [sec] |
| 758.0 | ProcessSetup._RinsePPM307Freq | REAL | 3.000000e+01 | 3.000000e+01 | |
| 762.0 | ProcessSetup._CIPPPM307Freq | REAL | 3.000000e+01 | 3.000000e+01 | |
| 766.0 | ProcessSetup._CIP2StepTN301Lvl | REAL | | 0.000000e+00 | Local CIP - 2 Step loading TN301 Level |
| 770.0 | ProcessSetup._CIP2StepTM301Lvl | REAL | | 0.000000e+00 | Local CIP - 2 Step loading TM301 Level |
| 774.0 | ProcessSetup._CIP2StepTP301Lvl | REAL | | 0.000000e+00 | Local CIP - 2 Step loading TP301 Level |
| 778.0 | ProcessSetup._PumpNominalFreq | REAL | 5.000000e+01 | 5.000000e+01 | 50.0 Hz or 60.0 Hz |
| 782.0 | _SwitchOff_DensityOK | BOOL | | FALSE | |

View File

@ -0,0 +1,4 @@
{
"type": "object",
"properties": {}
}

View File

@ -0,0 +1,4 @@
{
"type": "object",
"properties": {}
}

View File

@ -0,0 +1,28 @@
--- Log de Ejecución: x1.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-16 15:41:29
Fin: 2025-05-16 15:41:29
Duración: 0:00:00.179799
Estado: SUCCESS (Código de Salida: 0)
--- SALIDA ESTÁNDAR (STDOUT) ---
PLC Data Block Adapter - Advanced UDT Handling (Restored Auto File Find)
========================================================================
Using working directory: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001
Selected source file: db1001_data.db
Selected target file: db1001_format.db
Processing:
Source: db1001_data.db
Target: db1001_format.db
Output: db1001_format_updated.db
Successfully transferred 90 initial values and 279 current values.
Output file created: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_format_updated.db
SUCCESS: Script finished. Output: 'db1001_format_updated.db'
--- ERRORES (STDERR) ---
Ninguno
--- FIN DEL LOG ---

View File

@ -0,0 +1,37 @@
--- Log de Ejecución: x2.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-16 17:28:48
Fin: 2025-05-16 17:28:49
Duración: 0:00:01.729331
Estado: SUCCESS (Código de Salida: 0)
--- SALIDA ESTÁNDAR (STDOUT) ---
S7 Data Block Comparator to Excel (Multi-Sheet)
==============================================
Info: `find_working_directory_from_x1` is using the current directory.
Using working directory: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001
Identified files for comparison:
Data file: db1001_data.db
Format file: db1001_format.db
Updated file: db1001_format_updated.db
Processing _data file: db1001_data.db
Found 251 declaration vars, 280 initialization vars in _data file.
Processing _format file: db1001_format.db
Found 201 declaration vars, 279 initialization vars in _format file.
Processing _updated file: db1001_format_updated.db
Found 201 declaration vars, 279 initialization vars in _updated file.
Comparing 251 positional declaration entries (STRUCT section)...
Comparing 280 positional initialization entries (BEGIN block)...
Written 'Declarations (Initial Values)' sheet with 251 rows.
Written 'Initializations (Current Values)' sheet with 280 rows.
Successfully generated Excel comparison: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\S7_DB_Comparison_MultiSheet.xlsx
--- ERRORES (STDERR) ---
C:\Users\migue\miniconda3\envs\tia_scripting\Lib\site-packages\openpyxl\workbook\child.py:99: UserWarning: Title is more than 31 characters. Some applications may not be able to read the file
warnings.warn("Title is more than 31 characters. Some applications may not be able to read the file")
--- FIN DEL LOG ---

View File

@ -0,0 +1,51 @@
--- Log de Ejecución: x3.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-16 20:15:59
Fin: 2025-05-16 20:16:00
Duración: 0:00:00.897567
Estado: ERROR (Código de Salida: 1)
--- SALIDA ESTÁNDAR (STDOUT) ---
--- ERRORES (STDERR) ---
2025-05-16 20:16:00,228 - db_mapper - INFO - Iniciando mapeo de DBs por dirección absoluta
2025-05-16 20:16:00,309 - db_mapper - INFO - Directorio de trabajo: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001
2025-05-16 20:16:00,310 - db_mapper - INFO - Encontrados 3 archivos para procesar
2025-05-16 20:16:00,310 - db_mapper - INFO - Procesando: db1001_data.db
2025-05-16 20:16:00,310 - db_mapper - INFO - Procesando archivo: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_data.db
2025-05-16 20:16:00,310 - db_mapper - ERROR - Error procesando archivo C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_data.db: module 'DB_Parser' has no attribute 'parse_db_definition'
Traceback (most recent call last):
File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\S7_DB_Utils\x3.py", line 76, in process_db_file
db_node, db_number, db_name, family, version = DB_Parser.parse_db_definition(db_content, udt_definitions)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: module 'DB_Parser' has no attribute 'parse_db_definition'
2025-05-16 20:16:00,312 - db_mapper - INFO - Procesando: db1001_format.db
2025-05-16 20:16:00,312 - db_mapper - INFO - Procesando archivo: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_format.db
2025-05-16 20:16:00,313 - db_mapper - ERROR - Error procesando archivo C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_format.db: module 'DB_Parser' has no attribute 'parse_udt_definition'
Traceback (most recent call last):
File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\S7_DB_Utils\x3.py", line 64, in process_db_file
udt_name, udt_node = DB_Parser.parse_udt_definition(udt_content)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: module 'DB_Parser' has no attribute 'parse_udt_definition'
2025-05-16 20:16:00,316 - db_mapper - INFO - Procesando: db1001_format_updated.db
2025-05-16 20:16:00,316 - db_mapper - INFO - Procesando archivo: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_format_updated.db
2025-05-16 20:16:00,316 - db_mapper - ERROR - Error procesando archivo C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_format_updated.db: module 'DB_Parser' has no attribute 'parse_udt_definition'
Traceback (most recent call last):
File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\S7_DB_Utils\x3.py", line 64, in process_db_file
udt_name, udt_node = DB_Parser.parse_udt_definition(udt_content)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: module 'DB_Parser' has no attribute 'parse_udt_definition'
Traceback (most recent call last):
File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\S7_DB_Utils\x3.py", line 444, in <module>
main()
File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\S7_DB_Utils\x3.py", line 430, in main
processed_files, mapped_pairs = process_all_files_in_directory()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\S7_DB_Utils\x3.py", line 372, in process_all_files_in_directory
"timestamp": import_datetime().now().isoformat()
^^^^^^^^^^^^^^^^^^^^^
AttributeError: module 'datetime' has no attribute 'now'
--- FIN DEL LOG ---

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,77 @@
### How to work with config setup Example
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
if __name__ == "__main__":
"""
Load configuration from script_config.json in the current script directory.
Returns:
Dict containing configurations with levels 1, 2, 3 and working_directory
Example usage in scripts:
from script_utils import load_configuration
configs = load_configuration()
level1_config = configs.get("level1", {})
level2_config = configs.get("level2", {})
level3_config = configs.get("level3", {})
working_dir = configs.get("working_directory", "")
""""
configs = load_configuration()
working_directory = configs.get("working_directory")
# Acceder a la configuración específica del grupo
group_config = configs.get("level2", {})
# Leer parámetros con valores por defecto (usando los defaults del esquema como guía)
# Parámetros necesarios para x4
cfg_scl_output_dirname = group_config.get("scl_output_dir", "scl_output")
cfg_xref_output_dirname = group_config.get("xref_output_dir", "xref_output")
cfg_xref_source_subdir = group_config.get("xref_source_subdir", "source")
### Directory structure for Tia Portal scripts
<working_directory>/
├── <Project_Name>_CAx_Export.aml
├── <PLC1_Name>/
│ ├── ProgramBlocks_XML/
│ │ └── ... (archivos XML de bloques)
│ ├── ProgramBlocks_SCL/
│ │ └── ... (archivos SCL de bloques)
│ ├── ProgramBlocks_CR/
│ │ └── ... (archivos XML de referencias cruzadas de bloques)
│ ├── PlcTags/
│ │ └── ... (archivos XML de tablas de tags)
│ ├── PlcTags_CR/
│ │ └── ... (archivos XML de referencias cruzadas de tablas de tags)
│ ├── PlcDataTypes_CR/
│ │ └── ... (archivos XML de referencias cruzadas de UDTs)
│ ├── SystemBlocks_CR/
│ │ └── ...
│ └── SoftwareUnits_CR/
│ └── ...
│ └── Documentation/
│ └── Source
│ └── ... (archivos md de bloques de programa)
│ └── JSON
│ └── ... (archivos JSON temporales)
│ └── xref_calls_tree.md
│ └── xref_db_usage_summary.md
│ └── xref_plc_tags_summary.md
│ └── full_project_representation.md
│ └── <Project_Name>_CAx_Export_Hardware_Tree.md
├── <PLC2_Name>/
│ ├── ProgramBlocks_XML/
│ │ └── ...
│ └── ...
└── ...

View File

@ -0,0 +1,521 @@
TYPE "Recipe_Prod"
FAMILY : DataType;
VERSION : 0.1;
STRUCT
_Name : STRING[32] := ' ';
_EnProdTemp : BOOL;
_SyrFlushing : BOOL; // Ex_EnDeaireation --> DELETED - AVP320 VALVE OPEN
_GAS2_Injection : BOOL; // 0 = GAS2 not present; 1 = GAS2 present
_Eq_Pression_Selected : BOOL;
_DeoxStripEn : BOOL; // ******Deairation with Strip Enable
_DeoxVacuumEn : BOOL; // ******Deairation with Vacuum
_DeoxPreMixed : BOOL; // ******Deairation of Premixed Product
_EnBlowOffProdPipeCO2Fil : BOOL;
_WaterSelection : BYTE;
_FillerNextRecipeNum : BYTE;
_BottleShape : BYTE;
_Type : INT := 1; // 1= DIET; 2= REGULAR; 3= RATIO; 4= WATER
_ProdMeterRecipeNum : INT;
_SyrupBrix : REAL := 5.000000e+01;
_SyrupDensity : REAL := 1.255800e+00;
_SyrupFactor : REAL := 1.000000e+00;
_ProductBrix : REAL := 1.045000e+01;
_ProductionRate : REAL := 9.000000e+02;
_Ratio : REAL := 2.000000e+01;
_ProdBrixOffset : REAL;
_CO2Vols : REAL;
_CO2Fact : REAL := 1.000000e+00;
_ProdTankPress : REAL := 1.000000e+00;
_SP_ProdTemp : REAL := 1.000000e+01;
_PrdTankMinLevel : REAL := 1.000000e+01;
_WaterValveSave : REAL;
_SyrupValveSave : REAL;
_CarboCO2ValveSave : REAL;
_ProdMeterHighBrix : REAL;
_ProdMeterLowBrix : REAL;
_ProdMeterHighCO2 : REAL;
_ProdMeterLowCO2 : REAL;
_ProdMeter_ZeroCO2 : REAL;
_ProdMeter_ZeroBrix : REAL;
_ProdHighCond : REAL;
_ProdLowCond : REAL;
_BottleSize : REAL;
_FillingValveHead_SP : REAL;
_SyrMeter_ZeroBrix : REAL;
_FirstProdExtraCO2Fact : REAL := 9.700000e-01;
_Gas2Vols : REAL;
_Gas2Fact : REAL := 1.000000e+00;
_SyrupPumpPressure : REAL; // ******Syrup Pump Pressure SP
_WaterPumpPressure : REAL; // ******Water Pump Pressure SP
_CO2_Air_N2_PressSelect : INT; // 1=CO2; 2=CO2+SterilAir; 3=CO2+N2 - Pressure Tank Selection
_KFactRVM304BlowOff : REAL;
_ProdRecircPumpFreq : REAL;
_ProdBoosterPumpPress : REAL;
_ProdSendPumpFreq : REAL; // ******Product Sending Pump Frequency SP
END_STRUCT;
END_TYPE;
DATA_BLOCK "HMI_Blender_Parameters"
FAMILY : Resource;
VERSION : 0.0;
STRUCT
Processor_Options : STRUCT;
Blender_OPT : STRUCT;
_ModelNum : INT := 6;
_CO2_Offset : REAL := 4.500000e-01;
_MaxSyrDeltaBrix : REAL := 8.000000e-01;
_BrixMeter : BOOL := TRUE;
Spare101 : BOOL;
_TrackH2OEnable : BOOL;
_PAmPDSType : BOOL; // 0)Cobrix 2000 1)Carbo 2000
_HistoricalTrends : BOOL := TRUE; // 0)Not Present 1)Present
_PowerMeter : BOOL; // 0)Not Present 1)Present
_Report : BOOL := TRUE; // 0)Not Present 1)Present
_Balaiage : BOOL;
_Valves_FullFeedback : BOOL := TRUE; // Valves control Full feedback
_Valves_SingleFeedback : BOOL; // Valves control Single feedback
_PumpsSafetySwitches : BOOL; // Pumps with Safety Switches
_SurgeProtectionAct : BOOL;
_DBC_Type : BOOL; // 0) Deox,Carbo,Blend 1)Deox,Blend,Carbo
_CO2InletMeter : BOOL := TRUE; // 0)Not Present 1)Present
_ProductO2Meter : BOOL; // 0)Not Present 1)Present
_CopressedAirInletMeter : BOOL; // 0)Not Present 1)Present
_MeterType : INT := 6; // 1)Maselli 2)AntoonPaar 3)4-20mA 4)UC05 UR22 5)mPDSPA 6)MR02
_MeterReceiveOnly : BOOL;
_SyrBrixMeter : BOOL;
_Flooding_Start_Up : BOOL; // 0)Not Selected 1)Selected
_FastChangeOverEnabled : BOOL := TRUE;
_WaterInletMeter : BOOL; // 0)Not Present 1)Present
_BlendFillSystem : BOOL := TRUE;
_TrackFillerSpeed : BOOL := TRUE;
_SignalExchange : INT := 1; // FILLER - 0= Hardwire; 1= Ethernet
_CoolerPresent : BOOL := TRUE;
_CoolerControl : INT := 4; // 0)External 1)Water 2)Product 3)Water+Product-2 Ctrl 4)Water+Product-1 Ctrl
_CoolerType : INT; // 0)Glycol 1)Ammonia
_LocalCIP : BOOL;
_ICS_CustomerHotWater : BOOL; // 0)No Hot Water from Customer 1)Hot Water from Customer Available
_ICS_CustomerChemRecov : BOOL; // 0)No Customer's Chemicals Recovery 1)Customer's Chemicals Recovery Available
_CIPSignalExchange : BOOL; // CIP - 0= Hardwire; 1= Ethernet
_ICS_CustomerChemicals : BOOL; // 0)Chemicals from ICS 1)Chemicals from Customer
_CarboPresent : BOOL := TRUE;
_InverterSyrupPumpPPP302 : BOOL; // 0)Not Present 1)Present
_InverterWaterPumpPPN301 : BOOL; // 0)Not Present 1)Present
_DoubleDeair : BOOL := TRUE;
_DeairPreMixed : BOOL; // Deox Premixed Inlet
_Deaireation : BOOL := TRUE; // 0)SAG 1)SAE/SAF
_StillWaterByPass : BOOL;
_ManifoldSetting : BOOL := TRUE; // 0)Manual 1)Automatic
_InverterProdPumpPPM303 : BOOL;
_SidelCip : BOOL;
_EthernetCom_CpuPN_CP : BOOL := TRUE; // 0)Comunication with CP 1)Comunication with CPU PN
_2ndOutlet : INT; // 0)No 2nd Outlet 1)2nd Outlet No Standalone 2)2nd Outlet Standalone
_Promass : INT := 2;
_WaterPromass : BOOL := TRUE; // 0)Promag 1)Promass
_ProductConductimeter : BOOL;
_ICS_CustomerH2ORecov : BOOL; // 0)No Customer's H2O Recovery 1)Customer's H2O Recovery Available
Spare303 : BOOL;
_CO2_GAS2_Injection : BOOL; // 0)Only CO2 Injection 1)GAS2 Injection
_InverterVacuuPumpPPN304 : BOOL; // 0)Not Present 1)Present
_InverterBoostPumpPPM307 : BOOL; // 0)Not Present 1)Present
_RunOut_Water : BOOL := TRUE; // 0)Syrup Runout without Water 1)Syrup runout with Water pushing
_FlowMeterType : BOOL; // 0)Endrees Hauser -- 1)Micromotion
_SidelFiller : BOOL; // 0)Filler Simonazzi -- 1)Filler Sidel Filling
_Simulation : BOOL;
_ProductCoolingCTRL : BOOL; // 0)none 1) TTM307
_ChillerCTRL : BOOL; // Chiller Pressure Cross Control
_CO2_SterileFilter : BOOL := TRUE; // CO2 Inlet with Steril Filter
_InverterRecirPumpPPM306 : BOOL; // 0)Not Present 1)Present
_ProdPressReleaseRVM304 : BOOL; // 0)Not Present 1)Present
_VacuumPump : INT := 1; // 0)None 1)Sterling 2)Nash Elmo
_GAS2InjectionType : INT; // 0)None 1)N2 2)Steril Air
_InjectionPress_Ctrl : INT := 1; // 0)Manual 1)Norgren v1 2)Norgren v2
_ProdPressureType : INT; // 0)Only CO2 1)CO2+SterilAir 2)CO2+N2
_CIPHeatType : INT; // 0)Steam 1)Electric
_EHS_NrRes : INT := 6; // Number of Heat Resistances
END_STRUCT;
END_STRUCT;
Spare1 : ARRAY [1..9] OF INT;
_RVM301_DeadBand : REAL := 5.000000e-02;
_RVM301_Kp : REAL := 9.000000e+01;
Actual_Recipe_Parameters : "Recipe_Prod";
Spare2 : ARRAY [1..5] OF INT;
Next_Recipe_Name : STRING[32] := ' ';
Next_Recipe_Number : INT;
Spare3 : ARRAY [1..18] OF INT;
ProcessSetup : STRUCT;
Spare000 : REAL;
Spare040 : REAL;
_KWaterLoss : REAL := 1.000000e-03; // Friction Loss Constant in Serpentine
_KSyrupLoss : REAL := 7.800000e-03; // Friction Loss Constant in Syrup Pipe
_KProdLoss : REAL := 1.390000e-02; // Pressure Loss Factor
_KPPM303 : REAL := 5.700000e+00; // Frequency Overpressure Pump P3 Constant [Hz/mm]
_BaialageRVM301OVMin : REAL := 2.000000e+00; // Baialage Minimum Flow (Nm3/h)
_SyrupLinePressure : REAL := 2.200000e+00; // Syrup Line pressure at VEP2 valve
_CIPRMM301OV : REAL := 1.000000e+01; // Water Valve Opening During CIP
_CIPRMP302OV : REAL := 1.500000e+01; // Syrup Valve Opening During CIP
_CIPTM301MinLevel : REAL := 3.500000e+01; // Product Tank Minimum Level In CIP
_CIPTM301MaxLevel : REAL := 5.500000e+01; // Product Tank Maximum Level In CIP
_CIPPPM303Freq : REAL := 5.000000e+01; // CIP frequency Value [Hz]
_CIPTP301MinLevel : REAL := 2.500000e+01; // Syrup Tank Minimum Level In CIP
_CIPTP301MaxLevel : REAL := 4.500000e+01; // Syrup Tank Maximum Level In CIP
_RinseRMM301OV : REAL := 1.000000e+01; // Water Valve Opening During Rinse
_RinseRMP302OV : REAL := 1.400000e+01; // Syrup Valve Opening During Rinse
_RinseTM301Press : REAL := 3.000000e-01; // Product Tank Pressure In Rinse
_RinsePPM303Freq : REAL := 5.000000e+01; // Rinse frequency Value [Hz]
_DrainTM301Press : REAL := 1.000000e+00; // Buffer Tank Draining Pressure
_KRecBlendError : REAL := 2.000000e+00; // Blend Error Recovery CONSTANT
_KRecCarboCO2Error : REAL := 2.000000e+00; // Carbonation Error Recovery Constant
_MaxBlendError : REAL := 1.000000e+02; // Blend Error Maximum Value
_MaxCarboCO2Error : REAL := 5.000000e+02; // Carbonation Error Maximum Value
_StartUpBrixExtraWater : REAL := 4.700000e+01;
_StartUpCO2ExtraWater : REAL := 8.000000e+00;
_StartUpPPM303Freq : REAL := 2.000000e+01; // Start Up frequency Value [Hz]
_SyrupRoomTank : INT := 1;
_SyrupRunOutLiters : REAL := 2.900000e+02;
_InjCO2Press_Offset : REAL := 5.000000e-01;
_InjCO2Press_MinFlow : REAL := 4.500000e+02;
_InjCO2Press_MaxFlow : REAL := 2.500000e+03;
_CarboCO2Pressure : REAL := 1.250000e+01; // CO2 Pressure Infeed Line
_N2MinPressure : REAL := 1.000000e+00; // N2 Minimum Pressure Infeed Line
_DiffSensor_Height : REAL := 3.950000e+02; // Sensor Height from Soil [mm]
_DiffSensor_DeltaHeight : REAL := -2.500000e+01; // Sensor Plates Height Difference [mm]
_DiffSensor_Offset : REAL := 3.618000e+01; // Sensor Offset Read with zero pressure (all valves open) in [mm]
_FillingValveHeight : REAL := 1.400000e+03; // Filling Valve Height from soil [mm]
_FillerDiameter : REAL := 2.520000e+03; // Filler Carousel Diameter [mm]
_FillingValveNum : INT := 91; // Filling Valves Number
_FillerProdPipeDN : REAL := 1.000000e+02;
_FillerProdPipeMass : REAL := 1.600000e+02;
_FillingTime : REAL := 3.200000e+00;
_TM301Height_0 : REAL := 1.050000e+03; // Level at 0% Tank Level Height in mm
_TM301LevelPerc_2 : REAL := 4.600000e+01; // Second level percentage
_TM301Height_2 : REAL := 1.625000e+03; // Second level Height in mm
_RVN304Factor : REAL := 1.000000e+00; // DeareationFlow/WaterFlow
_DrainTM301Flushing : REAL := 1.300000e+00;
_FirstProdExtraBrix : REAL := 5.000000e-02;
_FirstProdDietExtraSyr : REAL := 1.400000e-03;
_EndProdLastSyrlt : REAL; // End Production Last syrup liters
_TM301DrainSt0Time : WORD := W#16#A; // sec
_TM301DrainSt1Time : WORD := W#16#50; // sec
_ProdPipeRunOutSt0Time : WORD := W#16#1; // sec
_RMM301ProdPipeRunOu : REAL := 3.000000e+01;
_RMP302ProdPipeRunOu : REAL := 4.000000e+01;
_ProdPipeRunOutAmount : REAL := 3.000000e+01;
_TM301RunOutChiller : REAL := 5.000000e+00;
_MinSpeedNominalProd : REAL := 4.000000e-01; // Min Speed for Nominal Production
_MinSpeedSlowProd : REAL := 3.000000e-01; // Min Speed for Very Low Production
_FastChgOvrTM301DrnPrss : REAL := 9.000000e-01; // Fast Change Over Product Tank Draining Pressure in Blendfill
_CIPTN301MinLevel : REAL := 3.500000e+01; // Deaireator Tank Minimum Level In CIP
_CIPTN301MaxLevel : REAL := 6.000000e+01; // Deaireator Tank Maximum Level In CIP
_ProdPPN304Freq : REAL := 5.000000e+01;
_GAS2InjectionPress : REAL := 4.000000e+00;
_BaialageRVM301OVMax : REAL := 2.000000e+01; // Baialage Production Flow Multiplier
_RinsePPN301Freq : REAL := 5.000000e+00;
_CIPPPN301Freq : REAL := 5.000000e+00;
_RinsePPP302Freq : REAL := 5.000000e+00;
_CIPPPP302Freq : REAL := 5.000000e+00;
_PercSyrupBrixSyrStarUp : REAL := 2.500000e+01;
_RefTempCoolingCTRL : REAL;
_H2OSerpPrimingVolume : REAL := 1.500000e+02; // Water Serpentine Volume + Water Chiller Volume
_AVN301_Nozzle_Kv : REAL := 1.650000e+02; // AVN301 Nozzle Kv
_AVN302_Nozzle_Kv : REAL := 2.600000e+02; // AVN302 Nozzle Kv
_AVN303_Nozzle_Kv : REAL := 1.650000e+02; // AVN303 Nozzle Kv
_DeoxSpryball_Kv : REAL := 6.700000e+01; // Deox Spryball Kv
_PremixedLineDrainTime : INT := 300; // Premixed Product Line Drain Time
_PPN301_H_MaxFlow : REAL := 9.000000e+01; // PPN301 Pump Head with Max Flow [m]
_PPN301_H_MinFlow : REAL := 8.700000e+01; // PPN301 Pump Head with Min Flow [m]
_PPN301_MaxFlow : REAL := 5.070000e+02; // PPN301 Max Flow [l/min]
_PPN301_MinFlow : REAL := 2.110000e+02; // PPN301 Min Flow [l/min]
_PPP302_H_MaxFlow : REAL := 8.600000e+01; // PPP302 Pump Head with Max Flow [m]
_PPP302_H_MinFlow : REAL := 8.500000e+01; // PPP302 Pump Head with Min Flow [m]
_PPP302_MaxFlow : REAL := 1.150000e+02; // PPP302 Max Flow [l/min]
_PPP302_MinFlow : REAL := 3.200000e+01; // PPP302 Min Flow [l/min]
_RinsePPM306Freq : REAL := 5.000000e+00;
_CIPPPM306Freq : REAL := 5.000000e+00;
_PPM307_H_MaxFlow : REAL; // PPM307 Pump Head with Max Flow [m]
_PPM307_H_MinFlow : REAL; // PPM307 Pump Head with Min Flow [m]
_PPM307_MaxFlow : REAL; // PPM307 Max Flow [l/min]
_PPM307_MinFlow : REAL; // PPM307 Min Flow [l/min]
_Temp0_VacuumCtrl : REAL := 1.800000e+01; // PPN304 Target Temperature - OPTION PPN304 Sterling Type
_Temp1_VacuumCtrl : REAL := 2.000000e+00; // PPN304 High Treshold Temperature Delta - OPTION PPN304 Sterling Type
_Temp2_VacuumCtrl : REAL := 2.000000e+00; // PPN304 Low Treshold Temperature Delta - OPTION PPN304 Sterling Type
_Temp3_VacuumCtrl : REAL := 5.000000e+01; // PPN304 Warning Temperature - OPTION PPN304 Sterling Type
_Temp4_VacuumCtrl : REAL := 5.000000e+01; // PPN304 Alarm Temperature - OPTION PPN304 Sterling Type
_T1_VacuumCtrl : DINT := L#1500; // PPN304 Time 1 [msec] - OPTION PPN304 Sterling Type
_T2_VacuumCtrl : DINT := L#1500; // PPN304 Time 2 [msec] - OPTION PPN304 Sterling Type
_T3_VacuumCtrl : DINT := L#1000; // PPN304 Time 3 [msec] - OPTION PPN304 Sterling Type
_T4_VacuumCtrl : DINT := L#1000; // PPN304 Time 4 [msec] - OPTION PPN304 Sterling Type
_ICS_VolDosWorkTimePAA : INT := 30; // ICS - DS - Dosing Working Time [sec]
_ICS_VolPauseTimePAA : INT := 30; // ICS - DS - Dosing Pause Time [sec]
_ICS_PAAPulseWeight : INT := 10; // ICS - DS - PAA Pulse Weight [(L/Pulse)/100]
_ICS_CausticPulseWeight : INT := 10; // ICS - DS - Caustic Pulse Weight [(L/Pulse)/100]
_ICS_AcidPulseWeight : INT := 10; // ICS - DS - Acid Pulse Weight [(L/Pulse)/100]
_ICS_VolumeRestOfLine : REAL := 3.500000e+02; // ICS - DS - Volume of the Rest of the Line (Filler + Piping) [L]
_ICS_VolDosWorkTimeCaus : INT := 30; // ICS - DS - Dosing Working Time [sec]
_ICS_VolDosPauseTimeCaus : INT := 30; // ICS - DS - Dosing Pause Time [sec]
_ICS_VolDosWorkTimeAcid : INT := 30; // ICS - DS - Dosing Working Time [sec]
_ICS_VolDosPauseTimeAcid : INT := 30; // ICS - DS - Dosing Pause Time [sec]
_ICS_ConcDosWorkTimeCaus : INT := 30; // ICS - DS - Dosing Working Time [sec]
_ICS_ConcDosPausTimeCaus : INT := 30; // ICS - DS - Dosing Pause Time [sec]
_ICS_ConcDosWorkTimeAcid : INT := 30; // ICS - DS - Dosing Working Time [sec]
_ICS_ConcDosPausTimeAcid : INT := 30; // ICS - DS - Dosing Pause Time [sec]
_RinsePPM307Freq : REAL := 3.000000e+01;
_CIPPPM307Freq : REAL := 3.000000e+01;
_CIP2StepTN301Lvl : REAL; // Local CIP - 2 Step loading TN301 Level
_CIP2StepTM301Lvl : REAL; // Local CIP - 2 Step loading TM301 Level
_CIP2StepTP301Lvl : REAL; // Local CIP - 2 Step loading TP301 Level
_PumpNominalFreq : REAL := 5.000000e+01; // 50.0 Hz or 60.0 Hz
END_STRUCT;
_SwitchOff_DensityOK : BOOL;
END_STRUCT;
BEGIN
Processor_Options.Blender_OPT._ModelNum := 6;
Processor_Options.Blender_OPT._CO2_Offset := 4.500000e-01;
Processor_Options.Blender_OPT._MaxSyrDeltaBrix := 8.000000e-01;
Processor_Options.Blender_OPT._BrixMeter := TRUE;
Processor_Options.Blender_OPT.Spare101 := FALSE;
Processor_Options.Blender_OPT._TrackH2OEnable := FALSE;
Processor_Options.Blender_OPT._PAmPDSType := FALSE;
Processor_Options.Blender_OPT._HistoricalTrends := TRUE;
Processor_Options.Blender_OPT._PowerMeter := FALSE;
Processor_Options.Blender_OPT._Report := TRUE;
Processor_Options.Blender_OPT._Balaiage := FALSE;
Processor_Options.Blender_OPT._Valves_FullFeedback := TRUE;
Processor_Options.Blender_OPT._Valves_SingleFeedback := FALSE;
Processor_Options.Blender_OPT._PumpsSafetySwitches := FALSE;
Processor_Options.Blender_OPT._SurgeProtectionAct := FALSE;
Processor_Options.Blender_OPT._DBC_Type := FALSE;
Processor_Options.Blender_OPT._CO2InletMeter := TRUE;
Processor_Options.Blender_OPT._ProductO2Meter := FALSE;
Processor_Options.Blender_OPT._CopressedAirInletMeter := FALSE;
Processor_Options.Blender_OPT._MeterType := 6;
Processor_Options.Blender_OPT._MeterReceiveOnly := FALSE;
Processor_Options.Blender_OPT._SyrBrixMeter := FALSE;
Processor_Options.Blender_OPT._Flooding_Start_Up := FALSE;
Processor_Options.Blender_OPT._FastChangeOverEnabled := TRUE;
Processor_Options.Blender_OPT._WaterInletMeter := FALSE;
Processor_Options.Blender_OPT._BlendFillSystem := TRUE;
Processor_Options.Blender_OPT._TrackFillerSpeed := TRUE;
Processor_Options.Blender_OPT._SignalExchange := 1;
Processor_Options.Blender_OPT._CoolerPresent := TRUE;
Processor_Options.Blender_OPT._CoolerControl := 4;
Processor_Options.Blender_OPT._CoolerType := 0;
Processor_Options.Blender_OPT._LocalCIP := FALSE;
Processor_Options.Blender_OPT._ICS_CustomerHotWater := FALSE;
Processor_Options.Blender_OPT._ICS_CustomerChemRecov := FALSE;
Processor_Options.Blender_OPT._CIPSignalExchange := FALSE;
Processor_Options.Blender_OPT._ICS_CustomerChemicals := FALSE;
Processor_Options.Blender_OPT._CarboPresent := TRUE;
Processor_Options.Blender_OPT._InverterSyrupPumpPPP302 := FALSE;
Processor_Options.Blender_OPT._InverterWaterPumpPPN301 := FALSE;
Processor_Options.Blender_OPT._DoubleDeair := TRUE;
Processor_Options.Blender_OPT._DeairPreMixed := FALSE;
Processor_Options.Blender_OPT._Deaireation := TRUE;
Processor_Options.Blender_OPT._StillWaterByPass := FALSE;
Processor_Options.Blender_OPT._ManifoldSetting := TRUE;
Processor_Options.Blender_OPT._InverterProdPumpPPM303 := FALSE;
Processor_Options.Blender_OPT._SidelCip := FALSE;
Processor_Options.Blender_OPT._EthernetCom_CpuPN_CP := TRUE;
Processor_Options.Blender_OPT._2ndOutlet := 0;
Processor_Options.Blender_OPT._Promass := 2;
Processor_Options.Blender_OPT._WaterPromass := TRUE;
Processor_Options.Blender_OPT._ProductConductimeter := FALSE;
Processor_Options.Blender_OPT._ICS_CustomerH2ORecov := FALSE;
Processor_Options.Blender_OPT.Spare303 := FALSE;
Processor_Options.Blender_OPT._CO2_GAS2_Injection := FALSE;
Processor_Options.Blender_OPT._InverterVacuuPumpPPN304 := FALSE;
Processor_Options.Blender_OPT._InverterBoostPumpPPM307 := FALSE;
Processor_Options.Blender_OPT._RunOut_Water := TRUE;
Processor_Options.Blender_OPT._FlowMeterType := TRUE;
Processor_Options.Blender_OPT._SidelFiller := FALSE;
Processor_Options.Blender_OPT._Simulation := FALSE;
Processor_Options.Blender_OPT._ProductCoolingCTRL := FALSE;
Processor_Options.Blender_OPT._ChillerCTRL := FALSE;
Processor_Options.Blender_OPT._CO2_SterileFilter := TRUE;
Processor_Options.Blender_OPT._InverterRecirPumpPPM306 := FALSE;
Processor_Options.Blender_OPT._ProdPressReleaseRVM304 := FALSE;
Processor_Options.Blender_OPT._VacuumPump := 1;
Processor_Options.Blender_OPT._GAS2InjectionType := 0;
Processor_Options.Blender_OPT._InjectionPress_Ctrl := 1;
Processor_Options.Blender_OPT._ProdPressureType := 0;
Processor_Options.Blender_OPT._CIPHeatType := 0;
Processor_Options.Blender_OPT._EHS_NrRes := 6;
_RVM301_DeadBand := 5.000000e-02;
_RVM301_Kp := 9.000000e+01;
Actual_Recipe_Parameters._Name := '';
Actual_Recipe_Parameters._EnProdTemp := TRUE;
Actual_Recipe_Parameters._SyrFlushing := FALSE;
Actual_Recipe_Parameters._GAS2_Injection := FALSE;
Actual_Recipe_Parameters._Eq_Pression_Selected := FALSE;
Actual_Recipe_Parameters._DeoxStripEn := FALSE;
Actual_Recipe_Parameters._DeoxVacuumEn := TRUE;
Actual_Recipe_Parameters._DeoxPreMixed := FALSE;
Actual_Recipe_Parameters._EnBlowOffProdPipeCO2Fil := FALSE;
Actual_Recipe_Parameters._WaterSelection := B#16#0;
Actual_Recipe_Parameters._FillerNextRecipeNum := B#16#0;
Actual_Recipe_Parameters._BottleShape := B#16#0;
Actual_Recipe_Parameters._Type := 2;
Actual_Recipe_Parameters._ProdMeterRecipeNum := 1;
Actual_Recipe_Parameters._SyrupBrix := 4.625000e+01;
Actual_Recipe_Parameters._SyrupDensity := 1.206908e+00;
Actual_Recipe_Parameters._SyrupFactor := 1.000000e+00;
Actual_Recipe_Parameters._ProductBrix := 1.000000e+01;
Actual_Recipe_Parameters._ProductionRate := 3.800000e+02;
Actual_Recipe_Parameters._Ratio := 4.238896e+00;
Actual_Recipe_Parameters._ProdBrixOffset := 2.500000e-01;
Actual_Recipe_Parameters._CO2Vols := 2.550000e+00;
Actual_Recipe_Parameters._CO2Fact := 9.400000e-01;
Actual_Recipe_Parameters._ProdTankPress := 4.400000e+00;
Actual_Recipe_Parameters._SP_ProdTemp := 1.700000e+01;
Actual_Recipe_Parameters._PrdTankMinLevel := 3.500000e+01;
Actual_Recipe_Parameters._WaterValveSave := 0.000000e+00;
Actual_Recipe_Parameters._SyrupValveSave := 0.000000e+00;
Actual_Recipe_Parameters._CarboCO2ValveSave := 0.000000e+00;
Actual_Recipe_Parameters._ProdMeterHighBrix := 1.030000e+01;
Actual_Recipe_Parameters._ProdMeterLowBrix := 9.830000e+00;
Actual_Recipe_Parameters._ProdMeterHighCO2 := 2.900000e+00;
Actual_Recipe_Parameters._ProdMeterLowCO2 := 2.300000e+00;
Actual_Recipe_Parameters._ProdMeter_ZeroCO2 := 0.000000e+00;
Actual_Recipe_Parameters._ProdMeter_ZeroBrix := 0.000000e+00;
Actual_Recipe_Parameters._ProdHighCond := 0.000000e+00;
Actual_Recipe_Parameters._ProdLowCond := 0.000000e+00;
Actual_Recipe_Parameters._BottleSize := 0.000000e+00;
Actual_Recipe_Parameters._FillingValveHead_SP := 0.000000e+00;
Actual_Recipe_Parameters._SyrMeter_ZeroBrix := 0.000000e+00;
Actual_Recipe_Parameters._FirstProdExtraCO2Fact := 1.020000e+00;
Actual_Recipe_Parameters._Gas2Vols := 0.000000e+00;
Actual_Recipe_Parameters._Gas2Fact := 0.000000e+00;
Actual_Recipe_Parameters._SyrupPumpPressure := 0.000000e+00;
Actual_Recipe_Parameters._WaterPumpPressure := 0.000000e+00;
Actual_Recipe_Parameters._CO2_Air_N2_PressSelect := 0;
Actual_Recipe_Parameters._KFactRVM304BlowOff := 0.000000e+00;
Actual_Recipe_Parameters._ProdRecircPumpFreq := 0.000000e+00;
Actual_Recipe_Parameters._ProdBoosterPumpPress := 0.000000e+00;
Actual_Recipe_Parameters._ProdSendPumpFreq := 0.000000e+00;
Next_Recipe_Name := 'cambio 1$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00$00';
Next_Recipe_Number := 0;
ProcessSetup.Spare000 := 0.000000e+00;
ProcessSetup.Spare040 := 0.000000e+00;
ProcessSetup._KWaterLoss := 1.000000e-03;
ProcessSetup._KSyrupLoss := 7.800000e-03;
ProcessSetup._KProdLoss := 1.390000e-02;
ProcessSetup._KPPM303 := 5.700000e+00;
ProcessSetup._BaialageRVM301OVMin := 2.000000e+00;
ProcessSetup._SyrupLinePressure := 2.200000e+00;
ProcessSetup._CIPRMM301OV := 1.000000e+01;
ProcessSetup._CIPRMP302OV := 1.500000e+01;
ProcessSetup._CIPTM301MinLevel := 3.500000e+01;
ProcessSetup._CIPTM301MaxLevel := 5.500000e+01;
ProcessSetup._CIPPPM303Freq := 5.000000e+01;
ProcessSetup._CIPTP301MinLevel := 2.500000e+01;
ProcessSetup._CIPTP301MaxLevel := 4.500000e+01;
ProcessSetup._RinseRMM301OV := 1.000000e+01;
ProcessSetup._RinseRMP302OV := 1.400000e+01;
ProcessSetup._RinseTM301Press := 3.000000e-01;
ProcessSetup._RinsePPM303Freq := 5.000000e+01;
ProcessSetup._DrainTM301Press := 1.000000e+00;
ProcessSetup._KRecBlendError := 2.000000e+00;
ProcessSetup._KRecCarboCO2Error := 2.000000e+00;
ProcessSetup._MaxBlendError := 1.000000e+02;
ProcessSetup._MaxCarboCO2Error := 5.000000e+02;
ProcessSetup._StartUpBrixExtraWater := 4.700000e+01;
ProcessSetup._StartUpCO2ExtraWater := 8.000000e+00;
ProcessSetup._StartUpPPM303Freq := 2.000000e+01;
ProcessSetup._SyrupRoomTank := 1;
ProcessSetup._SyrupRunOutLiters := 2.900000e+02;
ProcessSetup._InjCO2Press_Offset := 5.000000e-01;
ProcessSetup._InjCO2Press_MinFlow := 4.500000e+02;
ProcessSetup._InjCO2Press_MaxFlow := 2.500000e+03;
ProcessSetup._CarboCO2Pressure := 1.250000e+01;
ProcessSetup._N2MinPressure := 1.000000e+00;
ProcessSetup._DiffSensor_Height := 3.950000e+02;
ProcessSetup._DiffSensor_DeltaHeight := -2.500000e+01;
ProcessSetup._DiffSensor_Offset := 3.618000e+01;
ProcessSetup._FillingValveHeight := 1.400000e+03;
ProcessSetup._FillerDiameter := 2.520000e+03;
ProcessSetup._FillingValveNum := 91;
ProcessSetup._FillerProdPipeDN := 1.000000e+02;
ProcessSetup._FillerProdPipeMass := 1.600000e+02;
ProcessSetup._FillingTime := 3.200000e+00;
ProcessSetup._TM301Height_0 := 1.050000e+03;
ProcessSetup._TM301LevelPerc_2 := 4.600000e+01;
ProcessSetup._TM301Height_2 := 1.625000e+03;
ProcessSetup._RVN304Factor := 1.000000e+00;
ProcessSetup._DrainTM301Flushing := 1.300000e+00;
ProcessSetup._FirstProdExtraBrix := 5.000000e-02;
ProcessSetup._FirstProdDietExtraSyr := 1.400000e-03;
ProcessSetup._EndProdLastSyrlt := 0.000000e+00;
ProcessSetup._TM301DrainSt0Time := W#16#A;
ProcessSetup._TM301DrainSt1Time := W#16#50;
ProcessSetup._ProdPipeRunOutSt0Time := W#16#1;
ProcessSetup._RMM301ProdPipeRunOu := 3.000000e+01;
ProcessSetup._RMP302ProdPipeRunOu := 4.000000e+01;
ProcessSetup._ProdPipeRunOutAmount := 3.000000e+01;
ProcessSetup._TM301RunOutChiller := 5.000000e+00;
ProcessSetup._MinSpeedNominalProd := 4.000000e-01;
ProcessSetup._MinSpeedSlowProd := 3.000000e-01;
ProcessSetup._FastChgOvrTM301DrnPrss := 9.000000e-01;
ProcessSetup._CIPTN301MinLevel := 3.500000e+01;
ProcessSetup._CIPTN301MaxLevel := 6.000000e+01;
ProcessSetup._ProdPPN304Freq := 5.000000e+01;
ProcessSetup._GAS2InjectionPress := 4.000000e+00;
ProcessSetup._BaialageRVM301OVMax := 2.000000e+01;
ProcessSetup._RinsePPN301Freq := 5.000000e+00;
ProcessSetup._CIPPPN301Freq := 5.000000e+00;
ProcessSetup._RinsePPP302Freq := 5.000000e+00;
ProcessSetup._CIPPPP302Freq := 5.000000e+00;
ProcessSetup._PercSyrupBrixSyrStarUp := 2.500000e+01;
ProcessSetup._RefTempCoolingCTRL := 0.000000e+00;
ProcessSetup._H2OSerpPrimingVolume := 1.500000e+02;
ProcessSetup._AVN301_Nozzle_Kv := 1.650000e+02;
ProcessSetup._AVN302_Nozzle_Kv := 2.600000e+02;
ProcessSetup._AVN303_Nozzle_Kv := 1.650000e+02;
ProcessSetup._DeoxSpryball_Kv := 6.700000e+01;
ProcessSetup._PremixedLineDrainTime := 300;
ProcessSetup._PPN301_H_MaxFlow := 9.000000e+01;
ProcessSetup._PPN301_H_MinFlow := 8.700000e+01;
ProcessSetup._PPN301_MaxFlow := 5.070000e+02;
ProcessSetup._PPN301_MinFlow := 2.110000e+02;
ProcessSetup._PPP302_H_MaxFlow := 8.600000e+01;
ProcessSetup._PPP302_H_MinFlow := 8.500000e+01;
ProcessSetup._PPP302_MaxFlow := 1.150000e+02;
ProcessSetup._PPP302_MinFlow := 3.200000e+01;
ProcessSetup._RinsePPM306Freq := 5.000000e+00;
ProcessSetup._CIPPPM306Freq := 5.000000e+00;
ProcessSetup._PPM307_H_MaxFlow := 0.000000e+00;
ProcessSetup._PPM307_H_MinFlow := 0.000000e+00;
ProcessSetup._PPM307_MaxFlow := 0.000000e+00;
ProcessSetup._PPM307_MinFlow := 0.000000e+00;
ProcessSetup._Temp0_VacuumCtrl := 1.800000e+01;
ProcessSetup._Temp1_VacuumCtrl := 2.000000e+00;
ProcessSetup._Temp2_VacuumCtrl := 2.000000e+00;
ProcessSetup._Temp3_VacuumCtrl := 5.000000e+01;
ProcessSetup._Temp4_VacuumCtrl := 5.000000e+01;
ProcessSetup._T1_VacuumCtrl := L#1500;
ProcessSetup._T2_VacuumCtrl := L#1500;
ProcessSetup._T3_VacuumCtrl := L#1000;
ProcessSetup._T4_VacuumCtrl := L#1000;
ProcessSetup._ICS_VolDosWorkTimePAA := 30;
ProcessSetup._ICS_VolPauseTimePAA := 30;
ProcessSetup._ICS_PAAPulseWeight := 10;
ProcessSetup._ICS_CausticPulseWeight := 10;
ProcessSetup._ICS_AcidPulseWeight := 10;
ProcessSetup._ICS_VolumeRestOfLine := 3.500000e+02;
ProcessSetup._ICS_VolDosWorkTimeCaus := 30;
ProcessSetup._ICS_VolDosPauseTimeCaus := 30;
ProcessSetup._ICS_VolDosWorkTimeAcid := 30;
ProcessSetup._ICS_VolDosPauseTimeAcid := 30;
ProcessSetup._ICS_ConcDosWorkTimeCaus := 30;
ProcessSetup._ICS_ConcDosPausTimeCaus := 30;
ProcessSetup._ICS_ConcDosWorkTimeAcid := 30;
ProcessSetup._ICS_ConcDosPausTimeAcid := 30;
ProcessSetup._RinsePPM307Freq := 3.000000e+01;
ProcessSetup._CIPPPM307Freq := 3.000000e+01;
ProcessSetup._CIP2StepTN301Lvl := 0.000000e+00;
ProcessSetup._CIP2StepTM301Lvl := 0.000000e+00;
ProcessSetup._CIP2StepTP301Lvl := 0.000000e+00;
ProcessSetup._PumpNominalFreq := 5.000000e+01;
_SwitchOff_DensityOK := FALSE;
END_DATA_BLOCK;

View File

@ -0,0 +1,9 @@
{
"level1": {
"api_key": "your-api-key-here",
"model": "gpt-3.5-turbo"
},
"level2": {},
"level3": {},
"working_directory": "C:\\Trabajo\\SIDEL\\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\\Reporte\\DB1001"
}

View File

@ -0,0 +1,26 @@
{
"x1.py": {
"display_name": "01: Copiar Valores Actuales y de Inizio",
"short_description": "Copia los valores desde una DB exportada como .DB a otra",
"long_description": "Copia los valores desde una DB exportada como .DB a otra usando la posición de cada variable. Primero controla que el tipo de datos sea correcto para continuar con la asignacion.",
"hidden": false
},
"x2.py": {
"display_name": "02: Generar comparativa",
"short_description": "Genera archivo Excel con la comparación de los 3 archivos.",
"long_description": "",
"hidden": false
},
"DB_Parser.py": {
"display_name": "DB_Parser",
"short_description": "Sin descripción corta.",
"long_description": "",
"hidden": true
},
"x3.py": {
"display_name": "x3",
"short_description": "Sin descripción corta.",
"long_description": "",
"hidden": false
}
}

View File

@ -0,0 +1,6 @@
{
"path": "C:\\Trabajo\\SIDEL\\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\\Reporte\\DB1001",
"history": [
"C:\\Trabajo\\SIDEL\\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\\Reporte\\DB1001"
]
}

View File

@ -0,0 +1,497 @@
import re
import os
import sys
import json
import glob
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
def find_working_directory():
configs = load_configuration()
working_directory = configs.get("working_directory")
if not working_directory:
print("No working directory specified in the configuration file.")
sys.exit(1)
return working_directory
def find_data_files(working_dir, source_pattern_suffix="_data.", target_pattern_suffix="_format."):
"""Find source and target files based on glob patterns and suffixes."""
all_db_files = glob.glob(os.path.join(working_dir, "*.db"))
all_awl_files = glob.glob(os.path.join(working_dir, "*.awl"))
all_txt_files = glob.glob(os.path.join(working_dir, "*.txt")) # For .db.txt style
potential_files = all_db_files + all_awl_files + all_txt_files
source_files_found = []
target_files_found = []
for f_path in potential_files:
f_name = os.path.basename(f_path)
# Check for source pattern (e.g., ends with _data.db or _data.db.txt)
# We check if `source_pattern_suffix` is part of the name before the final extension
name_part, ext_part = os.path.splitext(f_name)
if name_part.endswith(source_pattern_suffix.rstrip('.')): # Handles cases like _data.db or _data.db (if suffix includes .)
source_files_found.append(f_path)
elif source_pattern_suffix.rstrip('.') in name_part and f_name.endswith(".txt") and ".db" in name_part : # for like _data.db.txt
if name_part.split(".db")[0].endswith(source_pattern_suffix.rstrip('.')):
source_files_found.append(f_path)
# Check for target pattern
name_part_target, ext_part_target = os.path.splitext(f_name)
if name_part_target.endswith(target_pattern_suffix.rstrip('.')):
target_files_found.append(f_path)
elif target_pattern_suffix.rstrip('.') in name_part_target and f_name.endswith(".txt") and ".db" in name_part_target: # for like _format.db.txt
if name_part_target.split(".db")[0].endswith(target_pattern_suffix.rstrip('.')):
target_files_found.append(f_path)
if not source_files_found:
print(f"Warning: No source files found matching pattern ending with '{source_pattern_suffix}*' in '{working_dir}'.")
# Try a broader search for any file containing '_data' if the strict one fails
source_files_found = [f for f in potential_files if "_data" in os.path.basename(f)]
if source_files_found:
print(f"Found potential source files with less strict '_data' search: {source_files_found}")
if not target_files_found:
print(f"Warning: No target files found matching pattern ending with '{target_pattern_suffix}*' in '{working_dir}'.")
# Try a broader search for any file containing '_format'
target_files_found = [f for f in potential_files if "_format" in os.path.basename(f)]
if target_files_found:
print(f"Found potential target files with less strict '_format' search: {target_files_found}")
# Logic to select the best match if multiple are found (e.g. prefer .db over .txt, or based on modification time)
# For now, just take the first one found.
source_file = source_files_found[0] if source_files_found else None
target_file = target_files_found[0] if target_files_found else None
if source_file: print(f"Selected source file: {os.path.basename(source_file)}")
if target_file: print(f"Selected target file: {os.path.basename(target_file)}")
return source_file, target_file
def extract_sections(content):
content = content.replace('\r\n', '\n') # Normalize line endings
udt_definitions_content = ""
udt_matches = list(re.finditer(r'(?s)(TYPE\s+.*?\s+END_TYPE\s*\n?)', content, re.IGNORECASE))
content_after_udts = content
if udt_matches:
udt_definitions_content = "".join(match.group(0) for match in udt_matches)
last_udt_end = udt_matches[-1].end()
content_after_udts = content[last_udt_end:]
header_match = re.search(r'(?s)^(.*?(?:DATA_BLOCK.*?VERSION.*?\n))(.*?STRUCT)', content_after_udts, re.IGNORECASE)
if header_match:
header = header_match.group(1)
# The rest_of_content should start from "STRUCT"
rest_of_content = content_after_udts[header_match.start(2):]
else: # Fallback if the specific DATA_BLOCK header is not found
header_fallback_match = re.search(r'(?s)(.*?)(STRUCT)', content_after_udts, re.IGNORECASE)
if header_fallback_match:
header = header_fallback_match.group(1)
# Ensure rest_of_content starts with "STRUCT"
rest_of_content = content_after_udts[header_fallback_match.start(2) - len("STRUCT") if header_fallback_match.start(2) >= len("STRUCT") else 0:]
if not rest_of_content.lstrip().upper().startswith("STRUCT"): # Verification
# This might happen if STRUCT was at the very beginning.
rest_of_content = "STRUCT" + rest_of_content # Prepend if missing
else: # No STRUCT found at all after UDTs
print("Critical Warning: No 'STRUCT' keyword found for DATA_BLOCK content.")
return udt_definitions_content, content_after_udts, "", "", ""
decl_match = re.search(r'(?s)STRUCT\s+(.*?)BEGIN', rest_of_content, re.IGNORECASE)
decl_section = decl_match.group(1) if decl_match else ""
init_match = re.search(r'(?s)BEGIN\s+(.*?)END_DATA_BLOCK', rest_of_content, re.IGNORECASE)
init_section = init_match.group(1) if init_match else ""
footer_match = re.search(r'(?s)END_DATA_BLOCK(.*?)$', rest_of_content, re.IGNORECASE)
footer = footer_match.group(1) if footer_match else ""
return udt_definitions_content, header, decl_section, init_section, footer
def analyze_source_file(decl_section, init_section):
source_decl_values = []
source_init_values = []
decl_idx = 0
for line_content in decl_section.split('\n'):
line = line_content.strip()
if not line or line.startswith('//') or \
(line.upper().startswith('STRUCT') and ';' not in line) or \
(line.upper().startswith('END_STRUCT') and ';' not in line) :
continue
if ';' in line:
type_match = re.search(r':\s*([^:=;]+)', line)
var_type = type_match.group(1).strip() if type_match else ""
value = None
comment = ''
assignment_match = re.search(r':=\s*([^;]+)', line)
if assignment_match:
value = assignment_match.group(1).strip()
comment_match = re.search(r';(.*)', line[assignment_match.end():])
if comment_match: comment = comment_match.group(1).strip()
else:
comment_match = re.search(r';(.*)', line)
if comment_match: comment = comment_match.group(1).strip()
source_decl_values.append({
"index": decl_idx, "type": var_type, "value": value,
"comment": comment, "original_line_for_debug": line
})
decl_idx += 1
init_idx = 0
for line_content in init_section.split('\n'):
line = line_content.strip()
if not line or line.startswith('//'): continue
assignment_match = re.search(r':=\s*([^;]+)', line)
if assignment_match and ';' in line:
value = assignment_match.group(1).strip()
comment_match = re.search(r';(.*)', line[assignment_match.end():])
comment = comment_match.group(1).strip() if comment_match else ""
source_init_values.append({
"index": init_idx, "value": value, "comment": comment,
"original_line_for_debug": line
})
init_idx += 1
return source_decl_values, source_init_values
def analyze_target_declarations(decl_section):
target_decl_info_list = []
current_var_idx = 0
decl_lines_split = decl_section.split('\n')
for line_num, line_content in enumerate(decl_lines_split):
original_line = line_content
line = line_content.strip()
is_udt_ref = False
udt_name = None
var_type_str = None
entry = {
"line_index_in_section": line_num, "var_idx": -1,
"is_udt_instance": False, "udt_name_if_any": None,
"original_line": original_line, "type": None
}
if not line or line.startswith('//') or \
(line.upper().startswith('STRUCT') and ';' not in line and ':' not in line) or \
(line.upper().startswith('END_STRUCT') and ';' not in line and ':' not in line):
target_decl_info_list.append(entry)
continue
if ';' in line:
var_type_match = re.search(r':\s*([^:=;]+)', line)
var_type_str = var_type_match.group(1).strip() if var_type_match else ""
udt_match = re.search(r':\s*"(.*?)"', line)
if udt_match:
is_udt_ref = True
udt_name = udt_match.group(1)
entry.update({
"var_idx": current_var_idx,
"is_udt_instance": is_udt_ref,
"udt_name_if_any": udt_name,
"type": var_type_str
})
current_var_idx += 1
target_decl_info_list.append(entry)
return target_decl_info_list
def analyze_target_assignments(init_section):
target_init_info_list = []
current_assign_idx = 0
init_lines_split = init_section.split('\n')
for line_num, line_content in enumerate(init_lines_split):
original_line = line_content
line = line_content.strip()
entry = {"line_index_in_section": line_num, "assign_idx": -1, "original_line": original_line}
if not line or line.startswith('//'):
target_init_info_list.append(entry)
continue
if ':=' in line and ';' in line:
entry["assign_idx"] = current_assign_idx
current_assign_idx += 1
target_init_info_list.append(entry)
return target_init_info_list
def is_compatible_type(source_value_str, target_type_str):
if source_value_str is None: return True
if not target_type_str: return True
s_val = source_value_str.upper()
t_type = target_type_str.upper()
if "STRING" in t_type: return s_val.startswith("'") and s_val.endswith("'")
if "BOOL" == t_type: return s_val in ["TRUE", "FALSE", "1", "0"]
if "BYTE" == t_type: return s_val.startswith(("B#16#", "16#")) or (s_val.isdigit() and 0 <= int(s_val) <= 255)
if "WORD" == t_type or "DWORD" == t_type : return s_val.startswith(("W#16#", "DW#16#", "16#"))
if "INT" == t_type:
try: int(s_val); return True
except ValueError: return False
if "DINT" == t_type:
try:
int(s_val[2:]) if s_val.startswith("L#") else int(s_val)
return True
except ValueError: return False
if "REAL" == t_type:
try: float(s_val.replace('E', 'e')); return True
except ValueError: return False
if t_type.startswith("ARRAY"): return True
return True
def transfer_values_by_position(source_file_path, target_file_path, output_file_path):
try:
with open(source_file_path, 'r', encoding='utf-8-sig') as f:
source_content = f.read()
with open(target_file_path, 'r', encoding='utf-8-sig') as f:
target_content = f.read()
source_udt_defs_ignored, source_header_ignored, source_decl_sec, source_init_sec, source_footer_ignored = extract_sections(source_content)
target_udt_defs, target_header, target_decl_sec, target_init_sec, target_footer = extract_sections(target_content)
source_decl_values, source_init_values = analyze_source_file(source_decl_sec, source_init_sec)
s_decl_ptr = 0
decl_values_transferred_count = 0
init_values_transferred_count = 0
processed_target_udt_lines = []
if target_udt_defs:
udt_section_lines = target_udt_defs.split('\n')
in_udt_struct_definition = False
for udt_line_content in udt_section_lines:
line_ws = udt_line_content
stripped_line = udt_line_content.strip()
modified_udt_line = line_ws
if stripped_line.upper().startswith("TYPE"): in_udt_struct_definition = False
if stripped_line.upper().startswith("STRUCT") and not stripped_line.upper().startswith("END_STRUCT"):
prev_lines = [l.strip().upper() for l in processed_target_udt_lines if l.strip()]
if prev_lines and prev_lines[-1].startswith("TYPE"): in_udt_struct_definition = True
if stripped_line.upper().startswith("END_STRUCT"): in_udt_struct_definition = False
if in_udt_struct_definition and ';' in stripped_line and \
not stripped_line.upper().startswith(("STRUCT", "END_STRUCT", "//")):
if s_decl_ptr < len(source_decl_values):
src_data = source_decl_values[s_decl_ptr]
src_val_str = src_data["value"]
src_comment = src_data["comment"]
type_m = re.search(r':\s*([^:=;]+)', stripped_line)
target_member_type = type_m.group(1).strip() if type_m else ""
if src_val_str is not None:
if is_compatible_type(src_val_str, target_member_type):
parts = line_ws.split(';',1)
decl_part = parts[0]
comment_part = f";{parts[1]}" if len(parts) > 1 else ";"
if ':=' in decl_part: mod_decl = re.sub(r':=\s*[^;]+', f':= {src_val_str}', decl_part.rstrip())
else: mod_decl = decl_part.rstrip() + f' := {src_val_str}'
final_comment = comment_part
if comment_part == ";" and src_comment: final_comment = f"; {src_comment}"
modified_udt_line = mod_decl + final_comment
decl_values_transferred_count +=1
else:
parts = line_ws.split(';',1)
decl_part = parts[0]
comment_part = f";{parts[1]}" if len(parts) > 1 else ";"
if ':=' in decl_part:
mod_decl = re.sub(r'\s*:=\s*[^;]+', '', decl_part.rstrip())
modified_udt_line = mod_decl + comment_part
s_decl_ptr += 1
processed_target_udt_lines.append(modified_udt_line)
target_udt_defs_updated = '\n'.join(processed_target_udt_lines)
else:
target_udt_defs_updated = target_udt_defs
target_decl_block_info = analyze_target_declarations(target_decl_sec)
output_decl_block_lines = target_decl_sec.split('\n')
for target_info in target_decl_block_info:
line_idx_in_sec = target_info["line_index_in_section"]
if target_info["var_idx"] == -1 or target_info["is_udt_instance"]: continue
if s_decl_ptr < len(source_decl_values):
src_data = source_decl_values[s_decl_ptr]
src_val_str = src_data["value"]
src_comment = src_data["comment"]
target_type = target_info["type"]
original_target_line_ws = target_info["original_line"]
if src_val_str is not None:
if is_compatible_type(src_val_str, target_type):
parts = original_target_line_ws.split(';',1)
decl_part = parts[0]
comment_part = f";{parts[1]}" if len(parts) > 1 else ";"
if ':=' in decl_part: mod_decl = re.sub(r':=\s*[^;]+', f':= {src_val_str}', decl_part.rstrip())
else: mod_decl = decl_part.rstrip() + f' := {src_val_str}'
final_comment = comment_part
if comment_part == ";" and src_comment: final_comment = f"; {src_comment}"
output_decl_block_lines[line_idx_in_sec] = mod_decl + final_comment
decl_values_transferred_count +=1
else:
parts = original_target_line_ws.split(';',1)
decl_part = parts[0]
comment_part = f";{parts[1]}" if len(parts) > 1 else ";"
if ':=' in decl_part:
mod_decl = re.sub(r'\s*:=\s*[^;]+', '', decl_part.rstrip())
output_decl_block_lines[line_idx_in_sec] = mod_decl + comment_part
s_decl_ptr += 1
else: pass
target_init_block_info = analyze_target_assignments(target_init_sec)
output_init_block_lines = target_init_sec.split('\n')
for target_info in target_init_block_info:
line_idx_in_sec = target_info["line_index_in_section"]
if target_info["assign_idx"] == -1: continue
current_target_assign_idx = target_info["assign_idx"]
original_target_line_ws = target_info["original_line"]
if current_target_assign_idx < len(source_init_values):
src_data = source_init_values[current_target_assign_idx]
src_val_str = src_data["value"]
src_comment = src_data["comment"]
if src_val_str is not None:
parts = original_target_line_ws.split(';',1)
assign_part_target = parts[0]
comment_part_target = f";{parts[1]}" if len(parts) > 1 else ";"
mod_assign = re.sub(r':=\s*.*$', f':= {src_val_str}', assign_part_target.rstrip())
final_comment = comment_part_target
if comment_part_target == ";" and src_comment: final_comment = f"; {src_comment}"
output_init_block_lines[line_idx_in_sec] = mod_assign + final_comment
init_values_transferred_count += 1
final_parts = []
if target_udt_defs_updated.strip(): final_parts.append(target_udt_defs_updated.rstrip('\n') + '\n\n') # Ensure space after UDTs
elif target_udt_defs: final_parts.append(target_udt_defs)
if target_header.strip() : final_parts.append(target_header) # Header already includes its spacing
elif target_header and not target_udt_defs_updated.strip(): # if header has only newlines but no UDTs before it
final_parts.append(target_header)
if target_decl_sec.strip():
final_parts.append("STRUCT\n")
final_parts.append('\n'.join(output_decl_block_lines))
final_parts.append("\n")
elif target_decl_sec:
final_parts.append(target_decl_sec)
final_parts.append("BEGIN\n")
final_parts.append('\n'.join(output_init_block_lines))
# Ensure END_DATA_BLOCK is on its own line or correctly spaced
final_parts.append("\nEND_DATA_BLOCK")
if target_footer: final_parts.append(target_footer.rstrip('\n') + '\n' if target_footer.strip() else target_footer)
final_content = "".join(final_parts)
# Ensure there's a newline at the end of the file
if not final_content.endswith('\n'): final_content += '\n'
# Remove potential multiple blank lines at the end, keep one
final_content = re.sub(r'\n\s*\n$', '\n', final_content)
with open(output_file_path, 'w', encoding='utf-8') as f:
f.write(final_content)
print(f"\nSuccessfully transferred {decl_values_transferred_count} initial values and {init_values_transferred_count} current values.")
print(f"Output file created: {output_file_path}")
return True
except FileNotFoundError:
print(f"Error: File not found. Source: '{source_file_path}', Target: '{target_file_path}'")
return False
except Exception as e:
print(f"An error occurred during transfer: {e}")
import traceback
print(traceback.format_exc())
return False
def main():
print("PLC Data Block Adapter - Advanced UDT Handling (Restored Auto File Find)")
print("========================================================================")
working_dir = find_working_directory()
print(f"Using working directory: {working_dir}")
# Using automatic file finding based on patterns
# "_data." will match _data.db, _data.awl, _data.db.txt (if .txt is handled in find_data_files)
source_f, target_f = find_data_files(working_dir,
source_pattern_suffix="_data",
target_pattern_suffix="_format")
if not source_f or not target_f:
print("Error: Could not automatically find required source or target files using patterns.")
print("Please ensure files ending with e.g., '_data.db' (source) and '_format.db' (target) exist.")
return False
# Construct output name
target_basename = os.path.basename(target_f)
name_part, first_ext = os.path.splitext(target_basename)
if first_ext.lower() == ".txt" and ".db" in name_part.lower(): # Handles .db.txt
name_part, second_ext = os.path.splitext(name_part) # name_part is now "xxx_format"
output_basename = name_part + "_updated" + second_ext + first_ext # e.g. xxx_format_updated.db.txt
elif first_ext.lower() in ['.db', '.awl']:
output_basename = name_part + "_updated" + first_ext
else: # Fallback for other extensions or no extension
output_basename = target_basename.rsplit('.',1)[0] if '.' in target_basename else target_basename
output_basename += "_updated" + ('.' + target_basename.rsplit('.',1)[1] if '.' in target_basename else ".db")
output_f = os.path.join(working_dir, output_basename)
print(f"\nProcessing:")
print(f" Source: {os.path.basename(source_f)}")
print(f" Target: {os.path.basename(target_f)}")
print(f" Output: {os.path.basename(output_f)}")
success = transfer_values_by_position(source_f, target_f, output_f)
if success:
print(f"\nSUCCESS: Script finished. Output: '{os.path.basename(output_f)}'")
else:
print(f"\nERROR: Script failed. Please check messages above.")
return success
if __name__ == "__main__":
main()

View File

@ -0,0 +1,335 @@
import re
import os
import sys # Not strictly needed by this version but often kept from original
import glob
import pandas as pd # For Excel writing
# --- Functions for script operation ---
def find_working_directory_from_x1():
"""
Finds the working directory.
Defaults to current directory. Adapt if specific configuration is needed.
"""
print("Info: `find_working_directory_from_x1` is using the current directory.")
return os.getcwd()
def extract_sections(content):
"""
Extracts UDT definitions, main declaration section, and initialization section from S7 AWL/DB content.
Uses re.IGNORECASE and re.DOTALL (via ?is) for matching keywords across different casings and newlines.
"""
content = content.replace('\r\n', '\n') # Normalize line endings
udt_definitions_content = ""
# Regex to find TYPE...END_TYPE blocks (UDT definitions)
udt_matches = list(re.finditer(r'(?is)(TYPE\s+.*?\s+END_TYPE\s*\n?)', content))
content_after_udts = content
if udt_matches:
udt_definitions_content = "".join(match.group(0) for match in udt_matches)
# Get content after the last UDT definition
last_udt_end = udt_matches[-1].end()
content_after_udts = content[last_udt_end:]
header_text = "" # Placeholder, not actively used in this script's comparison logic
rest_of_content_for_struct = content_after_udts
# Try to find the main DATA_BLOCK header and the start of its STRUCT
header_match = re.search(r'(?is)^(.*?(?:DATA_BLOCK.*?VERSION.*?\n))(.*?STRUCT)', content_after_udts)
if header_match:
# Content for further parsing starts at "STRUCT"
rest_of_content_for_struct = content_after_udts[header_match.start(2):]
else:
# Fallback: find the first "STRUCT" if the specific header pattern isn't met
header_fallback_match = re.search(r'(?is)(.*?)(STRUCT)', content_after_udts)
if header_fallback_match:
rest_of_content_for_struct = content_after_udts[header_fallback_match.start(2):]
else:
# If no STRUCT is found, declaration section will be empty
print(f"Warning: No 'STRUCT' keyword found for main DB declarations in a content block.")
# Declaration section: from the found STRUCT up to BEGIN
decl_match = re.search(r'(?is)STRUCT\s*(.*?)BEGIN', rest_of_content_for_struct)
decl_section = decl_match.group(1).strip() if decl_match else ""
# Initialization section: from BEGIN up to END_DATA_BLOCK
init_match = re.search(r'(?is)BEGIN\s*(.*?)END_DATA_BLOCK', rest_of_content_for_struct)
init_section = init_match.group(1).strip() if init_match else ""
# Footer after END_DATA_BLOCK isn't used
return udt_definitions_content, header_text, decl_section, init_section, ""
def find_comparison_files_detailed(working_dir, data_suffix="_data", format_suffix="_format", updated_suffix_part="_updated"):
"""Finds data, format, and _updated files based on naming conventions."""
all_files_in_dir = []
for ext_pattern in ["*.db", "*.awl", "*.txt"]: # Common S7 export extensions
all_files_in_dir.extend(glob.glob(os.path.join(working_dir, ext_pattern)))
# Normalize paths for consistent comparisons and ensure uniqueness
all_files_in_dir = sorted(list(set(os.path.normpath(f) for f in all_files_in_dir)))
found_paths = {'data': None, 'format': None, 'updated': None}
def select_best_file(file_list):
if not file_list: return None
# Prioritize: .db, then .awl, then .txt
file_list.sort(key=lambda x: ('.db' not in x.lower(), '.awl' not in x.lower(), '.txt' not in x.lower()))
return file_list[0]
# Find _data file: contains data_suffix, does not contain updated_suffix_part
data_candidates = [f for f in all_files_in_dir if data_suffix in os.path.basename(f).lower() and updated_suffix_part not in os.path.basename(f).lower()]
found_paths['data'] = select_best_file(data_candidates)
# Find _format file: contains format_suffix, does not contain updated_suffix_part
format_candidates = [f for f in all_files_in_dir if format_suffix in os.path.basename(f).lower() and updated_suffix_part not in os.path.basename(f).lower()]
if found_paths['data'] and format_candidates: # Ensure it's not the same as _data file
format_candidates = [f for f in format_candidates if f != found_paths['data']]
found_paths['format'] = select_best_file(format_candidates)
# Find _updated file:
# Strategy 1: Based on format_file name (most reliable if format_file found)
if found_paths['format']:
format_basename = os.path.basename(found_paths['format'])
name_part, first_ext = os.path.splitext(format_basename)
updated_basename_candidate = ""
# Handle double extensions like ".db.txt" or ".awl.txt"
if first_ext.lower() == ".txt" and ('.db' in name_part.lower() or '.awl' in name_part.lower()):
base_name_for_main_ext, second_ext = os.path.splitext(name_part)
updated_basename_candidate = base_name_for_main_ext + updated_suffix_part + second_ext + first_ext
else: # Single extension
updated_basename_candidate = name_part + updated_suffix_part + first_ext
potential_updated_path = os.path.join(working_dir, updated_basename_candidate)
if os.path.exists(potential_updated_path) and potential_updated_path in all_files_in_dir:
found_paths['updated'] = potential_updated_path
# Strategy 2: If not found by deriving from format_file, search more broadly
if not found_paths['updated']:
updated_candidates = [f for f in all_files_in_dir if updated_suffix_part in os.path.basename(f).lower()]
if found_paths['format'] and updated_candidates: # Prefer updated file related to format file's base name
format_base = os.path.basename(found_paths['format']).split(format_suffix)[0]
updated_candidates = [f for f in updated_candidates if format_base in os.path.basename(f)]
# Exclude already identified data and format files
if found_paths['data'] and updated_candidates: updated_candidates = [f for f in updated_candidates if f != found_paths['data']]
if found_paths['format'] and updated_candidates: updated_candidates = [f for f in updated_candidates if f != found_paths['format']]
found_paths['updated'] = select_best_file(updated_candidates)
print("Identified files for comparison:")
for key, val in found_paths.items():
print(f" {key.capitalize()} file: {os.path.basename(val) if val else 'Not found'}")
return found_paths['data'], found_paths['format'], found_paths['updated']
def get_variables_from_section_content(section_str, section_type="declaration"):
""" Parses a declaration or initialization section string and returns a list of variable dicts. """
variables = []
idx = 0
lines = section_str.replace('\r\n', '\n').split('\n')
for line_content in lines:
line = line_content.strip()
if not line or line.startswith('//'): continue # Skip empty or comment lines
line_upper = line.upper()
# Skip lines that are purely structural (STRUCT, TYPE, END_STRUCT)
# unless they also contain a full declaration/assignment on the same line.
if (line_upper == 'STRUCT' or line_upper.startswith('TYPE ') or line_upper == 'END_STRUCT' or line_upper == 'BEGIN' or line_upper == 'END_DATA_BLOCK'):
if not (':' in line and ';' in line or ':=' in line and ';' in line ): # if not also a var line
continue
var_name, var_type, value = None, None, None
if section_type == "declaration": # Expect: VarName : VarType [:= InitialValue] ;
if ':' in line and ';' in line:
# Name: part before ':' (handles simple and "quoted" names)
name_match = re.match(r'^\s*(\"(?:\\\"|[^\"])*\"|[a-zA-Z_][\w]*)', line, re.IGNORECASE)
var_name = name_match.group(1).strip().replace('"', "") if name_match else None
# Type: part between ':' and potential ':=' or ';' (handles "UDT", simple, ARRAY)
type_match = re.search(r':\s*(\"[^\"]+\"|[^:=;]+)', line, re.IGNORECASE)
var_type = type_match.group(1).strip().replace('"', "") if type_match else None
# Value: part between ':=' and ';'
assign_match = re.search(r':=\s*([^;]+)', line, re.IGNORECASE)
if assign_match: value = assign_match.group(1).strip()
if not var_name or not var_type: continue # Must have name and type for a declaration
else: continue # Not a declaration line by this rule
elif section_type == "initialization": # Expect: VarNameOrPath := Value ;
if ':=' in line and ';' in line:
# Name/Path: part before ':=' (handles "Quoted.Path", Simple.Path, Array[1].Path)
name_match = re.match(r'^\s*(\"(?:\\\"|[^\"])*\"|[a-zA-Z_][\w"\[\],\.]*(?:\[.*?\]|\.[a-zA-Z_][\w"\[\],\.]*)*)\s*:=', line, re.IGNORECASE)
var_name = name_match.group(1).strip().replace('"', "") if name_match else None
# Value: part between ':=' and ';'
value_match = re.search(r':=\s*([^;]+)', line, re.IGNORECASE)
value = value_match.group(1).strip() if value_match else None
if not var_name or value is None : continue # Must have name and value for assignment
else: continue # Not an assignment line
if var_name is not None: # If a name was captured (and other conditions met), record it
variables.append({
"index": idx, "name": var_name, "type": var_type, "value": value,
"original_line": line_content
})
idx += 1
return variables
def process_file_for_vars(file_path):
"""
Reads a file, extracts main STRUCT declarations and BEGIN block initializations.
UDT definitions themselves are not included in the returned `main_struct_decl_vars`.
"""
if not file_path or not os.path.exists(file_path):
return [], [] # Return empty lists if file not found
try:
with open(file_path, 'r', encoding='utf-8-sig') as f: # utf-8-sig handles BOM
content = f.read()
except Exception as e:
print(f"Error reading file {file_path}: {e}")
return [], []
# udt_definitions_content is extracted but not directly used for the comparison lists below
_udt_definitions_content, _header, decl_content_main, init_content, _footer = extract_sections(content)
# "main_struct_decl_vars" are from the main DATA_BLOCK's STRUCT section (initial values).
main_struct_decl_vars = get_variables_from_section_content(decl_content_main, "declaration")
# "begin_block_init_vars" are from the BEGIN...END_DATA_BLOCK section (current values).
begin_block_init_vars = get_variables_from_section_content(init_content, "initialization")
return main_struct_decl_vars, begin_block_init_vars
def generate_excel_comparison(data_file, format_file, updated_file, output_excel_path):
"""Generates an Excel file with two sheets comparing variables from three source files."""
print(f"\nProcessing _data file: {os.path.basename(data_file) if data_file else 'N/A'}")
data_decl_vars, data_init_vars = process_file_for_vars(data_file)
print(f" Found {len(data_decl_vars)} declaration vars, {len(data_init_vars)} initialization vars in _data file.")
print(f"Processing _format file: {os.path.basename(format_file) if format_file else 'N/A'}")
format_decl_vars, format_init_vars = process_file_for_vars(format_file)
print(f" Found {len(format_decl_vars)} declaration vars, {len(format_init_vars)} initialization vars in _format file.")
print(f"Processing _updated file: {os.path.basename(updated_file) if updated_file else 'N/A'}")
updated_decl_vars, updated_init_vars = process_file_for_vars(updated_file)
print(f" Found {len(updated_decl_vars)} declaration vars, {len(updated_init_vars)} initialization vars in _updated file.")
placeholder_var = {"name": "", "type": "", "value": "", "original_line": ""}
# Define column order once, will be used for both sheets
column_order = ["Variable Name (_data / _format)", "Data Type", "Value (_data)", "Value (_format)", "Value (_updated)"]
# --- Prepare data for "Declarations (Initial Values)" sheet ---
decl_excel_rows = []
# Determine max length for declaration rows based on non-empty lists
decl_lengths = [len(lst) for lst in [data_decl_vars, format_decl_vars, updated_decl_vars] if lst is not None]
max_decl_len = max(decl_lengths) if decl_lengths else 0
print(f"\nComparing {max_decl_len} positional declaration entries (STRUCT section)...")
for i in range(max_decl_len):
var_d = data_decl_vars[i] if data_decl_vars and i < len(data_decl_vars) else placeholder_var
var_f = format_decl_vars[i] if format_decl_vars and i < len(format_decl_vars) else placeholder_var
var_u = updated_decl_vars[i] if updated_decl_vars and i < len(updated_decl_vars) else placeholder_var
# Construct combined name
name_d_str = var_d['name'] if var_d['name'] else ""
name_f_str = var_f['name'] if var_f['name'] else ""
combined_name = f"{name_d_str} / {name_f_str}".strip(" /")
if not combined_name: combined_name = var_u['name'] or name_d_str or name_f_str # Fallback
# Determine Data Type: Priority: format, then updated, then data
type_to_use = var_f['type'] or var_u['type'] or var_d['type'] or "N/A"
decl_excel_rows.append({
"Variable Name (_data / _format)": combined_name,
"Data Type": type_to_use,
"Value (_data)": str(var_d['value']) if var_d['value'] is not None else "",
"Value (_format)": str(var_f['value']) if var_f['value'] is not None else "",
"Value (_updated)": str(var_u['value']) if var_u['value'] is not None else ""
})
df_declarations = pd.DataFrame(decl_excel_rows)
if not df_declarations.empty: # Apply column order if DataFrame is not empty
for col in column_order:
if col not in df_declarations.columns: df_declarations[col] = "" # Ensure all columns exist
df_declarations = df_declarations[column_order]
# --- Prepare data for "Initializations (Current Values)" sheet ---
init_excel_rows = []
init_lengths = [len(lst) for lst in [data_init_vars, format_init_vars, updated_init_vars] if lst is not None]
max_init_len = max(init_lengths) if init_lengths else 0
print(f"Comparing {max_init_len} positional initialization entries (BEGIN block)...")
for i in range(max_init_len):
var_d = data_init_vars[i] if data_init_vars and i < len(data_init_vars) else placeholder_var
var_f = format_init_vars[i] if format_init_vars and i < len(format_init_vars) else placeholder_var
var_u = updated_init_vars[i] if updated_init_vars and i < len(updated_init_vars) else placeholder_var
name_d_str = var_d['name'] if var_d['name'] else ""
name_f_str = var_f['name'] if var_f['name'] else ""
combined_name = f"{name_d_str} / {name_f_str}".strip(" /")
if not combined_name: combined_name = var_u['name'] or name_d_str or name_f_str
init_excel_rows.append({
"Variable Name (_data / _format)": combined_name,
"Data Type": "N/A", # Type is not usually re-declared in initialization lines
"Value (_data)": str(var_d['value']) if var_d['value'] is not None else "",
"Value (_format)": str(var_f['value']) if var_f['value'] is not None else "",
"Value (_updated)": str(var_u['value']) if var_u['value'] is not None else ""
})
df_initializations = pd.DataFrame(init_excel_rows)
if not df_initializations.empty: # Apply column order
for col in column_order:
if col not in df_initializations.columns: df_initializations[col] = ""
df_initializations = df_initializations[column_order]
# --- Write to Excel with two sheets ---
try:
with pd.ExcelWriter(output_excel_path, engine='openpyxl') as writer:
if not df_declarations.empty:
df_declarations.to_excel(writer, sheet_name='Declarations (Initial Values)', index=False)
print(f"Written 'Declarations (Initial Values)' sheet with {len(df_declarations)} rows.")
else:
print("No data for 'Declarations (Initial Values)' sheet.")
if not df_initializations.empty:
df_initializations.to_excel(writer, sheet_name='Initializations (Current Values)', index=False)
print(f"Written 'Initializations (Current Values)' sheet with {len(df_initializations)} rows.")
else:
print("No data for 'Initializations (Current Values)' sheet.")
if df_declarations.empty and df_initializations.empty:
print("No data written to Excel as both datasets are empty.")
else:
print(f"\nSuccessfully generated Excel comparison: {output_excel_path}")
except Exception as e:
print(f"Error writing Excel file {output_excel_path}: {e}")
def main_comparator():
print("S7 Data Block Comparator to Excel (Multi-Sheet)")
print("==============================================")
working_dir = find_working_directory_from_x1()
print(f"Using working directory: {working_dir}")
data_f, format_f, updated_f = find_comparison_files_detailed(working_dir)
if not any([data_f, format_f, updated_f]): # Check if at least one relevant file was found
print("\nError: Could not find a sufficient set of input files (_data, _format, _updated). Exiting.")
return
output_filename = "S7_DB_Comparison_MultiSheet.xlsx"
output_excel_file = os.path.join(working_dir, output_filename)
generate_excel_comparison(data_f, format_f, updated_f, output_excel_file)
if __name__ == "__main__":
main_comparator()

View File

@ -0,0 +1,533 @@
import re
import json
from dataclasses import dataclass, field
from typing import List, Dict, Optional, Union, Tuple, Any
import copy
@dataclass
class ArrayDimension:
lower_bound: int
upper_bound: int
@property
def count(self) -> int:
return self.upper_bound - self.lower_bound + 1
@dataclass
class VariableInfo:
name: str
data_type: str
byte_offset: float
size_in_bytes: int # For BOOL arrays, this is the number of bytes spanned. For single BOOL, 0.
bit_size: int = 0 # For BOOL, this is 1. For others, usually 0 unless it's a bitfield type.
udt_source_name: Optional[str] = None
string_length: Optional[int] = None
array_dimensions: List[ArrayDimension] = field(default_factory=list)
initial_value: Optional[str] = None
current_value: Optional[str] = None
comment: Optional[str] = None
children: List['VariableInfo'] = field(default_factory=list)
is_udt_expanded_member: bool = False
@dataclass
class UdtInfo:
name: str
family: Optional[str] = None
version: Optional[str] = None
members: List[VariableInfo] = field(default_factory=list)
total_size_in_bytes: int = 0
@dataclass
class DbInfo:
name: str
title: Optional[str] = None
family: Optional[str] = None
version: Optional[str] = None
members: List[VariableInfo] = field(default_factory=list)
total_size_in_bytes: int = 0
_initial_values_from_begin_block: Dict[str, str] = field(default_factory=dict)
@dataclass
class ParsedData:
udts: List[UdtInfo] = field(default_factory=list)
dbs: List[DbInfo] = field(default_factory=list)
@dataclass
class OffsetContext:
byte_offset: int = 0
bit_offset: int = 0 # 0-7
def get_combined_offset(self) -> float:
if self.bit_offset == 0:
return float(self.byte_offset)
return float(self.byte_offset * 10 + self.bit_offset) / 10.0
def advance_bits(self, num_bits: int):
self.bit_offset += num_bits
self.byte_offset += self.bit_offset // 8
self.bit_offset %= 8
def align_to_byte(self):
if self.bit_offset > 0:
self.byte_offset += 1
self.bit_offset = 0
def align_to_word(self):
self.align_to_byte()
if self.byte_offset % 2 != 0:
self.byte_offset += 1
S7_PRIMITIVE_SIZES = {
# type_name: (size_in_bytes, alignment_in_bytes_for_start, is_bool_type)
"BOOL": (0, 1, True), "BYTE": (1, 1, False), "CHAR": (1, 1, False),
"SINT": (1, 1, False), "USINT": (1, 1, False), "WORD": (2, 2, False),
"INT": (2, 2, False), "UINT": (2, 2, False), "S5TIME": (2, 2, False),
"DATE": (2, 2, False), "DWORD": (4, 2, False), "DINT": (4, 2, False),
"UDINT": (4, 2, False), "REAL": (4, 2, False), "TIME": (4, 2, False),
"TIME_OF_DAY": (4, 2, False), "TOD": (4, 2, False), # TOD is alias for TIME_OF_DAY
"LREAL": (8, 2, False), "LINT": (8, 2, False), "ULINT": (8, 2, False),
"LWORD": (8, 2, False), "DATE_AND_TIME": (8, 2, False), "DT": (8, 2, False), # DT is alias for DATE_AND_TIME
# STRING is handled specially due to its length component
}
class S7Parser:
def __init__(self):
self.parsed_data = ParsedData()
self.known_udts: Dict[str, UdtInfo] = {}
self.type_start_regex = re.compile(r'^\s*TYPE\s+"([^"]+)"', re.IGNORECASE)
self.db_start_regex = re.compile(r'^\s*DATA_BLOCK\s+"([^"]+)"', re.IGNORECASE)
self.property_regex = re.compile(r'^\s*([A-Z_]+)\s*:\s*(.+?)(?:\s*;)?\s*(?://.*)?$', re.IGNORECASE)
self.struct_start_regex = re.compile(r'^\s*STRUCT\b', re.IGNORECASE)
self.end_struct_regex = re.compile(r'^\s*END_STRUCT\b', re.IGNORECASE)
self.end_type_regex = re.compile(r'^\s*END_TYPE\b', re.IGNORECASE)
self.end_db_regex = re.compile(r'^\s*END_DATA_BLOCK\b', re.IGNORECASE)
self.begin_regex = re.compile(r'^\s*BEGIN\b', re.IGNORECASE)
self.var_regex_simplified = re.compile(
r'^\s*(?P<name>[a-zA-Z_][a-zA-Z0-9_]*)\s*:\s*'
r'(?P<typefull>'
r'(?:ARRAY\s*\[(?P<arraydims>[^\]]+?)\]\s*OF\s*)?'
r'(?P<basetype>(?:"[^"]+"|[a-zA-Z_][a-zA-Z0-9_]*))' # UDTs in quotes, primitives without
r'(?:\s*\[\s*(?P<stringlength>\d+)\s*\])?' # Optional string length
r')'
r'(?:\s*:=\s*(?P<initval>[^;]*?))??\s*' # Initial value: non-greedy, does not cross a semicolon
r';?\s*$', # Optional semicolon at the end of the declaration
re.IGNORECASE
)
self.array_dim_regex = re.compile(r'(\d+)\s*\.\.\s*(\d+)')
def _get_type_details(self, type_name_raw: str) -> Tuple[int, int, bool, str]:
type_name_cleaned = type_name_raw.strip('"').upper()
udt_original_case_name = type_name_raw.strip('"')
if type_name_cleaned in S7_PRIMITIVE_SIZES:
size, align, is_bool = S7_PRIMITIVE_SIZES[type_name_cleaned]
return size, align, is_bool, type_name_cleaned
elif udt_original_case_name in self.known_udts:
udt = self.known_udts[udt_original_case_name]
return udt.total_size_in_bytes, 2, False, udt_original_case_name # UDTs align like structs (word)
elif type_name_cleaned == "STRUCT": # For explicit STRUCT members
return 0, 2, False, "STRUCT" # Size determined by members, aligns to word
raise ValueError(f"Unknown data type or UDT not defined: '{type_name_raw}' (Cleaned: '{type_name_cleaned}', Original UDT: '{udt_original_case_name}')")
@staticmethod
def _adjust_children_offsets(children: List[VariableInfo], base_offset_add: float):
for child in children:
child.byte_offset += base_offset_add
if child.byte_offset == float(int(child.byte_offset)):
child.byte_offset = float(int(child.byte_offset))
if child.children:
S7Parser._adjust_children_offsets(child.children, base_offset_add) # Pass the original base_offset_add
def _parse_struct_members(self, lines: List[str], current_line_idx: int,
parent_members_list: List[VariableInfo],
active_context: OffsetContext,
is_top_level_struct_in_block: bool = False) -> int:
idx_to_process = current_line_idx
while idx_to_process < len(lines):
original_line_text_with_leading_space = lines[idx_to_process]
original_line_text = original_line_text_with_leading_space.strip()
line_to_parse = original_line_text
line_comment = None
comment_marker_idx = original_line_text.find("//")
if comment_marker_idx != -1:
line_to_parse = original_line_text[:comment_marker_idx].strip()
line_comment = original_line_text[comment_marker_idx + 2:].strip()
line_index_for_return = idx_to_process # Save index before incrementing
idx_to_process += 1 # Pre-increment for next loop or return
if not line_to_parse: # If line is empty after stripping comments, or was originally empty
continue
# Handle block endings (STRUCT, TYPE, DB, BEGIN) based on line_to_parse
if self.end_struct_regex.match(line_to_parse):
if not is_top_level_struct_in_block: # End of a nested STRUCT member
active_context.align_to_byte() # Ensure current byte is finished
if active_context.byte_offset % 2 != 0: # Struct total size must be even
active_context.byte_offset += 1
return idx_to_process # Return line number AFTER END_STRUCT
# If is_top_level_struct_in_block, END_STRUCT is for the main block, handled by END_TYPE/DB
if is_top_level_struct_in_block and \
(self.end_type_regex.match(line_to_parse) or \
self.end_db_regex.match(line_to_parse) or \
self.begin_regex.match(line_to_parse)):
active_context.align_to_byte() # Finish current byte for the whole UDT/DB declaration part
if active_context.byte_offset % 2 != 0: # Total size must be even
active_context.byte_offset += 1
return line_index_for_return # Return index OF the BEGIN/END_TYPE/END_DB line
# Check for STRUCT start for a member
if self.struct_start_regex.match(line_to_parse): # This is a nested STRUCT member declaration
# This line should be matched by var_regex as a variable of type STRUCT
# If we are here, it means var_regex didn't match it, or it's an anonymous struct.
# For simplicity, we assume named structs are parsed by var_regex.
# This path might need review if anonymous structs are common.
# For now, we assume explicit STRUCT members are named and caught by var_regex
pass # Let var_regex handle it if it's a named struct
var_match = self.var_regex_simplified.match(line_to_parse)
if var_match:
var_data = var_match.groupdict()
var_info = VariableInfo(name=var_data['name'], data_type="", byte_offset=0, size_in_bytes=0)
initial_val_str = var_data.get('initval')
if initial_val_str:
var_info.initial_value = initial_val_str.strip()
if line_comment:
var_info.comment = line_comment
raw_base_type = var_data['basetype'].strip()
var_info.data_type = raw_base_type.strip('"') # Store clean type for logic
if raw_base_type.startswith('"') and raw_base_type.endswith('"'):
var_info.udt_source_name = raw_base_type # Store with quotes if UDT
num_array_elements = 1
if var_data['arraydims']:
for dim_match in self.array_dim_regex.finditer(var_data['arraydims']):
var_info.array_dimensions.append(ArrayDimension(int(dim_match.group(1)), int(dim_match.group(2))))
if var_info.array_dimensions:
for dim in var_info.array_dimensions:
num_array_elements *= dim.count
# --- Offset and Size Calculation ---
if var_info.data_type.upper() == "STRUCT": # Member is explicitly 'STRUCT'
active_context.align_to_word()
var_info.byte_offset = active_context.get_combined_offset()
nested_struct_context = OffsetContext() # Children offsets are relative to this new context
# We need to find the line "STRUCT" and parse from the line AFTER it
# The current idx_to_process is already advanced.
# The _parse_struct_members call will continue from where the var_match line was,
# which is not right for a struct definition that spans multiple lines.
# This means "STRUCT" members need to be handled by the parser finding "STRUCT" keyword,
# not just by var_regex matching "Variable : STRUCT".
# For now, assume if var_regex matched, it's a named struct.
# The call to _parse_struct_members for children should start from the *next line* in the input lines list.
idx_after_nested_struct = self._parse_struct_members(
lines,
idx_to_process, # Start parsing members of this struct from the next available line
var_info.children,
nested_struct_context,
is_top_level_struct_in_block=False # This is a nested struct
)
var_info.size_in_bytes = nested_struct_context.byte_offset # This is the calculated size of the nested struct
# Adjust children offsets to be absolute
# The children's byte_offset are currently relative to the start of the nested_struct_context (0.0)
# They need to be relative to the DB/UDT.
# var_info.byte_offset is the absolute start of this STRUCT member.
for child in var_info.children:
child.byte_offset += var_info.byte_offset
if child.byte_offset == float(int(child.byte_offset)):
child.byte_offset = float(int(child.byte_offset))
if child.children: # If UDTs within struct had their own structs
S7Parser._adjust_children_offsets(child.children, var_info.byte_offset)
active_context.byte_offset += var_info.size_in_bytes # Advance parent context
idx_to_process = idx_after_nested_struct # Update main loop's line index
elif var_info.data_type.upper() == "STRING" and var_data['stringlength']:
var_info.string_length = int(var_data['stringlength'])
unit_size = var_info.string_length + 2
active_context.align_to_word() # STRINGs are word-aligned
var_info.byte_offset = active_context.get_combined_offset()
var_info.size_in_bytes = unit_size * num_array_elements
active_context.byte_offset += var_info.size_in_bytes
else: # Primitive or UDT instance
# Use var_info.data_type (cleaned name) for _get_type_details
unit_size_bytes, unit_alignment_req, is_bool, type_name_for_udt_lookup = self._get_type_details(var_info.data_type)
if is_bool:
var_info.bit_size = 1 # A single BOOL is 1 bit
# For an array of BOOLs, record offset of the first bit
var_info.byte_offset = active_context.get_combined_offset()
active_context.advance_bits(num_array_elements) # Advance context by total bits
# Calculate effective byte span for the BOOL or BOOL array
start_byte_abs = int(var_info.byte_offset)
start_bit_in_byte = int(round((var_info.byte_offset - start_byte_abs) * 10))
if num_array_elements == 1:
var_info.size_in_bytes = 0 # Convention for single bit
else: # Array of BOOLs
bits_remaining = num_array_elements
bytes_spanned = 0
if start_bit_in_byte > 0: # Starts mid-byte
bits_in_first_byte = 8 - start_bit_in_byte
if bits_remaining <= bits_in_first_byte:
bytes_spanned = 1
else:
bytes_spanned = 1
bits_remaining -= bits_in_first_byte
bytes_spanned += (bits_remaining + 7) // 8 # Ceiling division for remaining full bytes
else: # Starts on a byte boundary
bytes_spanned = (bits_remaining + 7) // 8
var_info.size_in_bytes = bytes_spanned
else: # Non-BOOL primitive or UDT
active_context.align_to_byte() # Finish any pending bits
if unit_alignment_req == 2: # WORD, DWORD, REAL, UDT, etc.
active_context.align_to_word()
var_info.byte_offset = active_context.get_combined_offset()
var_info.size_in_bytes = unit_size_bytes * num_array_elements
active_context.byte_offset += var_info.size_in_bytes
# If it's a UDT instance, expand its members
if type_name_for_udt_lookup in self.known_udts and not is_bool:
udt_def = self.known_udts[type_name_for_udt_lookup]
udt_instance_absolute_start_offset = var_info.byte_offset
for udt_member_template in udt_def.members:
expanded_member = copy.deepcopy(udt_member_template)
expanded_member.is_udt_expanded_member = True
# udt_member_template.byte_offset is relative to UDT start (0.0)
expanded_member.byte_offset += udt_instance_absolute_start_offset
if expanded_member.byte_offset == float(int(expanded_member.byte_offset)):
expanded_member.byte_offset = float(int(expanded_member.byte_offset))
# If the UDT member itself has children (e.g., a struct within the UDT)
# their offsets also need to be made absolute relative to the DB.
# The base_offset_add for _adjust_children_offsets should be the
# absolute start of the current UDT instance.
if expanded_member.children:
S7Parser._adjust_children_offsets(expanded_member.children, udt_instance_absolute_start_offset)
var_info.children.append(expanded_member)
parent_members_list.append(var_info)
else: # Line not matched by var_regex
# Check if it's a STRUCT definition line that var_regex MISSED
# This is a fallback / debug for when 'STRUCT' starts a definition block for a member
struct_keyword_match = self.struct_start_regex.match(line_to_parse)
if struct_keyword_match and not var_match : # An unnamed struct or parsing issue
print(f"DEBUG: Found 'STRUCT' keyword on line but not parsed by var_regex: '{original_line_text}' | Processed='{line_to_parse}'")
# This case might need more robust handling if anonymous structs are used or if var_regex is too strict for named structs
elif line_to_parse and \
not self.end_struct_regex.match(line_to_parse) and \
not (is_top_level_struct_in_block and \
(self.end_type_regex.match(line_to_parse) or \
self.end_db_regex.match(line_to_parse) or \
self.begin_regex.match(line_to_parse))):
print(f"DEBUG: Line not parsed as variable or known keyword: Original='{original_line_text}' | Processed='{line_to_parse}'")
# This final padding should ideally be handled when END_STRUCT or END_TYPE/DB is detected
# For is_top_level_struct_in_block, it's handled by BEGIN/END_TYPE/DB detection.
# For nested structs, it's handled by END_STRUCT detection.
return idx_to_process
def _parse_begin_block(self, lines: List[str], start_idx: int, db_info: DbInfo) -> int:
idx = start_idx
# Regex for assignment: path := value ;
# Path can contain dots, array indices. Value can be complex.
assignment_regex = re.compile(r'^\s*(?P<path>[a-zA-Z0-9_."\[\],\s]+?)\s*:=\s*(?P<value>.+?)\s*;?\s*$', re.IGNORECASE)
while idx < len(lines):
original_line = lines[idx].strip()
line_to_parse = original_line
comment_marker_idx = original_line.find("//")
if comment_marker_idx != -1:
line_to_parse = original_line[:comment_marker_idx].strip()
# comment = original_line[comment_marker_idx+2:].strip() # Comment in BEGIN usually not stored
if self.end_db_regex.match(line_to_parse): # END_DATA_BLOCK terminates BEGIN section
return idx # Return index of END_DATA_BLOCK
idx += 1 # Advance to next line
if not line_to_parse: continue # Skip empty lines
match = assignment_regex.match(line_to_parse)
if match:
path = match.group("path").strip()
value = match.group("value").strip().rstrip(';').strip()
db_info._initial_values_from_begin_block[path] = value
# else: # Optional: print lines in BEGIN that don't match assignment
# print(f"DEBUG: Line in BEGIN not matched as assignment: '{original_line}'")
raise SyntaxError("Expected END_DATA_BLOCK after BEGIN section, but not found.")
def _apply_current_values(self, members: List[VariableInfo], begin_values: Dict[str, str], current_path_prefix: str = ""):
for var_info in members:
# Construct full path, handling array indices if necessary (simplification: not handling array element assignment here)
# For UDTs, the path in BEGIN block directly names the UDT member, e.g., "MyUdtVar._Name"
full_member_path = f"{current_path_prefix}{var_info.name}"
if var_info.is_udt_expanded_member: # Path comes from the UDT parent
# This requires careful reconstruction if the assignment path is more complex
# For now, assume direct member access for expanded UDTs.
# Example: If parent is "Actual_Recipe", and child is "_Name", path is "Actual_Recipe._Name"
# current_path_prefix should be the name of the UDT variable instance.
pass # The full_member_path is already constructed above with current_path_prefix
if full_member_path in begin_values:
var_info.current_value = begin_values[full_member_path]
elif var_info.initial_value is not None: # Fallback to declaration initial value
var_info.current_value = var_info.initial_value
# If this member itself has children (it's a parsed STRUCT or an expanded UDT that contained STRUCTs),
# recurse into them.
if var_info.children and not var_info.is_udt_expanded_member: # Recurse for normal structs
self._apply_current_values(var_info.children, begin_values, f"{full_member_path}.")
# For expanded UDT members (is_udt_expanded_member = True), their values are set directly,
# and if THEY had children (structs within the UDT def), those are part of the UDT expansion.
# The BEGIN block paths would typically be like "MyUdtInstance.StructInUdt.Member".
# This simplified _apply_current_values might need enhancement for complex paths into UDTs.
def parse_file(self, filepath: str) -> ParsedData:
try:
with open(filepath, 'r', encoding='utf-8-sig') as f:
lines = f.readlines()
except Exception as e:
print(f"Error reading file {filepath}: {e}")
return self.parsed_data
current_block_handler: Optional[Union[UdtInfo, DbInfo]] = None
active_block_context = OffsetContext()
idx = 0
while idx < len(lines):
original_line = lines[idx].strip()
line_to_parse = original_line
comment_marker_idx = original_line.find("//")
if comment_marker_idx != -1:
line_to_parse = original_line[:comment_marker_idx].strip()
# Top-level comments usually not stored with block definition
type_match = self.type_start_regex.match(line_to_parse)
db_match = self.db_start_regex.match(line_to_parse)
if type_match:
if current_block_handler: print(f"Warning: Starting new TYPE block for '{type_match.group(1)}' before previous block '{current_block_handler.name}' ended.")
udt_name = type_match.group(1)
current_block_handler = UdtInfo(name=udt_name)
self.parsed_data.udts.append(current_block_handler)
active_block_context = OffsetContext()
idx += 1; continue
elif db_match:
if current_block_handler: print(f"Warning: Starting new DATA_BLOCK for '{db_match.group(1)}' before previous block '{current_block_handler.name}' ended.")
db_name = db_match.group(1)
current_block_handler = DbInfo(name=db_name)
self.parsed_data.dbs.append(current_block_handler)
active_block_context = OffsetContext()
idx += 1; continue
if not current_block_handler:
idx += 1; continue
# Inside a UDT or DB block definition part (before BEGIN for DBs)
prop_match = self.property_regex.match(original_line) # Properties can have comments
struct_keyword_on_line = self.struct_start_regex.match(line_to_parse) # Check for "STRUCT" keyword line
if prop_match:
key, value = prop_match.group(1).upper(), prop_match.group(2).strip()
attr_name = key.lower()
if hasattr(current_block_handler, attr_name):
setattr(current_block_handler, attr_name, value)
elif struct_keyword_on_line and not current_block_handler.members: # Start of main STRUCT for UDT/DB
# The line 'STRUCT' itself is consumed. Parsing of members starts from the next line.
idx = self._parse_struct_members(
lines, idx + 1, # Start from line AFTER "STRUCT"
current_block_handler.members,
active_block_context,
is_top_level_struct_in_block=True
)
# idx is now the line number of BEGIN, END_TYPE, or END_DB
continue # Let the main loop handle this new line index
elif self.begin_regex.match(line_to_parse) and isinstance(current_block_handler, DbInfo):
# Finalize size from declaration part
current_block_handler.total_size_in_bytes = active_block_context.byte_offset
idx = self._parse_begin_block(lines, idx + 1, current_block_handler) # idx + 1 to start after BEGIN
# idx is now the line of END_DATA_BLOCK
continue
elif self.end_type_regex.match(line_to_parse) and isinstance(current_block_handler, UdtInfo):
if not hasattr(current_block_handler, 'total_size_in_bytes') or current_block_handler.total_size_in_bytes == 0:
current_block_handler.total_size_in_bytes = active_block_context.byte_offset # Size from declarations
self.known_udts[current_block_handler.name] = current_block_handler
print(f"Parsed UDT: {current_block_handler.name}, Size: {current_block_handler.total_size_in_bytes} bytes. Members: {len(current_block_handler.members)}")
current_block_handler = None
elif self.end_db_regex.match(line_to_parse) and isinstance(current_block_handler, DbInfo):
if not hasattr(current_block_handler, 'total_size_in_bytes') or current_block_handler.total_size_in_bytes == 0: # If no BEGIN block, size is from declarations
current_block_handler.total_size_in_bytes = active_block_context.byte_offset
self._apply_current_values(current_block_handler.members, current_block_handler._initial_values_from_begin_block)
print(f"Parsed DB: {current_block_handler.name}, Decl. Size: {current_block_handler.total_size_in_bytes} bytes. Members: {len(current_block_handler.members)}")
current_block_handler = None
idx += 1
return self.parsed_data
def custom_json_serializer(obj: Any) -> Any:
if isinstance(obj, OffsetContext): return None # Don't serialize OffsetContext
if hasattr(obj, '__dict__'):
# Filter out None values, empty lists, and specific private fields
d = {k: v for k, v in obj.__dict__.items()
if v is not None and \
not (isinstance(v, list) and not v) and \
k != '_initial_values_from_begin_block'}
# Ensure 'is_udt_expanded_member' is present even if False (unless explicitly None)
if isinstance(obj, VariableInfo):
if 'is_udt_expanded_member' not in d and obj.is_udt_expanded_member is False:
d['is_udt_expanded_member'] = False
# If it was True, it would already be in d or caught by the general v is not None
elif obj.is_udt_expanded_member is True:
d['is_udt_expanded_member'] = True
return d
raise TypeError(f"Object of type {obj.__class__.__name__} is not JSON serializable")
if __name__ == "__main__":
parser = S7Parser()
# IMPORTANT: Ensure this filepath points to your actual source file.
# The filename was changed to .txt for upload, adjust if your local file is .db
filepath = "db1001_format.db.txt" # Or "db1001_format.db" if that's the actual name
print(f"Attempting to parse: {filepath}")
parsed_result = parser.parse_file(filepath)
json_output_filename = "parsed_s7_data_expanded.json" # New output filename
print(f"\nParsing complete. Attempting to serialize to JSON.")
try:
json_output = json.dumps(parsed_result, default=custom_json_serializer, indent=2)
# print(json_output) # Optional: print to console for quick check
with open(json_output_filename, "w", encoding='utf-8') as f:
f.write(json_output)
print(f"Result saved to {json_output_filename}")
except Exception as e:
print(f"Error during JSON serialization or file writing: {e}")

View File

@ -0,0 +1,303 @@
import json
from typing import List, Dict, Any, Union
# Se asume que las dataclasses (VariableInfo, UdtInfo, etc.) del script x3.py
# estarían disponibles si este script fuera parte de un paquete más grande.
# Para este script independiente, trabajaremos directamente con los diccionarios del JSON.
def format_data_type_for_source(var_info: Dict[str, Any]) -> str:
"""Formatea la declaración de tipo completa para la variable en S7 source."""
base_type = var_info.get("udt_source_name") if var_info.get("udt_source_name") else var_info["data_type"]
type_str = ""
if var_info.get("array_dimensions"):
dims_str = ",".join([f"{d['lower_bound']}..{d['upper_bound']}" for d in var_info["array_dimensions"]])
type_str += f"ARRAY [{dims_str}] OF "
type_str += base_type
if var_info["data_type"].upper() == "STRING" and var_info.get("string_length") is not None:
type_str += f"[{var_info['string_length']}]"
return type_str
def generate_variable_declaration_for_source(var_info: Dict[str, Any], indent_level: int) -> str:
"""Genera una línea de declaración de variable S7."""
indent_str = " " * indent_level
type_declaration_str = format_data_type_for_source(var_info)
line = f'{indent_str}{var_info["name"]} : {type_declaration_str}'
if var_info.get("initial_value") is not None:
# Asegurarse de que los booleanos se escriban como TRUE/FALSE
initial_val = var_info["initial_value"]
if isinstance(initial_val, bool):
initial_val_str = "TRUE" if initial_val else "FALSE"
else:
initial_val_str = str(initial_val)
line += f' := {initial_val_str}'
line += ';'
if var_info.get("comment"):
line += f'\t// {var_info["comment"]}'
return line
def generate_struct_members_for_source(members: List[Dict[str, Any]], indent_level: int) -> List[str]:
"""Genera recursivamente las declaraciones de miembros para STRUCTs/UDTs."""
lines = []
for var_info in members:
# No expandir UDTs anidados dentro de la sección de declaración de otro UDT o DB.
# Solo declarar la variable del tipo UDT.
# La expansión de miembros de UDT solo ocurre en el JSON para análisis, no para la reconstrucción de la fuente.
if var_info.get("is_udt_expanded_member"): # Estos no se declaran individualmente en el padre.
continue
if var_info["data_type"].upper() == "STRUCT" and not var_info.get("udt_source_name"): # Es una definición de STRUCT anidada
current_indent_str = " " * indent_level
lines.append(f'{current_indent_str}{var_info["name"]} : STRUCT;')
if var_info.get("children"):
lines.extend(generate_struct_members_for_source(var_info["children"], indent_level + 1))
lines.append(f'{current_indent_str}END_STRUCT;')
else: # Variable primitiva, String, Array, o instancia de UDT
lines.append(generate_variable_declaration_for_source(var_info, indent_level))
return lines
def _generate_assignments_recursive(members: List[Dict[str, Any]], path_prefix: str, indent_str: str) -> List[str]:
"""Ayudante recursivo para generar asignaciones del bloque BEGIN."""
assignment_lines = []
for var_info in members:
# Construir la ruta actual para esta variable
current_member_name = var_info['name']
current_full_path = f"{path_prefix}{current_member_name}"
# Si es una instancia de UDT, sus 'children' en el JSON son los miembros expandidos.
# Necesitamos iterar sobre estos 'children' para obtener sus 'current_value'.
if var_info.get("udt_source_name") and var_info.get("children"):
# Para la instancia de UDT, recursivamente generar asignaciones para sus miembros.
# El prefijo de ruta para los miembros del UDT será el nombre de la instancia UDT seguido de un punto.
assignment_lines.extend(
_generate_assignments_recursive(var_info["children"], f"{current_full_path}.", indent_str)
)
# Si es un STRUCT definido inline (no una instancia de UDT)
elif var_info["data_type"].upper() == "STRUCT" and not var_info.get("udt_source_name") and var_info.get("children"):
assignment_lines.extend(
_generate_assignments_recursive(var_info["children"], f"{current_full_path}.", indent_str)
)
# Si es un miembro primitivo (o array/string que tiene un current_value directo)
# y tiene un 'current_value'. Los miembros expandidos de UDT (is_udt_expanded_member=True)
# tendrán su current_value y su current_full_path ya incluirá el nombre de la instancia UDT.
elif var_info.get("current_value") is not None:
val_str = var_info["current_value"]
if isinstance(val_str, bool): # Convertir booleanos de JSON a TRUE/FALSE de S7
val_str = "TRUE" if val_str else "FALSE"
assignment_lines.append(f"{indent_str}{current_full_path} := {val_str};")
return assignment_lines
# En x4.py
def generate_begin_block_assignments(db_info: Dict[str, Any], indent_level: int, parsed_json_udts: Dict[str, Dict[str, Any]]) -> List[str]:
indent_str = " " * indent_level
lines = []
# Utilizar directamente _initial_values_from_begin_block del JSON
# ¡ASEGÚRATE DE QUE x3.py INCLUYA ESTE CAMPO EN EL JSON!
begin_values_map = db_info.get("_initial_values_from_begin_block")
if begin_values_map and isinstance(begin_values_map, dict):
# Intentar un ordenamiento simple por clave para una salida más consistente,
# aunque el orden original del bloque BEGIN no se garantiza.
for path, value_str in sorted(begin_values_map.items()):
# Aquí, value_str ya es una cadena. Si necesitáramos convertir booleanos
# necesitaríamos información del tipo del 'path', lo cual es complejo aquí.
# Asumimos que x3.py guardó los valores en el formato correcto (ej. TRUE/FALSE para bools).
# Si x3.py guardó Python bools (true/false), necesitamos convertir.
# Para ser seguro, si el valor es "true" o "false" (strings), convertir.
# Esta conversión es una heurística. Sería mejor si x3.py ya los formateara.
final_value_str = str(value_str) # Asegurar que es string
if final_value_str.lower() == "true":
final_value_str = "TRUE"
elif final_value_str.lower() == "false":
final_value_str = "FALSE"
lines.append(f"{indent_str}{path} := {final_value_str};")
else:
# Fallback si _initial_values_from_begin_block no está o está mal formado.
# Este fallback ahora necesita ser más inteligente o se eliminará si el principal funciona.
# print(f"Advertencia: _initial_values_from_begin_block no encontrado o vacío para DB {db_info['name']}. Reconstrucción de BEGIN puede ser incompleta.")
# La función _generate_assignments_recursive anterior podría ser un fallback,
# pero depende de que los `current_value` de los elementos de array estén bien poblados.
# Si se implementa el `current_element_values` en `VariableInfo` en x3.py:
def generate_recursive_fallback(members, prefix, current_indent):
fallback_lines = []
for v_info in members:
m_name = v_info['name']
m_path = f"{prefix}{m_name}"
if v_info.get("current_element_values") and isinstance(v_info["current_element_values"], dict):
for index_str, val_str_el in sorted(v_info["current_element_values"].items()):
# index_str puede ser "1" o "1,2" etc.
el_path = f"{m_path}[{index_str}]"
f_val_str_el = str(val_str_el)
if f_val_str_el.lower() == "true": f_val_str_el = "TRUE"
elif f_val_str_el.lower() == "false": f_val_str_el = "FALSE"
fallback_lines.append(f"{current_indent}{el_path} := {f_val_str_el};")
elif v_info.get("udt_source_name") and v_info.get("children"):
fallback_lines.extend(generate_recursive_fallback(v_info["children"], f"{m_path}.", current_indent))
elif v_info.get("data_type", "").upper() == "STRUCT" and not v_info.get("udt_source_name") and v_info.get("children"):
fallback_lines.extend(generate_recursive_fallback(v_info["children"], f"{m_path}.", current_indent))
elif v_info.get("current_value") is not None:
val_str_cv = v_info["current_value"]
f_val_str_cv = str(val_str_cv)
if f_val_str_cv.lower() == "true": f_val_str_cv = "TRUE"
elif f_val_str_cv.lower() == "false": f_val_str_cv = "FALSE"
fallback_lines.append(f"{current_indent}{m_path} := {f_val_str_cv};")
return fallback_lines
lines.extend(generate_recursive_fallback(db_info.get("members", []), "", indent_str))
return lines
def generate_s7_source_code_lines(data: Dict[str, Any]) -> List[str]:
"""Genera el código fuente S7 completo (UDTs y DBs) a partir de los datos JSON."""
lines = []
# Generar UDTs
for udt in data.get("udts", []):
lines.append(f'TYPE "{udt["name"]}"')
if udt.get("family"): lines.append(f' FAMILY : {udt["family"]};')
if udt.get("version"): lines.append(f' VERSION : {udt["version"]};')
lines.append("") # Línea en blanco
lines.append(" STRUCT")
# Los miembros del UDT están directamente bajo 'members'
lines.extend(generate_struct_members_for_source(udt["members"], 2)) # Indentación 2 para miembros
lines.append(" END_STRUCT;")
lines.append(f'END_TYPE;')
lines.append("") # Línea en blanco después de cada UDT
# Generar DBs
for db in data.get("dbs", []):
lines.append(f'DATA_BLOCK "{db["name"]}"')
if db.get("title"): lines.append(f' TITLE = {db["title"]};') # Asumir que el título ya tiene el formato correcto
if db.get("family"): lines.append(f' FAMILY : {db["family"]};')
if db.get("version"): lines.append(f' VERSION : {db["version"]};')
lines.append("") # Línea en blanco
lines.append(" STRUCT")
lines.extend(generate_struct_members_for_source(db["members"], 2)) # Indentación 2 para miembros
lines.append(" END_STRUCT;")
# Generar bloque BEGIN si hay valores actuales (implicando que hubo un bloque BEGIN)
# La forma más fiable es chequear si hay current_values en los miembros.
# O, si el parser x3.py guardara una bandera explícita "has_begin_block".
# Por ahora, generaremos BEGIN si hay miembros, ya que las asignaciones se basan en current_value.
if db.get("members"): # Asumimos que si hay miembros, puede haber un bloque BEGIN.
lines.append("BEGIN")
lines.extend(generate_begin_block_assignments(db, 1)) # Indentación 1 para asignaciones
lines.append(f'END_DATA_BLOCK;')
lines.append("") # Línea en blanco después de cada DB
return lines
def generate_markdown_table(db_info: Dict[str, Any]) -> List[str]:
"""Genera una tabla Markdown para la documentación de un DB."""
lines = []
lines.append(f"# Documentación para DB: {db_info['name']}")
lines.append("")
lines.append("| Address | Name | Type | Initial Value | Actual Value | Comment |")
lines.append("|---|---|---|---|---|---|")
def flatten_members_for_markdown(members: List[Dict[str, Any]], prefix: str = "", base_offset: float = 0.0):
md_lines = []
for var in members:
if var.get("is_udt_expanded_member"): # No listar miembros expandidos como filas separadas de alto nivel aquí
continue
name = f"{prefix}{var['name']}"
# El offset en el JSON ya debería ser absoluto para los miembros del DB.
# Para miembros dentro de STRUCTs anidados, el JSON también debería tener offsets absolutos.
address = f"{var['byte_offset']:.1f}" if isinstance(var['byte_offset'], float) else str(var['byte_offset'])
if var.get("bit_size", 0) > 0 and isinstance(var['byte_offset'], float) and var['byte_offset'] != int(var['byte_offset']):
pass # El formato X.Y ya está bien para bools
elif var.get("bit_size", 0) > 0 : # bool en X.0
address = f"{int(var['byte_offset'])}.0"
data_type_str = format_data_type_for_source(var) # Usar la misma función de formato
initial_value = str(var.get("initial_value", ""))
actual_value = str(var.get("current_value", ""))
comment = str(var.get("comment", ""))
# Reemplazar pipes en los valores para no romper la tabla Markdown
initial_value = initial_value.replace("|", "\\|")
actual_value = actual_value.replace("|", "\\|")
comment = comment.replace("|", "\\|").replace("\n", " ")
md_lines.append(f"| {address} | {name} | {data_type_str} | {initial_value} | {actual_value} | {comment} |")
# Si es un STRUCT (no UDT) o un UDT, listar sus miembros constitutivos recursivamente para la documentación
if var.get("children"):
# Si es una instancia de UDT, los hijos son los miembros expandidos.
# Si es un STRUCT, los hijos son los miembros directos del STRUCT.
# El prefijo para los hijos debe ser el nombre completo del padre (STRUCT/UDT).
md_lines.extend(flatten_members_for_markdown(var["children"], f"{name}.", var['byte_offset']))
return md_lines
lines.extend(flatten_members_for_markdown(db_info.get("members", [])))
return lines
def main():
json_input_filename = "parsed_s7_data_expanded.json"
s7_output_filename = "reconstructed_s7_source_v2.txt" # Nuevo nombre para la salida S7
try:
with open(json_input_filename, 'r', encoding='utf-8') as f:
data_from_json = json.load(f)
except FileNotFoundError:
print(f"Error: No se encontró el archivo JSON de entrada: {json_input_filename}")
return
except json.JSONDecodeError:
print(f"Error: El archivo JSON de entrada no es válido: {json_input_filename}")
return
except Exception as e:
print(f"Error al leer el archivo JSON {json_input_filename}: {e}")
return
print(f"Archivo JSON '{json_input_filename}' cargado correctamente.")
# 1. Generar el archivo S7 reconstruido
s7_code_lines = generate_s7_source_code_lines(data_from_json)
try:
with open(s7_output_filename, 'w', encoding='utf-8') as f:
for line in s7_code_lines:
f.write(line + "\n")
print(f"Archivo S7 reconstruido generado: {s7_output_filename}")
except Exception as e:
print(f"Error al escribir el archivo S7 {s7_output_filename}: {e}")
# 2. Generar la documentación Markdown (para cada DB encontrado)
if data_from_json.get("dbs"):
for db_to_document in data_from_json["dbs"]:
db_name_safe = db_to_document['name'].replace('"', '').replace(' ', '_')
md_filename_specific = f"documentation_db_{db_name_safe}.md"
print(f"\nGenerando documentación Markdown para DB: {db_to_document['name']}...")
markdown_lines = generate_markdown_table(db_to_document)
try:
with open(md_filename_specific, 'w', encoding='utf-8') as f:
for line in markdown_lines:
f.write(line + "\n")
print(f"Archivo Markdown de documentación generado: {md_filename_specific}")
except Exception as e:
print(f"Error al escribir el archivo Markdown {md_filename_specific}: {e}")
else:
print("No se encontraron DBs en el archivo JSON para generar documentación.")
if __name__ == "__main__":
main()

View File

@ -1,10 +1,42 @@
[14:05:02] Iniciando ejecución de x4_prompt_generator.py en C:\Trabajo\SIDEL\06 - E5.007363 - Modifica O&U - SAE196 (cip integrato)\Reporte\TAGsIO\v2...
[14:05:03] Generador de prompt para adaptación de IO
[14:05:03] =========================================
[14:05:03] Usando directorio de trabajo: C:\Trabajo\SIDEL\06 - E5.007363 - Modifica O&U - SAE196 (cip integrato)\Reporte\TAGsIO\v2
[14:05:03] Usando ruta de Obsidian desde configuración: C:\Users\migue\OneDrive\Miguel\Obsidean\Trabajo\VM\04-SIDEL\00 - MASTER\MIXER\IO
[14:05:03] Usando carpeta de equivalencias en Obsidian: C:\Users\migue\OneDrive\Miguel\Obsidean\Trabajo\VM\04-SIDEL\00 - MASTER\MIXER\IO
[14:05:03] ¡Prompt generado y copiado al portapapeles con éxito!
[14:05:03] Prompt guardado en: C:\Trabajo\SIDEL\06 - E5.007363 - Modifica O&U - SAE196 (cip integrato)\Reporte\TAGsIO\v2\IO_Adaptation_Prompt.txt
[14:05:04] Ejecución de x4_prompt_generator.py finalizada (success). Duración: 0:00:01.643930.
[14:05:04] Log completo guardado en: d:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\IO_adaptation\log_x4_prompt_generator.txt
[20:15:59] Iniciando ejecución de x3.py en C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001...
[20:16:00] --- ERRORES ---
[20:16:00] 2025-05-16 20:16:00,228 - db_mapper - INFO - Iniciando mapeo de DBs por dirección absoluta
[20:16:00] 2025-05-16 20:16:00,309 - db_mapper - INFO - Directorio de trabajo: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001
[20:16:00] 2025-05-16 20:16:00,310 - db_mapper - INFO - Encontrados 3 archivos para procesar
[20:16:00] 2025-05-16 20:16:00,310 - db_mapper - INFO - Procesando: db1001_data.db
[20:16:00] 2025-05-16 20:16:00,310 - db_mapper - INFO - Procesando archivo: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_data.db
[20:16:00] 2025-05-16 20:16:00,310 - db_mapper - ERROR - Error procesando archivo C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_data.db: module 'DB_Parser' has no attribute 'parse_db_definition'
[20:16:00] Traceback (most recent call last):
[20:16:00] File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\S7_DB_Utils\x3.py", line 76, in process_db_file
[20:16:00] db_node, db_number, db_name, family, version = DB_Parser.parse_db_definition(db_content, udt_definitions)
[20:16:00] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[20:16:00] AttributeError: module 'DB_Parser' has no attribute 'parse_db_definition'
[20:16:00] 2025-05-16 20:16:00,312 - db_mapper - INFO - Procesando: db1001_format.db
[20:16:00] 2025-05-16 20:16:00,312 - db_mapper - INFO - Procesando archivo: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_format.db
[20:16:00] 2025-05-16 20:16:00,313 - db_mapper - ERROR - Error procesando archivo C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_format.db: module 'DB_Parser' has no attribute 'parse_udt_definition'
[20:16:00] Traceback (most recent call last):
[20:16:00] File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\S7_DB_Utils\x3.py", line 64, in process_db_file
[20:16:00] udt_name, udt_node = DB_Parser.parse_udt_definition(udt_content)
[20:16:00] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[20:16:00] AttributeError: module 'DB_Parser' has no attribute 'parse_udt_definition'
[20:16:00] 2025-05-16 20:16:00,316 - db_mapper - INFO - Procesando: db1001_format_updated.db
[20:16:00] 2025-05-16 20:16:00,316 - db_mapper - INFO - Procesando archivo: C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_format_updated.db
[20:16:00] 2025-05-16 20:16:00,316 - db_mapper - ERROR - Error procesando archivo C:\Trabajo\SIDEL\09 - SAE452 - Diet as Regular - San Giovanni in Bosco\Reporte\DB1001\db1001_format_updated.db: module 'DB_Parser' has no attribute 'parse_udt_definition'
[20:16:00] Traceback (most recent call last):
[20:16:00] File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\S7_DB_Utils\x3.py", line 64, in process_db_file
[20:16:00] udt_name, udt_node = DB_Parser.parse_udt_definition(udt_content)
[20:16:00] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[20:16:00] AttributeError: module 'DB_Parser' has no attribute 'parse_udt_definition'
[20:16:00] Traceback (most recent call last):
[20:16:00] File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\S7_DB_Utils\x3.py", line 444, in <module>
[20:16:00] main()
[20:16:00] File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\S7_DB_Utils\x3.py", line 430, in main
[20:16:00] processed_files, mapped_pairs = process_all_files_in_directory()
[20:16:00] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[20:16:00] File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\S7_DB_Utils\x3.py", line 372, in process_all_files_in_directory
[20:16:00] "timestamp": import_datetime().now().isoformat()
[20:16:00] ^^^^^^^^^^^^^^^^^^^^^
[20:16:00] AttributeError: module 'datetime' has no attribute 'now'
[20:16:00] --- FIN ERRORES ---
[20:16:00] Ejecución de x3.py finalizada (error). Duración: 0:00:00.897567. Se detectaron errores (ver log).
[20:16:00] Log completo guardado en: D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\S7_DB_Utils\log_x3.txt