HMIx Praxisanleitungen
Ein Kreisdiagramm als Custom Web Control für WinCC Unified erstellen
Ein Kreisdiagramm macht die Produktionsmengen mehrerer Linien auf einen Blick vergleichbar. Wir erstellen es mit HTML, CSS und JavaScript, fügen es in TIA Portal ein und testen es mit drei internen Variablen.

Umgebung dieser Anleitung: TIA Portal / WinCC Unified V21.1. Prüfe Import und Ausführung des Beispiels auf deinem Zielgerät.
Was ist ein Custom Web Control?
Ein Custom Web Control, kurz CWC, ist eine kleine Webkomponente innerhalb eines WinCC-Unified-Bildes. HTML beschreibt den Inhalt, CSS das Aussehen und JavaScript das Verhalten. Ein CWC ist sinnvoll, wenn Standardobjekte die gewünschte Darstellung oder Bedienung nicht bieten.
Typische Beispiele sind Produktionsübersichten, Tabellen oder Kreisdiagramme. Das Control stellt Eigenschaften bereit: benannte Eingänge wie ValueA. In TIA Portal verknüpfst du jede Eigenschaft mit einer HMI-Variablen. Das CWC empfängt die Werte und aktualisiert das Diagramm. Eine direkte Verbindung zur SPS stellt es selbst nicht her.
- Verwende ein CWC für eigene Interaktionen, mehrere zusammengehörige Werte oder ein besonderes Layout.
- Für ein einzelnes Symbol mit veränderlicher Farbe, Position oder Füllhöhe ist ein dynamisches SVG oft einfacher.
- Für wiederverwendbare Kombinationen von Standardobjekten kommt ein Faceplate infrage.
Bei HMIx kannst du Hunderte kostenlose HMI-Ressourcen herunterladen. Beginne mit einem Control aus dem Katalog oder beschreibe dem HMIx KI-Generator deine Idee, um eine Ressource für dein Projekt zu erstellen.

Vor dem Start
Verwende ein Testprojekt mit einem WinCC-Unified-Gerät und einem leeren Bild. Benötigt werden TIA Portal mit WinCC Unified Engineering sowie passende Runtime- oder Simulationskomponenten. Ein herkömmliches Comfort-Projekt ist kein Unified-Projekt.
- Nutze für den ersten Test Unified PC Runtime oder die unterstützte Simulation deines Unified-Geräts.
- Zum Ändern des Beispiels benötigst du einen Texteditor und ein ZIP-Programm. Visual Studio Code ist praktisch, aber nicht zwingend erforderlich.
- Eine SPS brauchst du nicht: Drei interne HMI-Variablen und drei E/A-Felder liefern die Testwerte.
Die Browservorschau prüft die Darstellung. Erst ein Test in Unified bestätigt die WebCC-Verbindung und die Variablenanbindung.
Ein Kreisdiagramm mit drei Werten aufbauen
Unser Kreisdiagramm hat die Form eines Rings. In der Mitte steht die Summe, daneben die Legende. Die Eingänge heißen ValueA, ValueB und ValueC; ihre Anfangswerte sind 45, 35 und 20. Es sind Mengenangaben, die nicht 100 ergeben müssen. Das Control berechnet den jeweiligen Anteil an der Summe.
Dateien vorbereiten
Erstelle manifest.json im Hauptordner sowie die Ordner assets und control. Lege in control die Dateien index.html und code.js an. Lade Siemens' webcc.min.js aus dem unten verlinkten offiziellen Beispiel und lege es ebenfalls in control ab. Jede Datei hat eine Aufgabe; ein Webframework ist nicht erforderlich.
Die drei Eingänge festlegen
Deklariere in manifest.json ValueA, ValueB und ValueC als Zahlen mit den Standardwerten 45, 35 und 20. Das Manifest enthält außerdem den Namen HMIx Pie Chart, die Identität und die Startdatei.
Diagramm und Legende zeichnen
Erstelle in control/index.html einen Ring mit drei Segmenten, die Summe und die Legende A, B und C. Berechne in code.js jeden Anteil durch Division des Werts durch die Summe. Sind alle Werte null, erscheint ein leerer Ring. Das Beispiel verwendet SVG innerhalb von HTML und benötigt keine Diagrammbibliothek.
Verbindung zu Unified herstellen
Binde webcc.min.js von Siemens unverändert ein. Starte WebCC mit denselben drei Eigenschaften, lies deren Werte beim Verbindungsaufbau und zeichne bei jeder Meldung von onPropertyChanged neu. Dadurch erscheint auch beim Öffnen des Bildes der aktuelle Wert.
Dateien verpacken
Lege manifest.json, assets und control direkt im ZIP ab, ohne zusätzliche übergeordnete Ebene. Benenne das ZIP nach der GUID des Controls in geschweiften Klammern. Nach Änderungen muss das ZIP mit derselben Struktur neu erstellt werden. Ein anderer Dateiname allein erzeugt keine neue Control-Identität.
ValueA, ValueB und ValueC müssen im Manifest und im JavaScript übereinstimmen. Der Download dieser Anleitung ist ein eigenes Beispiel mit drei Eingängen. Das Pie Chart im Katalog verwendet Apache ECharts und fünf Elemente mit Value und Title.
Vollständige ZIP-Datei mit drei numerischen Eingängen und WebCC. Code und Struktur geprüft; Import und Verbindung in WinCC Unified V21.1 selbst testen.
Beispielcode ansehen
Optional: Der Download enthält das vollständige Beispiel. Du musst diesen Code für den Test nicht abtippen.
manifest.json
{
"mver": "1.2.0",
"control": {
"identity": {
"name": "HmixPieChart",
"version": "1.0",
"displayname": "HMIx Pie Chart",
"type": "guid://8D821B43-4EF5-4BF1-A31D-931D283C7C04",
"start": "./control/index.html"
},
"metadata": {
"author": "HMIx",
"description": "Educational read-only three-value pie chart"
},
"contracts": {
"api": {
"methods": {},
"events": {},
"properties": {
"ValueA": { "type": "number", "default": 45 },
"ValueB": { "type": "number", "default": 35 },
"ValueC": { "type": "number", "default": 20 }
}
}
},
"types": {}
}
}
control/index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>HMIx Pie Chart</title>
<style>
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 20px;
background: #171e26;
color: #f3f5f6;
font:
14px system-ui,
sans-serif;
}
header {
display: flex;
justify-content: space-between;
color: #bac5ce;
font-size: 11px;
letter-spacing: 0.14em;
}
main {
display: flex;
align-items: center;
justify-content: center;
gap: 24px;
min-height: 240px;
}
svg {
width: 55%;
max-width: 300px;
flex-shrink: 0;
}
ul {
list-style: none;
padding: 0;
min-width: 110px;
}
li {
display: grid;
grid-template-columns: 10px 1fr auto;
align-items: center;
gap: 10px;
padding: 14px 0;
border-bottom: 1px solid #35404a;
}
.dot {
width: 8px;
height: 8px;
border-radius: 50%;
}
small {
display: block;
margin-top: 4px;
color: #bac5ce;
font-variant-numeric: tabular-nums;
}
strong {
font-variant-numeric: tabular-nums;
}
@media (max-width: 360px) {
body {
padding: 12px;
}
main {
gap: 12px;
}
}
</style>
</head>
<body>
<header><span>HMIx</span><span>PIE CHART</span></header>
<main>
<svg viewBox="0 0 220 220" role="img" aria-labelledby="chart-title">
<title id="chart-title">Distribution of A, B and C</title>
<circle
cx="110"
cy="110"
r="76"
fill="none"
stroke="#35404a"
stroke-width="28"
/>
<g transform="rotate(-90 110 110)" fill="none" stroke-width="28">
<circle id="ValueA" cx="110" cy="110" r="76" stroke="#47d2c8" />
<circle id="ValueB" cx="110" cy="110" r="76" stroke="#79a9ed" />
<circle id="ValueC" cx="110" cy="110" r="76" stroke="#f5c16c" />
</g>
<text
id="total"
x="110"
y="115"
text-anchor="middle"
fill="#f3f5f6"
font-size="30"
font-weight="600"
>
100
</text>
<text
x="110"
y="139"
text-anchor="middle"
fill="#bac5ce"
font-size="10"
letter-spacing="2"
>
A + B + C
</text>
</svg>
<ul aria-label="Values and shares">
<li>
<i class="dot" style="background: #47d2c8"></i
><span>A<small id="ValueA-amount">45</small></span
><strong id="ValueA-percent">45%</strong>
</li>
<li>
<i class="dot" style="background: #79a9ed"></i
><span>B<small id="ValueB-amount">35</small></span
><strong id="ValueB-percent">35%</strong>
</li>
<li>
<i class="dot" style="background: #f5c16c"></i
><span>C<small id="ValueC-amount">20</small></span
><strong id="ValueC-percent">20%</strong>
</li>
</ul>
</main>
<script src="webcc.min.js"></script>
<script src="code.js"></script>
</body>
</html>
control/code.js
/* HMIx educational pie chart. Values are amounts, not required percentages. */
var values = { ValueA: 45, ValueB: 35, ValueC: 20 };
var keys = ['ValueA', 'ValueB', 'ValueC'];
var circumference = 2 * Math.PI * 76;
function drawChart() {
// Normalize before adding to avoid overflow for very large finite values.
var maximum = Math.max(values.ValueA, values.ValueB, values.ValueC, 1);
var sum = keys.reduce(function (n, key) {
return n + values[key] / maximum;
}, 0);
var offset = 0;
keys.forEach(function (key) {
var fraction = sum ? values[key] / maximum / sum : 0;
var arc = document.getElementById(key);
var length = fraction * circumference;
arc.setAttribute('stroke-dasharray', length + ' ' + circumference);
arc.setAttribute('stroke-dashoffset', String(-offset));
arc.setAttribute('visibility', fraction ? 'visible' : 'hidden');
document.getElementById(key + '-amount').textContent = String(values[key]);
document.getElementById(key + '-percent').textContent =
Math.round(fraction * 100) + '%';
offset += length;
});
var total = values.ValueA + values.ValueB + values.ValueC;
document.getElementById('total').textContent = isFinite(total)
? String(total)
: '—';
}
function setValue(key, value) {
if (keys.indexOf(key) === -1 || typeof value !== 'number' || !isFinite(value))
return;
values[key] = Math.max(0, value);
}
drawChart();
if (typeof WebCC !== 'undefined') {
WebCC.start(
function (connected) {
if (!connected) return;
keys.forEach(function (key) {
setValue(key, WebCC.Properties[key]);
});
drawChart();
WebCC.onPropertyChanged.subscribe(function (change) {
setValue(change.key, change.value);
drawChart();
});
},
{
methods: {},
events: [],
properties: { ValueA: 45, ValueB: 35, ValueC: 20 },
},
['HMI'],
10000,
);
}
Siemens · Aufbau des ManifestsSiemens · WebCC und Runtime-SchnittstelleSiemens · Beispieldateien und WebCC-Bibliothek
Das ZIP in TIA Portal einfügen
Projektordner öffnen
Öffne den Ordner deines TIA-Portal-Projekts. Erstelle in UserFiles den Unterordner CustomControls, falls er fehlt.
CWC-Paket kopieren
Kopiere das importierbare {GUID}.zip nach UserFiles\CustomControls. Dieses ZIP bleibt komprimiert. Nur index.html oder das äußere Downloadpaket reichen nicht aus.
Aktualisieren und platzieren
Öffne das Unified-Bild. Klicke unter Werkzeuge → Eigene Controls (Tools → My controls) auf Aktualisieren und ziehe HMIx Pie Chart ins Bild. Plane Platz für Ring und Legende ein, zum Beispiel 480 × 300 Pixel.
Schnittstelle prüfen
Wähle das Control und öffne Eigenschaften → Eigenschaften → Schnittstelle. Suche ValueA, ValueB und ValueC und trage statisch 45, 35 und 20 ein. Im nächsten Schritt verknüpfst du sie mit Variablen.

Mit drei internen Variablen ohne SPS testen
Drei interne Variablen anlegen
Lege in der HMI-Variablentabelle ProductionA, ProductionB und ProductionC an, mit einem numerischen Datentyp wie Real und ohne SPS-Verbindung.
Jeden Eingang mit seiner Variablen verbinden
Wähle in der CWC-Schnittstelle Variable als Dynamisierung: ValueA → ProductionA, ValueB → ProductionB und ValueC → ProductionC. Lass Nur lesen aktiviert; die E/A-Felder ändern die Daten.
Drei E/A-Felder ergänzen
Füge für jede Variable ein E/A-Feld im Ein-/Ausgabemodus hinzu. Beschrifte sie mit A, B und C. Verwende für den Test Mengen zwischen 0 und 100 und stelle Eingabegrenzen ein, falls verfügbar.
Übersetzen und starten
Lege das Bild als Startbild fest, übersetze die HMI und behebe gemeldete Fehler. Starte die unterstützte HMI-Simulation oder lade und starte das Testprojekt in Unified PC Runtime. Öffne den Runtime-Client und melde dich bei Bedarf mit dem eingerichteten Projektbenutzer an.
Zwei Verteilungen und den leeren Zustand testen
Gib 45, 35 und 20 ein und bestätige jeden Wert. Ändere dann A auf 90: Sein Segment wächst, die Summe beträgt 145. Setze anschließend alle drei Werte auf null; der Ring sollte leer sein. Öffne das Bild erneut und prüfe, ob die aktuellen Werte angezeigt werden.

So sieht das Ergebnis aus
Ändere A, B oder C und beobachte die Segmente. Die Eingänge sind Mengen; das Diagramm berechnet ihre Prozentanteile.
Der Test ist erfolgreich, wenn …
45 / 35 / 20 ergibt eine Summe von 100. Mit A = 90 beträgt sie 145; A hat etwa 62 % Anteil. Drei Nullen ergeben einen leeren Ring. Nach erneutem Öffnen müssen die aktuellen Werte erscheinen.
Siemens · CWC installieren und verwendenSiemens · Engineering-Beispiel und Originalaufnahmen
Wenn etwas nicht funktioniert
- Das Control fehlt: Prüfe UserFiles\CustomControls, die ZIP-Struktur, gültiges Manifest-JSON und den GUID-Dateinamen. Aktualisiere danach Eigene Controls.
- Das Diagramm erscheint, ändert sich aber nicht: Prüfe ValueA, ValueB und ValueC, ihre Variablen und die WebCC-Verbindung. Lokal geöffnetes HTML prüft die Darstellung, nicht die Unified-Verbindung.
- Es funktioniert am PC, aber nicht am Unified Comfort Panel: Halte Abhängigkeiten im Paket. Siemens dokumentiert Einschränkungen für externe Links und Datenabfragen mit fetch oder XMLHttpRequest.
- Eine Änderung ist nicht sichtbar: Erstelle das ZIP neu, aktualisiere das Control über den TIA-Portal-Workflow, übersetze und lade das Testprojekt erneut. Bewahre eine funktionierende Version auf.
Erweitere das Control anschließend schrittweise. Prüfe die endgültige Version am Zielgerät, bevor du sie mit einem realen Prozess verbindest.
Häufige Fragen
Muss ich JavaScript beherrschen?
Ein vorhandenes CWC kannst du ohne JavaScript importieren und anbinden. Für eigene Verhaltensänderungen helfen HTML-, CSS- und JavaScript-Grundkenntnisse. HMIx KI kann die Dateien vorbereiten; das Ergebnis prüfst du in Unified.
Kann ich das Control in einem anderen Projekt verwenden?
Kopiere das importierbare ZIP in dessen UserFiles\CustomControls und richte die dortigen Variablen ein. Halte Paket und Version zusammen. Setze das Verhalten nicht mit einem versionierten Faceplate-Bibliothekstyp gleich.
Reicht eine funktionierende Vorschau?
Sie bestätigt die Darstellung, aber nicht die gesamte Runtime-Integration. Prüfe auch Startverhalten, Eigenschaftsänderungen, Zielgerät und vorgesehene Bildgrößen.
Quellen und weiterführende Informationen
- Siemens · Custom Web Controls programmieren
- Siemens · Aufbau des Manifests
- Siemens · WebCC und Runtime-Schnittstelle
- Siemens · Beispieldateien und WebCC-Bibliothek
- Siemens · CWC installieren und verwenden
- Siemens · Engineering-Beispiel und Originalaufnahmen
- Siemens · CWC-Einschränkungen bei Unified Comfort Panels