Guías prácticas HMIx
Crea un tanque horizontal con SVG dinámico en WinCC Unified
Un tanque horizontal, un acabado metálico y un nivel que cambia con una variable. Aprende a construir este SVG dinámico y a probarlo en TIA Portal, sin JavaScript ni imágenes para cada estado.

Entorno de la guía: TIA Portal / WinCC Unified V21.1. Comprueba la importación y la ejecución del ejemplo en tu dispositivo de destino.
¿Qué es un SVG dinámico?
SVG describe una imagen mediante formas y líneas, en lugar de una cuadrícula fija de píxeles. Resulta útil para símbolos que deben verse nítidos a distintos tamaños: depósitos, válvulas, motores e indicadores.
Para un widget parametrizado de WinCC Unified se utiliza el formato .svghmi. Añade al dibujo una interfaz con parámetros, como FillLevel o un color. TIA Portal muestra esos parámetros y permite conectarlos a variables HMI. Un valor modifica el dibujo: no hacen falta 101 imágenes diferentes para un depósito de 0 a 100 %.
Un .svg normal se puede usar como gráfico, pero renombrarlo a .svghmi no añade una interfaz dinámica.
- Utiliza un SVG dinámico para niveles, estados de equipos, cambios de color o movimientos sencillos gobernados por valores.
- Elige un CWC si necesitas una interfaz web más completa, una tabla personalizada o varias interacciones.
- Empieza con un gráfico pequeño y sencillo para entender qué hace cada parámetro.
En HMIx puedes descargar cientos de recursos HMI gratuitos. Empieza con un control del catálogo o describe tu idea al generador de IA de HMIx para crear un recurso que puedas adaptar a tu proyecto.

Siemens · Gestión de gráficos SVG dinámicosSiemens · Formato SVG admitido y restricciones
Qué necesitas para la primera prueba
Utiliza un proyecto de prueba con un dispositivo Unified, una pantalla vacía y componentes compatibles de WinCC Unified Runtime o simulación. La guía sigue V21.1; otras ediciones de WinCC y versiones anteriores pueden variar.
- Para dibujarlo a mano, utiliza un editor vectorial como Inkscape y un editor de texto para añadir la interfaz HMI.
- Para probarlo directamente, descarga nuestro pequeño ejemplo .svghmi más abajo. No necesitas un PLC.
- Utiliza formas y efectos compatibles con WinCC Unified. Que un SVG se vea bien en el navegador no garantiza que todos sus elementos funcionen en el dispositivo HMI.
Dibuja un tanque horizontal con un solo parámetro
El tanque combina una silueta redondeada, dos soportes y degradados que le dan aspecto metálico. El líquido es un rectángulo independiente que queda recortado dentro del tanque. Solo cambia un parámetro: FillLevel, de 0 a 100.
Dibuja las partes fijas
Dibuja el cuerpo horizontal, los soportes y la boca superior. Define un viewBox de 400 × 250. Dentro de un clipPath coloca la silueta del tanque: servirá para que el líquido no sobresalga de los extremos redondeados.
Añade la interfaz HMI
En un editor de texto, añade los espacios de nombres HMI de Siemens y una sección hmi:self. Define FillLevel con hmi:paramDef, tipo number y valor inicial 50. Nuestro archivo completo ya contiene esa estructura.
Enlaza la forma del líquido
Relaciona hmi-bind:height y hmi-bind:y con ParamProps.FillLevel. Al aumentar la altura del rectángulo, su borde superior sube y el fondo permanece fijo. El clipPath contiene el líquido y Converter.Bounds limita la representación a 0–100.
Guarda como .svghmi
Guarda el XML en UTF-8 con la extensión exacta .svghmi, no .svghmi.txt. Conserva una copia editable. Tras añadir los enlaces HMI, evita guardarlo de nuevo con un editor vectorial genérico que pueda eliminar los atributos de Siemens.
Aquí FillLevel indica el porcentaje de altura del líquido. En un tanque horizontal no equivale, en general, al porcentaje de volumen. Para mostrar litros o volumen hace falta una conversión acorde con la geometría del depósito.
Archivo .svghmi completo con el parámetro FillLevel (0–100). Estructura XML y expresiones comprobadas; valida la importación en WinCC Unified V21.1.
Ver el código del ejemplo
Opcional: la descarga contiene el ejemplo completo. No necesitas escribir este código para seguir la prueba.
HmixHorizontalTank.svghmi
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//SIEMENS//DTD SVG 1.0 TIA-HMI//EN" "http://svg.siemens.com/hmi/svg10-hmi.dtd">
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:hmi-bind--xlink="http://svg.siemens.com/hmi/bind/xlink/"
xmlns:hmi="http://svg.siemens.com/hmi/"
xmlns:hmi-bind="http://svg.siemens.com/hmi/bind/"
xmlns:hmi-element="http://svg.siemens.com/hmi/element/"
xmlns:hmi-feature="http://svg.siemens.com/hmi/feature/"
xmlns:hmi-event="http://svg.siemens.com/hmi/event/"
width="400" height="250" viewBox="0 0 400 250" preserveAspectRatio="xMidYMid meet">
<hmi:self type="widget" displayName="HMIx Horizontal Tank"
name="extended.HmixHorizontalTank" version="1.0.0">
<hmi:paramDef name="FillLevel" type="number" default="50" />
</hmi:self>
<defs>
<hmi:localDef name="SafeLevel" type="number"
hmi-bind:value="{{ Converter.Bounds(ParamProps.FillLevel, 0, 100) }}" />
<linearGradient id="steel" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#7f949f" />
<stop offset="0.28" stop-color="#edf3f5" />
<stop offset="0.52" stop-color="#bdcbd1" />
<stop offset="1" stop-color="#667d88" />
</linearGradient>
<linearGradient id="water" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#4cc4df" />
<stop offset="1" stop-color="#176184" />
</linearGradient>
<clipPath id="inside"><rect x="40" y="60" width="320" height="120" rx="60" /></clipPath>
</defs>
<!-- One parameter changes liquid height, not volume percentage. -->
<path d="M100 170L90 220H130L120 170M280 170L270 220H310L300 170" fill="#405866" stroke="#273d49" stroke-width="2" />
<path d="M86 224H134M266 224H314" stroke="#607987" stroke-width="8" />
<rect x="180" y="43" width="40" height="17" rx="3" fill="url(#steel)" stroke="#546e7a" />
<rect x="175" y="54" width="50" height="8" rx="2" fill="#adbec7" stroke="#546e7a" />
<rect x="40" y="60" width="320" height="120" rx="60" fill="url(#steel)" />
<g clip-path="url(#inside)">
<rect id="liquid" x="40" y="120" width="320" height="60" fill="url(#water)"
hmi-bind:height="{{ LocalProps.SafeLevel * 1.2 }}"
hmi-bind:y="{{ 180 - LocalProps.SafeLevel * 1.2 }}" />
<path d="M120 60V180M280 60V180" stroke="#254b60" stroke-opacity="0.22" stroke-width="2" />
<path d="M55 78H345" stroke="#ffffff" stroke-opacity="0.28" stroke-width="8" />
</g>
<rect x="40" y="60" width="320" height="120" rx="60" fill="none" stroke="#546e7a" stroke-width="2" />
<rect x="354" y="109" width="14" height="28" rx="2" fill="url(#steel)" stroke="#546e7a" />
<path d="M369 115V131" stroke="#8ea5b1" stroke-width="6" />
</svg>
Cárgalo como widget dinámico en TIA Portal
Coloca el archivo en el proyecto
Abre la carpeta del proyecto y crea UserFiles\SVGControls si hace falta. Copia allí HmixHorizontalTank.svghmi. En este procedimiento debe estar el archivo .svghmi, no un ZIP.
Abre Widgets dinámicos
Abre la pantalla Unified y accede a Herramientas → Widgets dinámicos (Tools → Dynamic widgets). Actualiza la paleta al añadir o modificar el archivo; si el archivo nuevo no aparece, vuelve a abrir el proyecto.
Insértalo y revísalo
Arrastra HMIx Horizontal Tank a la pantalla. En sus propiedades, localiza el parámetro de usuario FillLevel y asigna el valor estático 50. Comprueba que el dibujo aparece antes de enlazar una variable.
Para este archivo utiliza Widgets dinámicos. Importar un SVG normal a la colección de gráficos es otro procedimiento y no crea estos parámetros.
Siemens · Gestión de gráficos SVG dinámicosSiemens · Actualización de SVG dinámicos
Haz que el nivel cambie en Runtime
Crea un valor interno
Añade una variable HMI interna llamada TankLevel, de un tipo numérico como Real y sin conexión a PLC. Es el valor que cambiarás a mano.
Conecta el parámetro
Selecciona el depósito, configura la dinamización del parámetro FillLevel como Variable y elige TankLevel. El nombre del parámetro pertenece al SVG; el de la variable pertenece a tu proyecto HMI.
Añade un campo E/S numérico
Colócalo junto al gráfico, selecciona el modo entrada/salida y enlaza su valor de proceso a la misma TankLevel. Configura límites de entrada de 0 y 100 cuando estén disponibles.
Compila y prueba tres valores
Establece esta pantalla como inicial, compila la HMI e inicia su simulación compatible o el Runtime Unified PC de prueba. Abre el cliente Runtime, inicia sesión si se solicita e introduce 0, 50 y 100 en el campo E/S. Confirma cada entrada y observa el líquido.
Comprueba tamaño y reapertura
Vuelve a abrir la pantalla para verificar el valor actual. Prueba también otra instancia a diferente tamaño: el contorno debe mantenerse nítido y el líquido dentro del depósito.
El deslizador de abajo ilustra el resultado esperado. Es independiente de TIA Portal y no se comunica con tu proyecto.
Primero, observa qué debería ocurrir
Mueve el deslizador: el líquido sube dentro de la silueta del tanque. FillLevel representa la altura, no el volumen.
La prueba funciona cuando…
Con 0, el tanque está vacío; con 50, el líquido llega a media altura; con 100, hasta arriba. El líquido permanece dentro del contorno y coincide con el campo E/S al volver a abrir la pantalla.
Problemas habituales y comprobaciones sencillas
- No aparece en Widgets dinámicos: revisa UserFiles\SVGControls, la extensión real, la sintaxis XML y la interfaz HMI; después actualiza la paleta.
- El depósito aparece pero no se llena: comprueba que el archivo contiene enlaces HMI y que FillLevel usa la misma variable que el campo E/S.
- El nivel crece hacia abajo: la posición superior del líquido debe variar a la vez que su altura. Nuestro ejemplo mantiene fijo el fondo.
- Se ve diferente al editor vectorial: simplifica efectos no admitidos, CSS y dependencias de fuentes. Comprueba el dispositivo de destino, además de la vista previa del navegador.
- Una actualización pierde un enlace: cambiar nombres, eliminar parámetros o modificar sus tipos puede romper las instancias. Conserva la interfaz o reconfigura las instancias afectadas.
Cuando funcione el ejemplo directamente en pantalla, puedes explorar los tipos de SVG dinámico de biblioteca para reutilizarlos en pantallas y faceplates. Es un siguiente paso útil, no un requisito para empezar.
Siemens · Actualización de SVG dinámicosSiemens · SVG dinámicos como tipos de biblioteca
Preguntas frecuentes
¿Un SVG es dinámico automáticamente en Unified?
No. Un SVG estático contiene un dibujo. Un .svghmi parametrizado también necesita la interfaz de Siemens y sus enlaces. Cambiar únicamente la extensión no basta.
¿Necesito JavaScript para este depósito?
No. El llenado utiliza expresiones dentro del SVGHMI y el enlace a una variable en TIA Portal. Para interacciones más elaboradas puede resultar más cómodo un CWC.
¿Sirve el mismo archivo para todas las ediciones de WinCC?
No lo des por hecho. Selecciona el destino correcto en HMIx y revisa la compatibilidad del recurso. Este recorrido es para WinCC Unified; las versiones y las demás ediciones de WinCC tienen sus propias limitaciones.