HMIx 实用指南
如何为 WinCC Unified & V8 创建动态 SVG(SVGHMI):手动或借助 AI 的分步指南
动态 SVG(.svghmi 文件)是一种会随画面中的数值改变外观的矢量图:会充满的储罐、会变色的阀门……在本指南中,你将改造一个真实的卧式储罐,把它导入 TIA Portal,并在 Runtime 中看到液体升降,无需 PLC。最后,你还会看到如何使用 HMIx AI 生成器创建你自己的动态 SVG。
- Siemens
- 动态 SVG
- SVGHMI
- 动态微件
- WinCC Unified
- WinCC V8
- TIA Portal
- AI
- AI 生成器

完整流程一览
- 下载
HmixHorizontalTank.svghmi并在文本编辑器中打开 - 修改
FillLevel的初始值 - 复制到项目的
UserFiles\SVGControls中 - 从动态微件(Dynamic widgets)拖到画面上
- 将
FillLevel连接到变量TankLevel,并在 Runtime 中测试
你需要准备
- 带有 WinCC Unified 的 TIA Portal(本文为 V21.1),以及其仿真或 Unified PC Runtime
- 一个文本编辑器,例如 Visual Studio Code 或 Notepad++
- 其他什么都不需要:无需 PLC、JavaScript 或绘图软件
WinCC Unified 与 WinCC V8 的文件准备方式相同。导入和测试步骤以 TIA Portal / WinCC Unified V21.1 为例。在 WinCC V8 中使用 Graphics Designer 操作:请确认你的安装环境中可用的功能。
什么是动态 SVG(SVGHMI),它有什么用
想象机器画面上画着一个储罐。普通图片总是显示同一个液位;动态 SVG 则能在使用同一幅图的同时,让液体随一个数字升高或降低。它还可以显示阀门是否打开、改变电机的颜色,或只在需要时显示某个部件。
SVG 是一种由形状和线条组成的图像格式,因此放大后不会出现像素化。为了让 WinCC Unified 改变图形的某些部分,文件需要声明称为“参数”的输入,并以 .svghmi 扩展名保存。在 TIA Portal 中,它会出现在“动态微件”(Dynamic widgets)窗格中。
参数是作者开放出来的一项设置。在这个储罐中,它叫 FillLevel,接收 0 到 100 的数字:为 50 时,液体到达一半高度。稍后你会把它连接到 HMI 变量 TankLevel,也就是项目中保存你所输入数字的地方。两者名称不同,因为一个属于图形,另一个属于项目。
同一幅图可以显示不同状态
改变液位
用 0 到 100 的数字决定液体画到多高。
FillLevel = 25
FillLevel = 75
改变颜色
颜色参数可以改变填充色,例如用来区分两种液体。
液体 A 的颜色
液体 B 的颜色
显示或隐藏某个部件
可见性参数可以显示或隐藏储罐的接管。
带接管
不带接管
每个资源都有自己的参数。本指南的下载文件只包含 FillLevel。示意图中的颜色和可见性示例展示的是动态 SVG 的其他可能用法,并不是这个文件的设置项。
在 HMIx 上,你可以下载数百种免费的 HMI 资源。可以从目录中的现成控件开始,也可以向 HMIx AI 生成器描述你的想法,创建一个可以根据项目调整的资源。

Siemens · 创建动态 SVG 图形(109782045)Siemens · 管理动态 SVG 图形Siemens · WinCC V8 中的 SVGHMI 图形
准备文件和测试画面(5 分钟)
你需要带有 WinCC Unified 的 TIA Portal(步骤以 V21.1 为例),以及其仿真或 Unified PC Runtime,也就是运行画面的程序。你将使用存在于 HMI 内部的内部变量,因此不需要 PLC。
请在 Windows 中打开文件扩展名显示(文件资源管理器 → 查看 → 显示 → 文件扩展名)。这样你就能看清文件是否真的以 .svghmi 结尾,而不是 .svghmi.txt——这是保存时最常见的错误。
本指南要用的文件
下载这份基础示例,即可使用与指南相同的名称和数值跟着操作。
下载储罐,跟着指南操作单个 HmixHorizontalTank.svghmi 文件,FillLevel 范围为 0 到 100,初始值为 50。结构和计算已经过检查;在 WinCC Unified V21.1 中的导入和运行情况请在你的环境中确认。
操作位置 · 文件资源管理器 → 工作文件夹
下载储罐并保留一份工作副本
使用本节的按钮下载
HmixHorizontalTank.svghmi。它是单个文件:不需要解压。保留原文件,把文件复制到名为MyTank的文件夹中。用 Visual Studio Code 或 Notepad++ 等文本编辑器打开副本(右键 → 打开方式)。你会看到文字,因为这幅图是用可编辑的指令描述的。检查结果: 你已在编辑器中打开
MyTank\HmixHorizontalTank.svghmi。操作位置 · TIA Portal → Unified 设备 → 画面(Screens)
准备放置储罐的画面
打开或新建一个包含 WinCC Unified 设备的测试项目。新建一张名为
TestTank的空白画面,然后保存项目。记下项目文件夹的位置:默认为文档\Automation\<项目名称>。检查结果: 图形文件已在编辑器中打开,TIA Portal 中有
TestTank画面,并且你知道项目文件夹在哪里。
继续之前
你能找到下载的文件、空白画面和项目文件夹。现在还不需要创建变量。
制作你的版本:看懂图形并修改初始液位
储罐由三部分组成:固定不变的罐体、表示液体的蓝色矩形,以及与储罐内部形状一致的裁剪区域。裁剪区域就像一张模板:超出的部分都会被遮住。液位变化时,只有液体的可见部分发生变化。
如果从零开始绘制资源,先在矢量编辑器中画出各个部件并保存为 SVG;然后像本例一样,用文本编辑器加入 HMI 部分(参数和绑定)。把 .svg 重命名为 .svghmi 并不能让它变成动态图形。在这里,各个部件已经画好,你只需调整它们的行为。
操作位置 · 文本编辑器 → 搜索(Ctrl+F)
id="liquid"找到会变化的部分
搜索
id="liquid":这就是表示液体的矩形。罐体和支架写在其他行中,保持不变。包含它的分组使用了clip-path,也就是让蓝色保持在圆角轮廓之内的裁剪区域。储罐如何分层构建
固定图形
液位升高时,罐体、支架和接管不会变化。
液体矩形
它的高度和上边缘位置会变化,底部保持不动。
内部裁剪区域
只显示储罐圆角轮廓以内的液体。
各层组成一个图形
FillLevel = 50
液体到达一半高度,并在两端被裁剪。罐体和支架保持原有形状。
FillLevel 表示液体高度:50 表示内部高度的一半。在卧式储罐中,高度与容积不是线性关系。 检查结果: 你知道哪个部分是液体,以及它为什么能升高而不超出储罐。
操作位置 · 文本编辑器 → 搜索
hmi:paramDef找到参数并修改初始值
在文件开头附近、
<hmi:self>内部,有一行声明了FillLevel。type="number"表示它接收一个数字,default="50"设定其初始值。只把default="50"改为default="25"。不要修改FillLevel这个名称:你在 TIA Portal 中看到的就是它。检查结果: 你的版本会让每个新储罐从 25% 高度开始,而不是原来的 50%。
操作位置 · 文本编辑器 → 回到
id="liquid"理清数字与液体之间的联系
这个矩形有两个绑定:
hmi-bind:height改变液体高度,hmi-bind:y移动其上边缘;两者配合使底部保持固定。它们都使用SafeLevel,这是在hmi:localDef中通过Converter.Bounds计算出的值,会把FillLevel限制在 0 到 100 之间。因此,即使传入 140 或 −20,液体也不会超出储罐。不要改动这些行。检查结果: 你理解了完整的路径:参数接收一个数字,绑定把它转换成可见的高度。
操作位置 · 文本编辑器 → 保存
以完整扩展名保存文件
以 UTF-8 编码保存修改(Ctrl+S),保持文件名为
HmixHorizontalTank.svghmi。在文件资源管理器中检查它不是以.svghmi.txt结尾。不要用通用绘图程序打开或保存这个文件:它可能会删除让图形变为动态的hmi:和hmi-bind:属性。检查结果: 你得到一个包含图形、参数以及二者之间绑定的
.svghmi文件,可以用于 TIA Portal 了。
在本例中,百分比表示液体的高度。对于卧式储罐,25% 的高度并不等于 25% 的容积:如果要显示升数,需要根据储罐的几何形状进行换算。
查看示例代码
可选:下载文件已包含完整示例。按照本指南测试时,无需自己编写这些代码。
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>
继续之前
你只修改了一处:FillLevel 的初始值,从 50 改为 25。文件名和参数名称都保持不变。
将动态 SVG 导入 TIA Portal
TIA Portal 会在特定文件夹中查找每个项目的动态 SVG,并将它们显示在“动态微件”(Dynamic widgets)窗格中,你可以从那里把它们拖到画面上。
操作位置 · 文件资源管理器 → 你的 TIA 项目文件夹
把文件复制到项目文件夹
在项目文件夹中进入
UserFiles(如果不存在,就新建)。在其中新建SVGControls(如果还不存在),并把修改后的文件复制进去。目标位置是项目文件夹,而不是 Siemens 的安装文件夹。储罐文件保存在哪里
在你的项目文件夹内
你的项目/UserFiles/SVGControls/HmixHorizontalTank.svghmi
如果 SVGControls 还不存在,请先创建,再把文件复制到这里。
然后,在画面编辑器中
在工具(Tools)任务卡中刷新“动态微件”窗格,把储罐拖到 Unified 设备的画面上。
保留完整的文件名和扩展名:HmixHorizontalTank.svghmi。动态 SVG 以单个文件的形式复制,不需要 ZIP。 检查结果: 路径末尾为
UserFiles\SVGControls\HmixHorizontalTank.svghmi。操作位置 · TIA Portal →
TestTank→ 工具 → 动态微件(Dynamic widgets)刷新窗格并拖入储罐
在画面打开的状态下,展开工具(Tools)任务卡中的“动态微件”,点击其刷新按钮。找到储罐——它显示为 HMIx Horizontal Tank,或显示为文件名 HmixHorizontalTank——然后把它拖到画面上。如果没有出现,请先检查上一步的路径再继续。
检查结果:
TestTank上有一个储罐实例。操作位置 · 选中的储罐 → 巡视窗口(Inspector window)→ 属性
绑定之前先检查参数
选中储罐后,在其属性中找到
FillLevel(可以在巡视窗口的搜索框中输入它)。如果你做了修改,初始值应为 25;如果导入的是原文件,则为 50。输入固定值 50 并确认:在画面编辑器中,液体应位于一半高度。检查结果: 图形能响应固定值:在添加任何变量之前,文件就已经能正常工作。
继续之前
你能看到储罐,并能在其属性中找到 FillLevel。如果缺少这个参数,请先检查文件,再进行动态测试。
绑定变量,让储罐在 Runtime 中注满
到目前为止,液位还是一个固定值。现在你要把它连接到一个可在画面运行时修改的变量:I/O(输入/输出)域写入 TankLevel,储罐则通过 FillLevel 读取同一个变量。不需要 JavaScript。
先看看预期效果
在 TIA Portal 中配置之前,先在这里试试液位:移动滑块,观察只有液体高度发生变化。
操作位置 · TIA Portal → Unified 设备 → HMI 变量
创建保存液位的变量
打开默认变量表,添加
TankLevel。在“连接”列中选择“内部变量”,并选择数值数据类型,例如Real。检查结果: 项目中有了变量
TankLevel;SVG 文件中仍然是参数FillLevel。操作位置 ·
TestTank→ 选中的储罐 →FillLevel属性把储罐参数绑定到该变量
在
FillLevel的“动态化”列中,选择“变量”(Tag),然后选择TankLevel。这样就用变量的当前值替换了固定值 50。从你输入的数字到你看到的液位
在 I/O 域中输入 50
- 数值
- 50
输入/输出域让你在测试时输入数字。
HMI 变量保存 50
- TankLevel
- 50
TankLevel 是内部变量。不连接 PLC 也能测试。
FillLevel 参数收到 50
- FillLevel
- 50
在储罐属性中,将 FillLevel 绑定到 TankLevel。
液体到达一半高度
50%
然后试试 0 和 100,检查两个极端情况。
I/O 域和 FillLevel 共用变量 TankLevel。在 Runtime 中修改该域时,储罐会收到新数值并改变液体高度。 检查结果:
FillLevel从TankLevel获取数值。操作位置 · 工具 → 元素 → I/O 域(I/O field)
添加一个输入液位的域
把一个 I/O 域拖到储罐旁边。选择“输入/输出”模式,并将其过程值连接到同一个变量
TankLevel。如果愿意,可以在旁边添加文字“液位,0–100%”。检查结果: 储罐和数值输入域都使用
TankLevel,因此你输入的数字会体现在图形中。操作位置 · TIA Portal → 项目树 → HMI 设备
编译、打开 Runtime,并测试 0、50 和 100
右键点击
TestTank,选择“设置为起始画面”(Define as start screen)。编译 HMI 设备(右键 → 编译 → 软件),修正出现的错误,然后点击“启动仿真”,或下载到你的 Unified PC Runtime。使用项目用户登录 Web 客户端(如果还没有用户,请在“安全设置 → 用户和角色”中创建一个带 HMI 角色的用户,然后重新编译)。在 I/O 域中输入 0 并按 Enter;再依次输入 50 和 100。检查结果: 为 0 时看不到液体,为 50 时液体到达一半高度,为 100 时充满内部。轮廓和支架保持不动。
本页上的滑块仅用于演示预期效果。它不能控制你的 TIA Portal 项目,也不能代替 Runtime 中的测试。
继续之前
I/O 域和储罐显示相同的液位。刷新客户端页面(F5),检查图形仍然反映 TankLevel 的当前值。
结果不一致时:症状与解决方法
- “动态微件”中没有出现: 检查文件是否位于当前打开项目的
UserFiles\SVGControls中,并以.svghmi结尾(而不是.svghmi.txt)。在窗格中点击刷新;如果仍未出现,请将文件开头与原始下载文件进行比较。 - 能看到储罐,但找不到
FillLevel: 确认你是从“动态微件”插入的。作为普通图形导入的 SVG 没有参数。 - 固定值有效,但 I/O 域无法改变液体: 检查该域和
FillLevel是否使用同一个变量TankLevel,以及该域是否为“输入/输出”模式。每个数字都要按 Enter 确认。 - 无法登录 Runtime: 客户端要求使用项目用户。在“安全设置 → 用户和角色”中创建一个带 HMI 角色的用户,然后重新编译并下载。
- 看不到从 50 改为 25 的效果: 检查
SVGControls中保存的是哪一份副本。刷新窗格并插入一个新实例测试:已有实例会保留它原来的值。 - 显示效果与浏览器中不同: WinCC Unified 只支持 SVG 的一个子集。请使用受支持的形状和效果,并在目标设备上检查结果。
这个测试成功后,你可以为 SVG 添加颜色(HmiColor)或可见性(boolean)参数。如果想在面板(faceplate)中复用它,请参阅 Siemens 关于在库中创建动态 SVG 类型的步骤。
Siemens · 更新动态 SVGSiemens · 支持的 SVG 格式与限制Siemens · 将动态 SVG 用作库类型
捷径:用 AI 创建你的动态 SVG
手工绘制工业设备并编写其 hmi-bind 绑定需要花费时间。HMIx AI 生成器(ai.hmix.tech)可根据描述或参考图片,为 WinCC Unified 和 V8 创建动态 SVG:它会绘制符号或设备,提出参数建议(液位、颜色、可见性、旋转),并生成 .svghmi 文件。你可以通过 Community 套餐免费开始。
你在这里学到的内容依然适用:从 UserFiles\SVGControls 导入、将参数绑定到变量以及在 Runtime 中测试的方式完全相同。
操作位置 · ai.hmix.tech → 动态 SVG
描述你需要的图形
说明设备、视角和状态,例如:“卧式不锈钢储罐,正视图,液位 0–100%,液体颜色可配置”。选择你需要的是示意(P&ID)符号还是精细的设备图。
检查结果: AI 绘制出第一个版本,你可以在聊天或矢量编辑器中继续完善。
操作位置 · 生成器 → 定义与仿真步骤
检查参数和仿真
检查建议的参数(例如类似
FillLevel的液位参数),并在仿真中调整它们,确认液体从底部升起并保持在轮廓之内。检查结果: 图形在仿真中的反应符合你的预期。
操作位置 · 生成器 → 生成与安装步骤
下载 .svghmi 文件
下载生成的
.svghmi。它和本指南的文件一样,是单个文件。检查结果: 你得到一个可直接复制到
UserFiles\SVGControls的.svghmi。操作位置 · TIA Portal → 动态微件(Dynamic widgets)
按本指南的方法导入并测试
使用你的参数名称,按照“将动态 SVG 导入 TIA Portal”和“绑定变量”两节操作。
检查结果: AI 生成的 SVG 在 Runtime 中随你的变量变化。
在免费套餐中,生成的资源会发布到 HMIx 目录,供其他用户使用;付费套餐可以将其设为私有。
继续之前
AI 能加快绘图和绑定的速度,但不能代替测试。务必在 Runtime 和目标设备上验证结果。
常见问题
FillLevel 和 TankLevel 有什么区别?
FillLevel 是在图形内部定义的参数(hmi:paramDef)。TankLevel 是在 HMI 项目中保存数字的变量。在 TIA Portal 中把它们绑定后,图形就会接收这个数字并改变液体高度。
可以通过这个示例的属性修改颜色吗?
这个下载文件只开放了 FillLevel;其颜色固定在文件内部。如果要在 TIA Portal 中修改颜色,可以添加一个 HmiColor 参数并通过 Converter.RGBA 绑定到填充色,或选择目录中已包含该参数的资源,也可以用 HMIx AI 生成。
把 SVG 重命名为 .svghmi 就够了吗?
不够。文件必须声明参数(hmi:self 中的 hmi:paramDef),以及把参数与图形关联起来的 hmi-bind 绑定。可下载的示例已经包含这两部分。
可以用 AI 创建动态 SVG 吗?
可以。HMIx AI 生成器(ai.hmix.tech)可根据描述或图片为 WinCC Unified 和 V8 创建动态 SVG(.svghmi):包括图形、参数和绑定。之后按照本指南的方法导入并测试即可。
需要 PLC 或 JavaScript 吗?
本次测试不需要。液位保存在 HMI 内部变量中,SVG 内部的表达式负责改变图形。但你需要带有 WinCC Unified 的 TIA Portal,以及其仿真或 Unified PC Runtime。