HMIx 实用指南

为 WinCC Unified 创建卧式储罐动态 SVG

一个带金属质感的卧式储罐,用一个变量控制液位。学习创建这个动态 SVG 并在 TIA Portal 中测试,无需 JavaScript,也不必为每种状态准备单独的图片。

HMIx 团队阅读约 9 分钟核对日期
金属卧式储罐及其 SVG 图形的示意图,液位高度为百分之五十
为 HMIx 用 AI 制作的示意图:卧式储罐及其图形表示。FillLevel 控制可见液体的高度。

本指南的操作环境:TIA Portal / WinCC Unified V21.1。请在目标设备上检查示例的导入和运行情况。

01

什么是动态 SVG?

SVG 用形状和线条描述图片,而不是固定的像素网格。因此,它适合需要在不同尺寸下保持清晰的符号,例如储罐、阀门、电机和指示器。

WinCC Unified 中的参数化图形组件采用 .svghmi 格式。它在图形上添加接口,提供 FillLevel、颜色等参数。TIA Portal 会显示这些参数,并允许将它们绑定到 HMI 变量。数值变化就能改变图形,无需为 0–100 % 的储罐准备 101 张图片。

普通 .svg 可以作为图形使用,但仅将扩展名改成 .svghmi,并不会增加动态接口。

  • 液位、设备状态、颜色变化,以及由数值驱动的简单运动,都适合动态 SVG。
  • 如果需要更丰富的 Web 界面、定制表格或多种交互,可以选择 CWC。
  • 先从简单的小图形开始,逐一理解每个参数的作用。

在 HMIx,你可以免费下载数百种 HMI 资源。可以从目录中的现成控件开始,也可以向 HMIx AI 生成器描述想法,创建适合自己项目的资源。

HMIx 已发布的 Horizontal Tank,带金属罐体、支座和蓝色液体
HMIx 已发布的 Horizontal Tank。其文件包含 FillLevel、LiquidColor、BasicColor、SaddleColor 和 ShowFittings。本指南示例保留卧式外观,只提供 FillLevel,方便完成第一次测试。 在 HMIx 查看此资源

西门子 · 管理动态 SVG 图形西门子 · 支持的 SVG 格式及限制

02

首次测试需要哪些工具

准备带有 Unified 设备和空白画面的测试项目,以及兼容的 Runtime 或仿真组件。本指南参考 V21.1;较早版本和其他 WinCC 版本系列可能存在差异。

  • 手动绘制时,可以使用 Inkscape 等矢量编辑器,再用文本编辑器添加 HMI 接口。
  • 如果希望直接测试,可下载下方的小型 .svghmi 示例。不需要 PLC。
  • 使用 WinCC Unified 支持的形状和效果。SVG 在浏览器中显示正常,并不代表所有元素都能在 HMI 设备上运行。

西门子 · 支持的 SVG 格式及限制

03

用一个参数绘制卧式储罐

储罐由圆角轮廓、两个支座和金属渐变组成。液体是独立的矩形,通过裁剪限制在罐体内部。只有一个变化参数:FillLevel,范围为 0 到 100。

  1. 绘制固定部分

    绘制水平罐体、支座和顶部开口,设置 400 × 250 的 viewBox。将罐体轮廓放入 clipPath,避免液体超出两端的圆角。

  2. 添加 HMI 接口

    在文本编辑器中添加西门子 HMI 命名空间和 hmi:self 段。用 hmi:paramDef 定义 FillLevel,类型为 number,默认值为 50。完整示例已经提供这些结构。

  3. 绑定液体形状

    将 hmi-bind:height 和 hmi-bind:y 与 ParamProps.FillLevel 关联。矩形高度增加时,上边缘上移,底部保持不动。clipPath 将液体限制在罐内,Converter.Bounds 将显示值限制为 0–100。

  4. 保存为 .svghmi

    以 UTF-8 保存 XML,确保扩展名正好是 .svghmi,而不是 .svghmi.txt。保留可编辑副本。添加 HMI 绑定后,避免再次用可能删除西门子属性的普通矢量编辑器保存。

这里的 FillLevel 表示液体高度的百分比。对于卧式储罐,它通常不等于体积百分比。如果需要显示升数或体积,应根据储罐几何形状进行换算。

下载卧式储罐示例

完整 .svghmi 文件,包含 FillLevel 参数(0–100)。已检查 XML 结构和表达式;请在 WinCC Unified V21.1 中验证导入。

查看示例代码

可选阅读:下载文件包含完整示例。完成本次测试不需要手动输入这些代码。

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>

西门子 · 创建动态 SVG 图形(109782045)

04

在 TIA Portal 中作为动态小部件加载

  1. 把文件放进项目

    打开项目目录,必要时创建 UserFiles\SVGControls。将 HmixHorizontalTank.svghmi 复制进去。这里需要实际的 .svghmi 文件,而不是 ZIP。

  2. 打开动态小部件

    打开 Unified 画面,进入工具 → 动态小部件(Tools → Dynamic widgets)。添加或修改文件后刷新面板;如果新文件仍未出现,重新打开项目。

  3. 放置并检查

    将 HMIx Horizontal Tank 拖入画面。在属性中找到用户定义参数 FillLevel,把静态值设为 50。先确认图形可见,再绑定变量。

此文件应通过动态小部件使用。将普通 SVG 导入图形集合是另一种流程,不会创建这里的参数接口。

西门子 · 管理动态 SVG 图形西门子 · 更新动态 SVG 图形

05

让液位在 Runtime 中变化

  1. 创建内部数值

    新增内部 HMI 变量 TankLevel,使用 Real 等数值类型,不连接 PLC。这个数值将由你手动输入。

  2. 绑定参数

    选中储罐,将 FillLevel 参数的动态化设置为变量(Tag),再选择 TankLevel。参数名属于 SVG 文件,变量名属于 HMI 项目。

  3. 添加数值 I/O 域

    把 I/O 域放在图形旁,设置为输入/输出模式,把过程值连接到同一个 TankLevel。如果支持输入限制,设为 0 和 100。

  4. 编译并测试三个数值

    设置起始画面,编译 HMI,并启动支持的仿真或 Unified PC 测试 Runtime。打开 Runtime 客户端,按需登录,然后依次输入 0、50、100。确认每次输入,观察液体变化。

  5. 检查缩放和重新打开

    重新打开画面,确认显示当前值。再放置一个不同尺寸的实例:轮廓应保持清晰,液体应始终位于储罐内部。

下方滑块用于说明预期效果。它独立于 TIA Portal,不会与项目通信。

先看看预期效果

移动滑块,液体会在罐体内部升高。FillLevel 表示高度,而非体积。

50%
这是本指南的交互演示,并非 WinCC Runtime 会话。

满足这些条件,测试才算成功

0 时储罐为空,50 时液体达到一半高度,100 时达到顶部。液体应始终保持在轮廓内部,重新打开画面后也应与输入/输出域一致。

06

常见问题与简单检查

  • 动态小部件中找不到文件:检查 UserFiles\SVGControls、真实扩展名、XML 语法和 HMI 接口,然后刷新面板。
  • 储罐显示了,但液位不变:检查文件是否包含 HMI 绑定,以及 FillLevel 是否连接到与 I/O 域相同的变量。
  • 液位向下增长:液体顶部位置必须与高度同时变化。我们的示例保持底部固定。
  • 效果与矢量编辑器不同:简化不支持的效果、CSS 和字体依赖。除浏览器预览外,还要在实际目标上检查。
  • 更新后绑定丢失:重命名、删除参数或修改参数类型可能破坏现有实例。请保留接口,或重新配置受影响的实例。

直接放置在画面中的示例运行成功后,可以继续了解动态 SVG 库类型,将其复用于画面和 faceplate。这是后续学习内容,并非首次测试的前提。

西门子 · 更新动态 SVG 图形西门子 · 将动态 SVG 创建为库类型

常见问题

SVG 在 Unified 中会自动变成动态的吗?

不会。静态 SVG 只包含图形。参数化 .svghmi 还需要西门子接口和绑定,仅修改扩展名不够。

这个储罐需要 JavaScript 吗?

不需要。液位使用 SVGHMI 内部表达式和 TIA Portal 变量绑定。更复杂的交互可能更适合使用 CWC。

同一个文件适用于所有 WinCC 版本系列吗?

不要直接作此假定。在 HMIx 中选择正确目标,并核对资源兼容性。本指南针对 WinCC Unified;其他 WinCC 版本系列及不同版本有各自的限制。

资料来源与延伸阅读