Desde hace tiempo vengo experimentando una dificultad que parece ser una constante en este sector: la regular calidad de la documentación que entregan nuestros clientes al iniciar nuestros proyectos de automatización.
No sé si les pasa, pero en mi caso, es común recibir diagramas eléctricos, listado de equipos, diagramas de distribución de tableros y listados de señales incompletos. En muchos casos, suelo encontrar listas sin etiquetas (tags) donde solo es visible la descripción funcional, pero no un identificador claro. Aunque trabajar bajo estas condiciones es poco óptimo, como desarrolladores de proyectos de automatización, a menudo nos vemos obligados a adaptarnos a estas circunstancias y empezar un largo y tedioso trabajo manual.
En esta ocasión y para este proyecto que estoy desarrollando, recibí un amplio listado de señales para el control de tres arrancadores suaves destinados a bombas de extracción de agua de unos pozos. Como es sabido en este sector en el que usted y yo trabajamos, existe una gran cantidad de variables que intervienen para el control de motores, ya sea cuando se usan arrancadores suaves, variadores de velocidad o un sencillo arranque directo a través de contactores. Las señales de tipo booleano como: estados de marcha y paro, fallas térmicas o modos de operación (local/remoto) son fundamentales, sin contar con otras que pueden estar presentes dependiendo del tipo de aplicación. Por ello, lograr gestionar un número elevado de motores implica un manejo masivo de señales que debe procesarse con mucho cuidado.
Para ilustrar este escenario, observemos en la siguiente imagen algunas de las señales utilizadas en el control de un arrancador suave para nuestra «Bomba 1».

Ahora, imaginemos que tenemos veinte Bombas y cada una cuenta con la misma cantidad de datos. Supongamos el peor escenario: el cliente solicita un cambio de última hora y requiere que, en lugar de «Bomba», toda la nomenclatura pase a ser «Unidad». Es aquí donde comienza el verdadero dolor de cabeza.
¿Cómo podemos ejecutar este cambio sin que esto suponga un trauma o una pérdida excesiva de tiempo? Incluso, partiendo de una sola unidad ya creada, ¿cómo podemos generar las demás de forma automatizada y organizada? bueno, he encontrado una forma y quiero compartirla con ustedes.
¿Cómo automatizar tareas repetitivas en TIA Portal?
Bien, existen muchas vías y creo que la más idónea para este tipo de actividades se llama TIA Portal Openness. Pero en esta oportunidad no nos vamos a centrar en esta herramienta; vamos a utilizar unas vías alternativas, usando algo de la inteligencia artificial de Google Gemini, la función Version Control Interface de TIA Portal y Python.
¿Qué vamos a necesitar para este ejercicio?
- TIA Portal desde la versión 16 en adelante. En mi caso, estoy usando la versión 20.
- Un proyecto en TIA Portal con rutinas de función (FC), bloques de función (FB) y bloques de datos (DB).
- Python
- Cualquier herramienta de inteligencia artificial para la generación de scripts en Python. En mi caso, haré uso de Google Gemini
Desarrollo de automatización de flujos de trabajo en TIA Portal
A continuación, expongo la situación que queremos resolver mediante las herramientas mencionadas. Como se observa, contamos con una función (FC) denominada «1. Entradas Digitales Bombas». En su interior, existen bloques de función (FB) llamados «Sensores DI», los cuales están vinculados o instanciados a cada señal del arrancador suave de la «Bomba 1».
En la sección izquierda, dentro de la carpeta «1. DB’s Bomba 1», se encuentran todos los bloques de datos (DB) asociados a cada bloque de función (FB) que hemos creado dentro de nuestra función (FC) «2. Entradas Digitales Bombas».

1. Exportar los bloques de datos DB
Para editar los bloques de datos (DB) de forma masiva e incorporarlos a nuestro proyecto de TIA Portal con sus nuevos nombres, el primer paso consiste en exportar los bloques DB existentes a nuestro computador siguiendo este procedimiento: seleccione los bloques de datos, haga clic derecho sobre ellos y elija la opción Generate source from blocks > Selected blocks only.

Posteriormente, guardamos el archivo generado en cualquier carpeta de nuestro computador, en mi caso, la guardé en una carpeta que he creado llamada Workspace Bombas.

Después de haber guardado nuestro archivo exportado, procedemos a abrirlo con un editor de texto en este caso, yo usé Notepad++.
Con el archivo abierto, el siguiente paso consiste en utilizar la función «Buscar y reemplazar» o «Sustituir» para localizar todas las instancias del texto que se llamen «Bomba 1» y las vamos a cambiar por «Unidad 1».

Con esto realizado, copiaremos todo el contenido del texto inicial y lo pegaremos al final del archivo. ¿Cuál es el propósito? la idea es duplicar los bloques de datos (DB) para las nuevas unidades. Entonces lo que queremos es cambiar el texto a Unidad 2 y Unidad 3.

Con los cambios realizados, procedemos a guardar nuestro archivo sin cambiarle la extensión.

Con el archivo editado y guardado, volvemos a TIA Portal y ahora nos desplazamos hasta la sección External Source File e importamos el que guardamos previamente.

Ya con el archivo importado en TIA Portal, hacemos clic derecho sobre este y ahora vamos a Generate blocks from source y esperamos a que el proceso finalice.

Con el proceso finalizado, ahora podremos ver todos los nuevos bloques de datos en nuestro proyecto de TIA Portal renombrados de Bomba a Unidad y adicionados, Unidad 2 y Unidad 3.

2. Exportar el bloque FC
Ahora, la idea es exportar nuestro bloque FC, pero en esta ocasión, lastimosamente no podemos efectuar el mismo procedimiento del paso anterior de usar la función Generate source from blocks.

Lamentablemente, este procedimiento no se puede replicar para bloques FC ni FB, a menos que estén desarrollados en STL (lista de instrucciones) o SCL (texto estructurado). Dado que en nuestro caso fueron desarrollados en Ladder (KOP), la única vía consiste en exportar el bloque a un archivo .XML mediante la herramienta u opción Version Control Interface (VCI), de la cual hablaremos a continuación.
3. Configuración de la interfaz de control de versiones dentro de TIA Portal
Antes de proceder, es importante conocer qué es Version Control Interface. La definición de Siemens, es la siguiente: «la interfaz de control de versiones de TIA Portal nos permite conectar un programa de control de versiones externo a TIA Portal. Esta es una manera sencilla de intercambiar los datos de su proyecto con su programa de control de versiones preferido. Para ello, defina uno o más directorios en su PC como espacios de trabajo. Luego, tanto el programa de control de versiones como el Portal TIA acceden a estos espacios de trabajo. Por lo tanto, TIA Portal no interactúa directamente con el programa de control de versiones».
«Los símbolos en el Portal TIA indican si los objetos de un espacio de trabajo son idénticos a los objetos del Portal TIA o si existen diferencias. En caso de diferencias, puede ejecutar la sincronización entre el espacio de trabajo y el Portal TIA. Los objetos del Portal TIA en el espacio de trabajo se pueden versionar a través del servidor de administración de versiones».
Para añadir un nuevo espacio de trabajo, solo basta con ir a Version Control Interface y hacer doble clic sobre Add new workspace.

Al añadir un Workspace en la interfaz de control de versiones, se despliegan dos columnas: Project, que hace referencia a todos los elementos del proyecto en desarrollo, y Workspace, el cual todavía no hemos configurado.

Al hacer clic en el icono Configure Workplace, se nos despliega la siguiente ventana emergente la cual vamos a configurar de la siguiente forma:

Workspace path: Ruta donde se alojarán nuestro archivo .XML que vamos a exportar e importar
Version Control Add-in: Lo dejamos por defecto
Import Add-in: Lo dejamos por defecto
Path offset: Ruta dentro de nuestro proyecto de TIA Portal sobre el cual queremos trabajar.

Una vez finalizadas las configuraciones, el espacio de trabajo se presentará de la siguiente manera: en la sección Project se visualizarán los parámetros definidos en Path Offset, mientras que en el panel derecho, bajo Workspace Path, se mostrará la ruta local del equipo destinada al almacenamiento de los archivos de importación y exportación.

La siguiente tarea consiste en trasladar o arrastrar el bloque 1. Entradas Digitales Bombas que está en la columna proyecto hacia la carpeta correspondiente dentro del espacio de trabajo (Workspace). Una vez finalizada la transferencia, el sistema desplegará una ventana de confirmación indicando que el proceso ha concluido satisfactoriamente.

Con el proceso finalizado, al revisar la carpeta que hemos configurado en Workspace path, veremos nuestra rutina 1. Entradas Digitales Bombas en formato .XML.

4. El turno de Google Gemini
El siguiente paso fue adjuntar mi archivo .XML a mi chat y realicé la siguiente solicitud:
«Necesito editar el contenido de este archivo .XML con las siguientes condiciones:
1. Editar el nombre que dice Bomba 1 por Unidad 1.
2. Cuando esté adicionada la Unidad 1, replicar todo el contenido para adicionar Bomba 2 y Bomba 3.
3. Brindarme el script de Python para hacer la respectiva edición.»

El script que fue generado por Google Gemini fue el siguiente:
import re
import os
# Rutas de entrada y salida
ruta_entrada = r"C:\Users\CristianMartinez\Documents\Siemens\Bombas\Workspace Bombas\1. Entradas Digitales Bombas.xml"
ruta_salida = r"C:\Users\CristianMartinez\Documents\Siemens\Bombas\Workspace Bombas\3. Entradas Unidades 1_2_3.xml"
def generar_multiples_unidades():
print("--- INICIANDO PASO 2: DUPLICACIÓN ---")
if not os.path.exists(ruta_entrada):
print(f"ERROR: No encuentro el archivo original en:\n{ruta_entrada}")
return
# Leer el archivo completo
with open(ruta_entrada, 'r', encoding='utf-8') as archivo:
contenido = archivo.read()
print("1. Archivo leído. Aislando las redes (Networks)...")
# Encontrar dónde empiezan y terminan los bloques de redes (CompileUnits)
patron_redes = re.compile(r'(<SW\.Blocks\.CompileUnit.*?</SW\.Blocks\.CompileUnit>)', re.DOTALL)
matches = list(patron_redes.finditer(contenido))
if not matches:
print("ERROR: No se encontraron redes en el archivo.")
return
inicio_redes = matches[0].start()
fin_redes = matches[-1].end()
# Extraer todas las redes originales juntas
bloque_original = contenido[inicio_redes:fin_redes]
print("2. Creando bloques para Unidad 1, Unidad 2 y Unidad 3...")
# Transformar a Unidad 1
bloque_u1 = bloque_original.replace("Bomba 1", "Unidad 1").replace("bomba 1", "unidad 1")
# Clonar y transformar a Unidad 2 y 3 basándonos en la Unidad 1
bloque_u2 = bloque_u1.replace("Unidad 1", "Unidad 2").replace("unidad 1", "unidad 2")
bloque_u3 = bloque_u1.replace("Unidad 1", "Unidad 3").replace("unidad 1", "unidad 3")
# Unir las tres unidades una debajo de otra
todas_las_redes = bloque_u1 + '\n\n' + bloque_u2 + '\n\n' + bloque_u3
# Insertar el gran bloque de redes en el esqueleto del archivo original
contenido_nuevo = contenido[:inicio_redes] + todas_las_redes + contenido[fin_redes:]
print("3. Regenerando IDs hexadecimales para TIA Portal...")
# Función para reasignar IDs y evitar errores de colisión en TIA Portal
contador_id = 0
def reasignar_id(match):
nonlocal contador_id
nuevo_id = hex(contador_id)[2:].upper() # Convierte a Hexadecimal sin el '0x'
contador_id += 1
return f'ID="{nuevo_id}"'
# Busca cualquier etiqueta ID="X" y la reemplaza por el nuevo contador
contenido_final = re.sub(r'ID="[A-Fa-f0-9]+"', reasignar_id, contenido_nuevo)
print("4. Guardando el archivo final...")
with open(ruta_salida, 'w', encoding='utf-8') as archivo_salida:
archivo_salida.write(contenido_final)
print("--- ¡ÉXITO! ---")
print(f"El archivo listo para importar se guardó en:\n{ruta_salida}")
# Ejecutar el script
generar_multiples_unidades()5. Python en acción
Con el script de Python generado por Google Gemini, el siguiente paso fue instalar Python en mi ordenador. Tras abrir el IDLE Shell 3.14.3 que fue instalado, lo que hice fue crear un nuevo archivo.

Para crear el archivo, simplemente hice clic en File / New File y, una vez generado, pegué el script proporcionado por Gemini en el campo de texto, tal como se aprecia en la siguiente imagen:

Con el Script añadido, hice clic en File / Save As / y guardé ese archivo de extensión .py en la carpeta o ruta donde tengo el archivo .XML que fue exportado usando Version Control Interface (ver paso 3).

Tras guardar el archivo, lo siguiente que hice fue ejecutar el Script, haciendo clic en el menú Run / Run Module.

Y luego, tras finalizar el proceso, se me informa que el archivo con extensión .XML quedó guardado en la ruta que he definido.

Como el archivo nuevo quedó exportado con el nombre 3. Entradas Unidades 1_2_3.XML y yo lo necesito con el nombre Entradas Digitales Bombas.xml, entonces lo que hice fue eliminar el archivo inicial y lo reemplacé por este nuevo que ya incluye los nombres actualizados de la «Unidad 1», así como las nuevas «Unidad 2» y «Unidad 3».
6. Importando la nueva versión a TIA Portal con VCI
A continuación, regresamos a la Version Control Interface. Allí ya será visible el nuevo archivo .XML, el cual debemos importar desde el Workspace como se observa en la siguiente imagen, haciendo clic derecho sobre nuestra función FC y luego en Import from workspace.

Finalizado ese proceso, al revisar nuestra función (FC) 1. Entradas Digitales Bombas, encontraremos que se han creado los distintos bloques de función renombrados y con las nuevas unidades, Unidad 2 y Unidad 3 y de esta forma hemos realizado nuestro trabajo sin tanto esfuerzo manual.

Entiendo perfectamente que si es la primera vez que se está familiarizando con TIA Portal, este tipo de actividades pueden resultar un poco confusas, sin embargo, he tratado de hacer de este procedimiento lo más claro y descriptivo posible.
Para finalizar, este texto ha sido pensado, desarrollado y redactado por un humano, ¿Le ha parecido de utilidad? Qué tal si conversamos, debatimos y encontramos nuevas formas de hacer nuestro trabajo más ágil.


