HMIx practical guides

How to create a dynamic SVG (SVGHMI) for WinCC Unified & V8: step-by-step guide, by hand or with AI

A dynamic SVG (.svghmi file) is a vector drawing that changes its appearance with a screen value: a tank that fills, a valve that changes color… In this guide you will adapt a real horizontal tank, import it into TIA Portal and watch the liquid rise and fall in Runtime, without a PLC. At the end you will see how to create your own dynamic SVGs with the HMIx AI generator.

HMIx team12 min read · 20 min hands-onReviewed
  • Siemens
  • Dynamic SVG
  • SVGHMI
  • Dynamic widgets
  • WinCC Unified
  • WinCC V8
  • TIA Portal
  • AI
  • AI generator
Start the guide
Horizontal steel tank next to a graphic showing liquid at half height
Editorial illustration created with AI for HMIx. The guide's tank shows its level with a simple drawing that changes with a screen value.

The whole path at a glance

  1. Download HmixHorizontalTank.svghmi and open it in a text editor
  2. Change the initial value of FillLevel
  3. Copy it to the project's UserFiles\SVGControls
  4. Drag it from Dynamic widgets onto the screen
  5. Bind FillLevel to the TankLevel tag and test in Runtime

What you need

  • TIA Portal with WinCC Unified (here, V21.1) and its simulation or Unified PC Runtime
  • A text editor, such as Visual Studio Code or Notepad++
  • Nothing else: no PLC, no JavaScript, no drawing software
Short on time? Create it with AI

Preparing the files is the same for WinCC Unified and WinCC V8. The import and test steps are shown in TIA Portal / WinCC Unified V21.1. In WinCC V8 you work with Graphics Designer: check the functions available in your installation.

01

What a dynamic SVG (SVGHMI) is and what it is for

Think of a tank drawn on a machine screen. A normal image always shows the same level. A dynamic SVG lets the liquid rise and fall with a number, using the same drawing. It also helps to show whether a valve is open, change a motor's color or show a part only when needed.

SVG is an image format made of shapes and lines, so it can be enlarged without becoming pixelated. For WinCC Unified to change parts of the drawing, the file declares inputs called parameters and is saved with the .svghmi extension. In TIA Portal it appears in the Dynamic widgets pane.

A parameter is a setting the author makes available. In this tank it is called FillLevel and takes a number from 0 to 100: at 50, the liquid reaches half height. Later you will connect it to TankLevel, an HMI tag: the place where the project stores the number you type. They have different names because one belongs to the drawing and the other to the project.

The same drawing can show different states

Change the level

A number from 0 to 100 decides how high the liquid is drawn.

FillLevel = 25

FillLevel = 75

Change a color

A color parameter can change the fill, for example to tell two liquids apart.

Liquid A color

Liquid B color

Show or hide a part

A visibility parameter can show or hide the tank's connections.

With connections

Without connections

This guide's download only includes FillLevel. The tank published in the catalog also has color and visibility parameters. The available parameters depend on how each resource was built.

Each resource has its own parameters. This guide's download includes only FillLevel. The color and visibility examples in the diagram show other possibilities of dynamic SVGs; they are not settings of this file.

On HMIx you can download hundreds of free HMI resources. Start with a control from the catalog or describe your idea to the HMIx AI generator to create a resource you can adapt to your project.

HMIx catalog Horizontal Tank resource, with a metal body, supports and blue liquid
This Horizontal Tank is published on HMIx and offers level, color and fittings-visibility settings: FillLevel, LiquidColor, BasicColor, SaddleColor and ShowFittings. This guide's download is a separate teaching version with a single parameter, FillLevel, so the first test is easy to follow. See this resource on HMIx

Siemens · Creating dynamic SVG graphics (109782045)Siemens · Managing dynamic SVG graphicsSiemens · SVGHMI graphics in WinCC V8

02

Prepare the file and a test screen (5 minutes)

You need TIA Portal with WinCC Unified (the steps are shown in V21.1) and its simulation or Unified PC Runtime, the program that runs the screen. You will use an internal tag, which lives inside the HMI, so no PLC is needed.

Turn on file name extensions in Windows (File Explorer → View → Show → File name extensions). That way you can see whether the file really ends in .svghmi and not .svghmi.txt, the most common mistake when saving it.

The file we will use

Download this starting point to follow the guide with the same names and values.

Download the tank to follow the guide

A single HmixHorizontalTank.svghmi file, with FillLevel from 0 to 100 and an initial value of 50. Structure and calculations reviewed; import and execution in WinCC Unified V21.1 must be checked in your environment.

  1. Where · File Explorer → working folder

    Download the tank and keep a working copy

    Download HmixHorizontalTank.svghmi with the button in this section. It is a single file: there is nothing to unzip. Keep the original and copy the file into a folder called MyTank. Open the copy with a text editor such as Visual Studio Code or Notepad++ (right-click → Open with). You will see text, because the drawing is described with editable instructions.

    Check: You have MyTank\HmixHorizontalTank.svghmi open in the editor.

  2. Where · TIA Portal → Unified device → Screens

    Prepare the screen where you will place it

    Open or create a test project with a WinCC Unified device. Create an empty screen called TestTank and save the project. Note where its folder is: by default, Documents\Automation\<ProjectName>.

    Check: You have the drawing file in the editor and the TestTank screen in TIA Portal, and you know where the project folder is.

Before you continue

You can find the downloaded file, the empty screen and the project folder. You do not need to create tags yet.

Siemens · Supported SVG format and restrictions

03

Create your variant: understand the drawing and change its initial level

The tank has three parts: a fixed body, a blue rectangle that represents the liquid and a clip with the tank's inner shape. The clip works like a stencil: it hides anything that sticks out. When the level changes, only the visible part of the liquid changes.

If you draw a resource from scratch, first create the parts in a vector editor and save it as SVG; then add the HMI part (parameters and bindings) with a text editor, as in this example. Renaming an .svg to .svghmi does not make it dynamic. Here the parts are already drawn and you will adapt their behavior.

  1. Where · Text editor → search (Ctrl+F) for id="liquid"

    Find the part that will change

    Search for id="liquid": it is the rectangle that represents the liquid. The body and the supports are on other lines and do not change. The group that contains it uses clip-path, the clip that keeps the blue inside the rounded outline.

    How the tank is built in layers

    1. Fixed drawing

      The body, supports and connections do not change when the level rises.

    2. Liquid rectangle

      Its height and the position of its top edge change. The bottom stays in place.

    3. Inner clip

      Only shows the liquid inside the tank's rounded outline.

    The layers form a single graphic

    FillLevel = 50

    The liquid reaches half height and is clipped at the ends. The body and supports keep their shape.

    FillLevel represents the liquid's height: 50 means half the inner height. In a horizontal tank, height and volume are not linearly related.

    Check: You know which part is the liquid and why it can grow without leaving the tank.

  2. Where · Text editor → search for hmi:paramDef

    Find the parameter and change its initial value

    Near the top, inside <hmi:self>, is the line that declares FillLevel. type="number" says it receives a number and default="50" sets its initial value. Change only default="50" to default="25". Do not change the name FillLevel: it is the one you will see in TIA Portal.

    Check: Your variant makes every new tank start at 25 % height instead of the original 50 %.

  3. Where · Text editor → back to id="liquid"

    Follow the link between the number and the liquid

    The rectangle has two bindings: hmi-bind:height changes the liquid's height and hmi-bind:y moves its top edge; together they keep the bottom fixed. Both use SafeLevel, a value calculated in hmi:localDef with Converter.Bounds, which keeps FillLevel between 0 and 100. So even if 140 or −20 arrives, the liquid never leaves the tank. Do not touch these lines.

    Check: You understand the whole path: the parameter receives a number and the bindings turn it into a visible height.

  4. Where · Text editor → Save

    Save the file with its full extension

    Save the changes (Ctrl+S) with UTF-8 encoding, keeping the name HmixHorizontalTank.svghmi. Check in File Explorer that it does not end in .svghmi.txt. Do not open or save this file with a generic drawing program: it could remove the hmi: and hmi-bind: attributes that make it dynamic.

    Check: You have an .svghmi with the drawing, its parameter and the bindings between them, ready for TIA Portal.

In this example the percentage expresses the liquid's height. In a horizontal tank, 25 % of the height is not 25 % of the volume: showing liters would need a conversion based on the tank's geometry.

View the example code

Optional: the download contains the complete example. You do not need to write this code to follow the test.

HmixHorizontalTank.svghmi

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//SIEMENS//DTD SVG 1.0 TIA-HMI//EN" "http://tia.siemens.com/graphics/svg/1.8/dtd/svg18-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>

Before you continue

You changed only one thing: the initial value of FillLevel, from 50 to 25. The file name and the parameter name are unchanged.

Siemens · Creating dynamic SVG graphics (109782045)

04

Import the dynamic SVG into TIA Portal

TIA Portal looks for each project's dynamic SVGs in a specific folder and shows them in the Dynamic widgets pane, from where you drag them onto the screen.

  1. Where · File Explorer → your TIA project folder

    Copy the file into the project folder

    In the project folder, go into UserFiles (create it if it does not exist). Inside, create SVGControls if it does not exist yet and copy your modified file there. The destination is the project folder, not the Siemens installation folder.

    Where to save the tank file

    Inside your project folder

    • Your project/
      • UserFiles/
        • SVGControls/
          • HmixHorizontalTank.svghmi

    Create SVGControls if it does not exist yet and copy the file here.

    Then, in the screen editor

    Refresh the Dynamic widgets pane in the Tools task card and drag the tank onto a screen of the Unified device.

    Keep the full name and extension: HmixHorizontalTank.svghmi. A dynamic SVG is copied as a single file, without a ZIP.

    Check: The path ends in UserFiles\SVGControls\HmixHorizontalTank.svghmi.

  2. Where · TIA Portal → TestTank → Tools → Dynamic widgets

    Refresh the pane and drag the tank

    With the screen open, expand Dynamic widgets in the Tools task card and click its refresh button. Look for the tank — it is listed as HMIx Horizontal Tank or by its file name, HmixHorizontalTank — and drag it onto the screen. If it does not appear, check the path from the previous step before continuing.

    Check: You have a tank instance on TestTank.

  3. Where · Selected tank → Inspector window → Properties

    Check the parameter before binding it

    With the tank selected, find FillLevel among its properties (you can type it into the Inspector window's search box). Its initial value should be 25 if you made the change, or 50 if you imported the original. Type a fixed value of 50 and confirm: the liquid should sit at half height in the screen editor.

    Check: The drawing responds to a fixed value: the file works before you add any tag.

Before you continue

You see the tank and can find FillLevel in its properties. If that parameter is missing, check the file before moving on to the dynamic test.

Siemens · Managing dynamic SVG graphicsSiemens · Updating dynamic SVGs

05

Bind a tag and make the tank fill in Runtime

So far the level was a fixed value. Now you will connect it to a tag you can change while the screen runs: an I/O (input/output) field writes to TankLevel and the tank reads the same tag through FillLevel. No JavaScript needed.

First, see what should happen

Try the level here before configuring it in TIA Portal: move the slider and see how only the liquid's height changes.

50%
Interactive explanation for this guide. It is not a WinCC Runtime session.
  1. Where · TIA Portal → Unified device → HMI tags

    Create the tag that stores the level

    Open the default tag table and add TankLevel. In the Connection column choose Internal tag and pick a numeric data type, for example Real.

    Check: Your project has the TankLevel tag; the SVG file still has the FillLevel parameter.

  2. Where · TestTank → selected tank → FillLevel property

    Bind the tank parameter to that tag

    In the Dynamization column of FillLevel, choose Tag and select TankLevel. This replaces the fixed value 50 with the tag's current value.

    From the number you type to the level you see

    1. You type 50 in the I/O field

      Value
      50

      The input/output field lets you enter a number during the test.

    2. The HMI tag stores 50

      TankLevel
      50

      TankLevel is an internal tag. You can test it without connecting a PLC.

    3. The FillLevel parameter receives 50

      FillLevel
      50

      In the tank's properties, bind FillLevel to TankLevel.

    4. The liquid reaches half height

      50%

      Then try 0 and 100 to check both ends.

    The I/O field and FillLevel share the TankLevel tag. When you change the field in Runtime, the tank receives the new value and changes the liquid's height.

    Check: FillLevel takes its value from TankLevel.

  3. Where · Tools → Elements → I/O field

    Add a field to type the level

    Drag an I/O field next to the tank. Choose the Input/output mode and connect its Process value to TankLevel, the same tag. If you like, add the text “Level, 0–100 %” next to it.

    Check: The tank and the numeric field both use TankLevel, so the number you type will show in the drawing.

  4. Where · TIA Portal → project tree → HMI device

    Compile, open Runtime and test 0, 50 and 100

    Right-click TestTank and choose Define as start screen. Compile the HMI device (right-click → Compile → Software), fix any errors and click Start simulation or download to your Unified PC Runtime. Log in to the web client with a project user (if you have none, create one in Security settings → Users and roles with an HMI role and compile again). Type 0 in the I/O field and press Enter; repeat with 50 and 100.

    Check: At 0 no liquid is visible, at 50 it reaches half height and at 100 it fills the inside. The outline and supports do not move.

The slider on this page only illustrates the expected behavior. It does not control your TIA Portal project or replace the Runtime test.

Before you continue

The I/O field and the tank show the same level. Reload the client page (F5) and check that the drawing still reflects the current value of TankLevel.

06

If something does not match: symptoms and fixes

  • It does not appear in Dynamic widgets: check that the file is in UserFiles\SVGControls of the open project and ends in .svghmi (not .svghmi.txt). Click refresh in the pane; if it still does not appear, compare the start of the file with the original download.
  • The tank appears but you cannot find FillLevel: check that you inserted it from Dynamic widgets. An SVG imported as a normal graphic has no parameters.
  • The fixed value works but the I/O field does not move the liquid: check that the field and FillLevel use the same TankLevel tag and that the field is in Input/output mode. Confirm each number with Enter.
  • You cannot log in to Runtime: the client asks for a project user. Create one in Security settings → Users and roles with an HMI role, compile and download again.
  • You do not see your change from 50 to 25: check which copy you saved in SVGControls. Refresh the pane and try a new instance: an existing instance keeps the value it already had.
  • It looks different than in the browser: WinCC Unified supports a subset of SVG. Use supported shapes and effects and check the result on the target device.

Once this test works, you can extend your SVG with color (HmiColor) or visibility (boolean) parameters. To reuse it in faceplates, see Siemens' procedure for creating a dynamic SVG type in a library.

Siemens · Updating dynamic SVGsSiemens · Supported SVG format and restrictionsSiemens · Dynamic SVGs as library types

07

Shortcut: create your dynamic SVGs with AI

Drawing industrial equipment and writing its hmi-bind bindings by hand takes time. The HMIx AI generator (ai.hmix.tech) creates dynamic SVGs for WinCC Unified and V8 from a description or a reference image: it draws the symbol or the equipment, proposes the parameters (level, colors, visibility, rotation) and generates the .svghmi file. You can start for free with the Community plan.

What you learned here still applies: importing from UserFiles\SVGControls, binding parameters to tags and testing in Runtime are identical.

  1. Where · ai.hmix.tech → Dynamic SVG

    Describe the graphic you need

    State the equipment, the view and the states, for example: “Horizontal stainless-steel tank, front view, liquid level 0–100 % and configurable liquid color”. Choose whether you want a schematic (P&ID) symbol or detailed equipment.

    Check: The AI draws a first version that you can refine in the chat or the vector editor.

  2. Where · Generator → definition and simulation steps

    Review the parameters and the simulation

    Check the proposed parameters (for example, a level like FillLevel) and move them in the simulation to confirm that the liquid rises from the bottom and stays inside the outline.

    Check: The drawing responds in the simulation as you expect.

  3. Where · Generator → generation and installation step

    Download the .svghmi file

    Download the generated .svghmi. It is a single file, like this guide's.

    Check: You have an .svghmi ready to copy to UserFiles\SVGControls.

  4. Where · TIA Portal → Dynamic widgets

    Import and test it as here

    Follow “Import the dynamic SVG into TIA Portal” and “Bind a tag” using your parameters' names.

    Check: Your AI-generated SVG changes in Runtime with your tags.

On the free plan, generated resources are published in the HMIx catalog so other users can use them too; paid plans let you keep them private.

Before you continue

AI speeds up the drawing and the bindings; it does not replace testing. Always validate the result in Runtime and on the target device.

Frequently asked questions

What is the difference between FillLevel and TankLevel?

FillLevel is the parameter defined inside the drawing (hmi:paramDef). TankLevel is the tag that stores the number in your HMI project. When you bind them in TIA Portal, the drawing receives that number and changes the liquid's height.

Can I change the color from this example's properties?

This download only exposes FillLevel; its colors are fixed inside the file. To change them from TIA Portal you would add an HmiColor parameter and bind it to the fill with Converter.RGBA, choose a catalog resource that already includes it, or generate it with HMIx AI.

Is it enough to rename an SVG to .svghmi?

No. The file must declare the parameters (hmi:paramDef inside hmi:self) and the hmi-bind bindings that link them to the drawing. The downloadable example already contains both.

Can I create a dynamic SVG with AI?

Yes. The HMIx AI generator (ai.hmix.tech) creates dynamic SVGs (.svghmi) for WinCC Unified and V8 from a description or an image: drawing, parameters and bindings. You then import and test it as this guide explains.

Do I need a PLC or JavaScript?

Not for this test. The level is stored in an internal HMI tag and the expressions inside the SVG change the drawing. You do need TIA Portal with WinCC Unified and its simulation or Unified PC Runtime.

Sources and further reading