Guide pratiche HMIx

Crea un grafico a torta come Custom Web Control per WinCC Unified

Un grafico a torta permette di confrontare a colpo d’occhio la produzione di più linee. Creiamolo con HTML, CSS e JavaScript, aggiungiamolo a TIA Portal e proviamolo con tre variabili interne.

Team HMIx10 min di letturaVerificato il
Illustrazione di un pannello HMI con un grafico a torta a tre serie: 45, 35 e 20
Illustrazione creata con IA per HMIx. L’esempio scaricabile usa gli stessi tre valori, con un grafico ad anello e una legenda.

Ambiente della guida: TIA Portal / WinCC Unified V21.1. Verifica l’importazione e il funzionamento dell’esempio sul dispositivo di destinazione.

01

Cos'è un Custom Web Control?

Un Custom Web Control, o CWC, è un piccolo componente web che inserisci in una schermata di WinCC Unified. HTML definisce il contenuto, CSS l'aspetto e JavaScript il comportamento. È utile quando gli oggetti HMI standard non offrono la presentazione o l'interazione che desideri.

Pensa a un pannello di produzione, una tabella o un grafico a torta. Il controllo espone proprietà: ingressi con un nome, come ValueA. In TIA Portal colleghi ogni proprietà a una variabile HMI; il CWC riceve i valori e aggiorna il grafico. Non si collega direttamente al PLC da solo.

  • Scegli un CWC per interazioni personalizzate, più valori coordinati o una disposizione particolare.
  • Per un simbolo che cambia colore, posizione o livello di riempimento, un SVG dinamico è spesso più semplice.
  • Per riutilizzare un insieme di oggetti HMI standard, valuta un faceplate.

Su HMIx puoi scaricare centinaia di risorse HMI gratuite. Parti da un controllo del catalogo oppure descrivi la tua idea al generatore IA di HMIx per creare una risorsa da adattare al tuo progetto.

Pie Chart di HMIx con cinque settori, legenda e dettaglio di una serie
Pie Chart – Dashboard Widget, pubblicato su HMIx: un grafico ad anello con cinque elementi e titoli configurabili. Puoi scaricarlo dalla scheda prodotto. Qui sotto realizziamo una versione a tre ingressi per capirne il funzionamento. Vedi questa risorsa su HMIx

Siemens · Programmazione dei Custom Web Controls

02

Prima di iniziare

Usa un progetto di prova con un dispositivo WinCC Unified e una schermata vuota. Servono TIA Portal con WinCC Unified Engineering e i componenti Runtime o di simulazione compatibili. Un progetto Comfort tradizionale e uno Unified sono destinazioni diverse.

  • Per la prima prova usa Unified PC Runtime o la simulazione supportata dal tuo dispositivo Unified.
  • Per modificare l'esempio tieni a disposizione un editor di testo e uno strumento ZIP. Visual Studio Code è comodo, ma non obbligatorio.
  • Non serve un PLC: tre variabili HMI interne e tre campi I/O forniscono i valori di prova.

L'anteprima nel browser verifica il disegno. Solo una prova in Unified verifica la connessione WebCC e il collegamento alla variabile.

03

Costruisci un grafico a torta con tre valori

Il nostro grafico ha la forma di un anello: al centro compare il totale e nella legenda ogni serie. Gli ingressi sono ValueA, ValueB e ValueC, inizialmente 45, 35 e 20. Sono quantità; non devono necessariamente sommare 100. Il controllo calcola la quota di ciascuna sul totale.

  1. Prepara i file

    Crea manifest.json nella radice e due cartelle: assets e control. Dentro control crea index.html e code.js. Recupera webcc.min.js di Siemens dall'esempio ufficiale collegato più sotto e inseriscilo in control. Ogni file ha un compito; non serve un framework web.

  2. Definisci i tre ingressi

    In manifest.json, dichiara ValueA, ValueB e ValueC come numeri, con valori iniziali 45, 35 e 20. Il manifesto specifica anche il nome HMIx Pie Chart, l’identità e il file iniziale.

  3. Disegna il grafico e la legenda

    In control/index.html, inserisci un anello a tre segmenti, il totale e la legenda A, B e C. In code.js, dividi ciascun valore per la somma per calcolarne la proporzione. Se tutti sono zero, mostra un anello vuoto. L’esempio usa SVG all’interno dell’HTML e non richiede librerie di grafici.

  4. Collegalo a Unified

    Carica webcc.min.js di Siemens senza modificarlo. Avvia WebCC con le stesse tre proprietà, leggi i valori alla connessione e ridisegna quando onPropertyChanged segnala un cambiamento. In questo modo i dati correnti appaiono già all’apertura della schermata.

  5. Prepara il pacchetto

    Inserisci manifest.json, assets e control nella radice dello ZIP, senza una cartella aggiuntiva che li contenga. Assegna allo ZIP il GUID del controllo tra parentesi graffe. Dopo le modifiche ricrea lo ZIP con la stessa struttura; cambiare solo il nome del file non crea una nuova identità del controllo.

ValueA, ValueB e ValueC devono coincidere nel manifesto e nel JavaScript. Il download della guida è un esempio originale con tre ingressi; il Pie Chart del catalogo usa Apache ECharts e cinque elementi con Value e Title.

Scarica il grafico a torta di esempio

ZIP completo con tre ingressi numerici e WebCC. Codice e struttura controllati; verifica importazione e collegamento in WinCC Unified V21.1.

Visualizza il codice dell'esempio

Facoltativo: il download contiene l'esempio completo. Non devi digitare questo codice per eseguire la prova.

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 · Struttura del manifestSiemens · WebCC e interfaccia con RuntimeSiemens · File di esempio e libreria WebCC

04

Aggiungi lo ZIP al progetto TIA Portal

  1. Trova la cartella del progetto

    Apri la cartella che contiene il progetto TIA Portal. Dentro UserFiles crea CustomControls, se manca.

  2. Copia il pacchetto CWC

    Inserisci il {GUID}.zip importabile in UserFiles\CustomControls. Questo ZIP deve restare compresso. Non copiare soltanto index.html o il pacchetto esterno del download.

  3. Aggiorna e inserisci il controllo

    Apri la schermata Unified. In Strumenti → Controlli personalizzati (Tools → My controls), aggiorna e trascina HMIx Pie Chart nella schermata. Lascia spazio all’anello e alla legenda, per esempio 480 × 300 pixel.

  4. Controlla l'interfaccia

    Seleziona il controllo e apri Proprietà → Proprietà → Interfaccia. Cerca ValueA, ValueB e ValueC e assegna i valori statici 45, 35 e 20. Nel passo successivo li collegherai alle variabili.

Schermata Siemens con My controls, un indicatore nella schermata Unified e le proprietà Interface
Schermata di engineering Siemens: controlli personalizzati → schermata → interfaccia. Siemens mostra GaugeMeter; per questa prova seleziona HMIx Pie Chart con ValueA, ValueB e ValueC. Fonte · © Siemens AG · Licenza e attribuzione

Siemens · Installazione e uso dei CWC

05

Provalo con tre variabili interne, senza PLC

  1. Crea tre variabili interne

    Nella tabella delle variabili HMI, aggiungi ProductionA, ProductionB e ProductionC con un tipo numerico come Real e senza collegamento a un PLC.

  2. Collega ogni ingresso alla sua variabile

    Nell’interfaccia CWC scegli Variabile come dinamizzazione: ValueA → ProductionA, ValueB → ProductionB e ValueC → ProductionC. Mantieni attivo Sola lettura; i campi I/O cambieranno i dati.

  3. Aggiungi tre campi I/O

    Inserisci un campo I/O in modalità ingresso/uscita per ogni variabile. Identificali con A, B e C. Per la prova usa quantità tra 0 e 100 e imposta i limiti di immissione dove disponibili.

  4. Compila ed esegui

    Imposta questa schermata come iniziale, compila l'HMI e risolvi gli errori segnalati. Avvia la simulazione HMI supportata oppure carica e avvia il progetto di prova in Unified PC Runtime. Apri il client Runtime e accedi con l'utente configurato nel progetto, se richiesto.

  5. Prova due distribuzioni e lo stato vuoto

    Inserisci 45, 35 e 20 e conferma ogni valore. Porta poi A a 90: il suo segmento cresce e il totale diventa 145. Infine imposta tutti e tre a zero; l’anello deve essere vuoto. Riapri la schermata per verificare la lettura dei valori correnti.

Schermata Siemens di una proprietà CWC collegata a una variabile con Read-only attivo
Collegamento di una proprietà nell’esempio Siemens. Sostituisci GaugeValue / Motor_Speed con ValueA / ProductionA e ripeti per B e C, mantenendo Sola lettura. Fonte · © Siemens AG · Licenza e attribuzione

Prima osserva il risultato atteso

Cambia A, B o C e osserva i segmenti. Gli ingressi sono quantità: il grafico calcola le percentuali.

100Totale
45 / 45%
35 / 35%
20 / 20%
Spiegazione interattiva della guida. Non è una sessione di WinCC Runtime.

La prova funziona quando…

45 / 35 / 20 dà un totale di 100. Con A = 90 il totale diventa 145 e A rappresenta circa il 62%. Tre zeri lasciano l’anello vuoto. Riaprendo la schermata devono comparire i valori correnti.

Siemens · Installazione e uso dei CWCSiemens · Esempio di engineering e schermate originali

06

Se qualcosa non funziona

  • Il controllo manca: verifica UserFiles\CustomControls, la radice dello ZIP, la sintassi JSON del manifesto e il nome GUID; poi aggiorna My controls.
  • Il grafico appare ma non cambia: controlla ValueA, ValueB e ValueC, le variabili e la connessione WebCC. Aprire l’HTML localmente verifica l’aspetto, non il collegamento a Unified.
  • Funziona su PC ma non su Unified Comfort Panel: mantieni le dipendenze nel pacchetto. Siemens documenta limitazioni per i collegamenti esterni e le richieste fetch o XMLHttpRequest.
  • Una modifica non compare: ricrea lo ZIP, usa la procedura di aggiornamento dei controlli di TIA Portal, compila e ricarica il progetto di prova. Conserva una copia della versione funzionante.

Dopo questa prima prova aggiungi una funzione alla volta. Verifica il controllo finale sul dispositivo di destinazione prima di collegarlo a un processo reale.

Siemens · Restrizioni CWC sui Unified Comfort Panel

Domande frequenti

Devo conoscere JavaScript?

Puoi importare e collegare un CWC esistente senza scrivere JavaScript. Per modificarne il comportamento a mano, sono utili nozioni di HTML, CSS e JavaScript. L'IA di HMIx può preparare i file; il risultato va comunque verificato in Unified.

Posso riutilizzarlo in un altro progetto?

Copia lo ZIP importabile in UserFiles\CustomControls dell'altro progetto e configura le sue variabili. Conserva insieme pacchetto e versione. Non presumere che si comporti come un tipo faceplate versionato in libreria.

Un'anteprima corretta significa che è pronto?

Conferma l'aspetto, non tutta l'integrazione con Runtime. Verifica anche avvio, modifiche delle proprietà, dispositivo di destinazione e dimensioni delle schermate previste.

Fonti e approfondimenti