El objetivo de este artículo es proveer de una alternativa para poder enviar alarmas de WinCC mediante Whatsapp, de forma que cuando en nuestro sistema de control se dispare dicha alarma, se envíe el texto de la alarma a un grupo de Whatsapp.
La utilidad de esta solución, es poder alertar a los usuarios del sistema (mantenimiento, producción, etc.) a tiempo y mediante un canal muy utilizado. En este ejemplo lo mandaremos a un grupo, aunque es igual de aplicable a personas físicas.
Existen diversas formas de hacerlo, en mi caso he optado por NO usar la API de Whatsapp business, ya que presenta mayor complejidad y costes añadidos. Se ha utilizado el manejo del navegador y la librería pywhatkit.
Índice
Arquitectura

Elementos:
- WinCC V8 Runtime corriendo en una maquina virtual (VM 1) con IP 192.168.18.88
- Servidor Flask, en otra máquina (VM 2), para escucha de mensajes y envío por Whatsap, con IP 192.168.18.77 y puerto 5000
- Teléfono emisor: necesario asociar un teléfono a la cuenta del servidor Flask, ya que será quien envíe los mensajes. Solo necesario escanear QR primera vez.
- Grupo de Whatsapp: será al grupo al que enviaremos el mensaje de alarma de Wincc.
Notas: como se observa en la imagen, VM1 no tiene conexión a internet y queda aislado, simulando una red OT protegida. Comunica con VM2 por red local, emulando la DMZ, y es esta quien sí puede comunicarse con el exterior.
Configuración Servidor Flask
Un servidor Flask es una aplicación web ligera escrita en Python que permite crear y servir páginas web o APIs de forma sencilla y rápida.
En este ejemplo se usa para estar a la escucha de solicitudes POST desde el SCADA WinCC. Una vez que recibe dicha solicitud, con el mensaje de la alarma en un JSON, ejecuta mediante Pywhatkit un manejo del navegador que abre la aplicación de Whatsapp (previamente autenticada, con un teléfono de emisor).
Pywhatkit se encarga de abrir sesión, localizar el grupo de Whatsapp (con su ID; ver en enlace de invitación), y escribir el mensaje que ha recibido del sistema SCADA.
Los pasos para dejar este servicio escuchando, son como en cualquier otra aplicación Flask. Primero un entorno VENV con las librerías necesarias, activarlo y ejecutarlo con “python app.py”
Este servicio, debe estar siempre disponible y activo para recibir y procesar las solicitudes de WinCC. En artículos posteriores veremos como podemos embeberlo en un Docker.
Configuración WinCC
Una vez tenemos el servidor preparado a la escucha, y con Whatsapp autenticado, pasamos a preparar nuestro SCADA para que sea capaz de extraer el texto de la alarma y luego enviarla cuando esta sea disparada.
Extracción texto alarma con GMsgFunction y MSRTGetMsgText
Aunque parece trivial, no es sencillo el poder extraer el texto de una alarma cuando esta se dispara, ya que hay que usar varias funciones para obtenerlo y realizar configuraciones, veámoslo:
Paso 1: Configurar la acción de la alarma. Hay que marcar la opción de “Activar una acción“, “Loop in alarm” y asignar la función “GMsgFunction“, que es la que se ejecuta cuando la alarma se dispara.

Paso 2: Modificar GMsgFunction para que al dispararse la alarma, recoja sus parámetros incluído el texto de la alarma. La función esta en C, y viene ya preparada para traer algunos datos de la alarma como Timestamp, ID, y otros, pero NO EL TEXTO.

Para obtener el texto de la alarma, hay que usar otra función que pasándole como parámetro el objeto alarma, y apuntando al campo correcto, se trae el texto del mensaje. Os dejo aquí el código:
Con esto ya tenemos el texto de la alarma, cuando se dispara, guardado en “AlarmText”.

Envío de texto alarma a servidor Flask
Ahora ya con la alarma guardada, solo queda realizar la petición al servidor Flask para que la envíe por Whatsapp. Para ello lo he hecho con VBS. como se puede ver, recogeremos el texto de la variable “AlarmText” y lo enviamos al servidor IP=192.168.18.77:5000/wincc
Sub EnviarTextoAServidor()
Dim http
Dim url
Dim data
Dim mensaje
Dim mensajeAlarma
mensajeAlarma = HMIRuntime.Tags("AlarmText").Read(1)
HMIRuntime.Trace mensajeAlarma
' Definir el mensaje a enviar (puedes reemplazarlo por una variable dinámica)
mensaje = mensajeAlarma
' Crear el objeto XMLHTTP para enviar la solicitud
Set http = CreateObject("MSXML2.XMLHTTP")
' Dirección del servidor Flask
url = "http://192.168.18.77:5000/wincc"
' Abrir la conexión de tipo POST
http.Open "POST", url, False
' Configurar la cabecera para enviar datos como JSON
http.setRequestHeader "Content-Type", "application/json"
' Crear el JSON con el mensaje
data = "{""mensaje"":""" & mensaje & """}"
' Enviar los datos
http.send data
' Leer la respuesta del servidor
Dim response
response = http.responseText
MsgBox "Respuesta del servidor: " & response
' Liberar objeto
Set http = Nothing
End Sub
Y ahora te preguntarás: ¿Y cuando se ejecuta esta función? Existen muchas formas de hacerlo, al final lo que necesitamos es que cuando la alarma se dispare, se ejecute. En mi caso y a modo de ejemplo, he asociado el texto de alarma a un Campo de texto, y cuando este varía, ejecuta el script.


Demostración
PLC: Hacemos saltar la alarma

WinCC: La alarma se dispara en SCADA y se guarda el texto de la misma en el textbox.

Servidor Flask + Navegador: recibe alarma y envía por whatsapp mediante el manejo del navegador.

MessageBox en SCADA confirmando el envío:

Conclusiones
Es posible el envío de alarmas con Whatsapp sin usar APIs y con coste mínimo. Esto puede ser de mucha utilidad para ciertos usuarios de los sistemas industriales, en los que ciertas alarmas críticas, necesitan ser monitorizadas en tiempo real.
El método usado para el envío de Whatsapp requiere de un número de teléfono para asociar la cuenta de Whatsapp que realiza los envíos, típicamente podría ser una cuenta básica de mantenimiento.
Se ha aislado completamente la funcionalidad, del SCADA. Quedando el sistema de control perfectamente aislado en la red OT sin necesidad de tener internet y exponerse.
La obtención del texto de alarma en WinCC no es trivial, y se ha proporcionado una forma de hacerlo genérica y escalable.