Erweiterte Konfiguration

Dieses Kapitel erklärt, wie die verschiedenen Funktionen und Merkmale des Trends weiter angepasst werden können.

Anpassung des Trendlineal-Fensters

Das Trendlineal-Fenster ist ein anpassbares Panel ("trendRulerPanel.pnl"), das sich im Verzeichnis /panels Ihrer WinCC OA-Installation befindet. Das Panel bietet eine vordefinierte Implementierung, wie Werte angezeigt werden und auf bestimmte Ereignisse reagiert wird. Dieser Code muss angepasst oder erweitert werden, um das gewünschte Verhalten Ihres Projekts zu erreichen. Die Schriftgrößen des Popup-Panel-Textes sind im Panel fest codiert und können nur dort geändert werden. Standardmäßig wird die Schriftgröße 12 für Text und 16 für Werte verwendet.

Mit dem $DP "$floating" kann definiert werden, ob das Panel als frei schwebendes Element (=TRUE; Standard, einschließlich einer Fenstertitelleiste) oder als Lineal-Popup geöffnet wird. Dies kann auch dynamisch durch die Verwendung der "floatingRulerWindow"-Eigenschaft des Trends festgelegt werden. Bei einem schwebenden Panel wird die letzte Position gespeichert und als Position verwendet, wenn das Panel erneut geöffnet wird.

Die öffentliche Funktion "rulerChanged" des Panels kann verwendet werden, um auf Änderungen (Hinzufügen, Entfernen, Verschieben usw.) am Lineal zu reagieren und die Logik des Panels zu implementieren. Innerhalb der Funktion kann der angezeigte Inhalt des Panels entsprechend aktualisiert werden.

public rulerChanged(shape theTrend, int area) synchronized(table)
Anmerkung:

Die Funktion rulerChanged wird automatisch alle 500ms ausgelöst, auch wenn keine Änderungen am Lineal vorgenommen wurden.

Beachten Sie, dass folgende Informationen erforderlich sind, um das Panel anzuzeigen:

  • Datum/Zeitstempel
  • Wert des Schnittpunkts (Die Funktion "RulerValue" muss verfügbar sein!)
  • Farbe und/oder Markierung der Kurve
  • Ereignisbereichsbeschreibungstext (Muss vom Benutzer implementiert werden!)
  • Alarmbeschreibung

Es kann nur ein Trendlineal-Panel (trendRulerPanel.pnl) für Ihr Projekt definiert werden, aber um verschiedene Anzeigeoptionen zu haben, können zusätzliche benutzerdefinierte Panels mit der Funktion addSymbol() aus dem trendRulerPanel.pnl geladen werden.

Trendlineal-Symbol

Um ein Symbol für das Lineal anzuzeigen, verwendet der Trend die Bilder "trendRuler_X.png" im Verzeichnis /pictures, wobei X das entsprechende Lineal darstellt (beginnend mit 1).

Bitte beachten Sie, dass die Verwendung mehrerer Lineale mit der Trend-Eigenschaft "maxRulerCount" aktiviert werden muss.

Ereigniskurve

Die Ereigniskurve kann verwendet werden, um spezifische Ereignisse oder Zeitspannen anzuzeigen, die innerhalb der Trendkurven deutlich sichtbar sein sollen. Die Ereigniskurve zeigt den Zeitstempel oder den Zeitrahmen an, in dem ein bestimmtes Ereignis ausgelöst wurde (z. B. Änderungen von Werten, Zeit oder Zustand). Für den Zeitpunkt wird eine horizontale (oder vertikale für den vertikalen Trend) Linie innerhalb des Trends angezeigt.

Der Kurventyp kann entweder über die Trend-Konfigurationspanels oder durch die Trend-Eigenschaft "curveType" festgelegt werden.

Beim Verwenden der Ereigniskurve sollten folgende Hinweise beachtet werden:

  • Die Ereignislinie einer Ereigniskurve wird als Prozentsatz des gesamten Plotbereichs gezeichnet, wobei "min" und "max" den Start- und Endprozentsatz der Linie definieren. So führt z. B. min = 10, max = 40 zu einer Ereignislinie, die bei 10% beginnt und bei 40% des verfügbaren Plotbereichs endet, ausgehend von der unteren Plotgrenze.
  • Mehrere Ereignisse können gestapelt und entsprechend angezeigt werden. Dies ermöglicht eine einfachere Unterscheidung zwischen überlappenden Zeitbereichen.
  • Um eine Hintergrundfarbe für einen Ereignisbereich anzuzeigen, muss die Kurvenfüllung festgelegt werden, z. B. "fill to bottom" oder "fill to refValue".
  • Die Füllung einer Ereigniskurve wird zwischen dem "on"- und "off"-Zustand einer Kurve angezeigt. Der "off"-Wert wurde zuvor als "0.0" definiert. Dies wurde geändert, um die kurven-definierte "ref.value"-Eigenschaft stattdessen zu verwenden. Im Trend-Konfigurationspanel im GEDI wird dies als "fill ref.value" bezeichnet. Der Standardwert bleibt "0.0", kann jedoch im Trend-Konfigurationspanel geändert werden. Der Wert wird nur verwendet, wenn der ausgewählte Fülltyp nicht "none" ist.
    VORSICHT: Falls zuvor ein anderer ref.value als "0.0" definiert wurde, sieht die Anzeige der Ereigniskurve jetzt anders aus.

    Grundsätzlich sollten die Ereignisse der Reihenfolge "on","off","on" usw. folgen, aber es ist möglich, einem "on"-Trigger mit einem weiteren "on"-Trigger zu folgen. In diesem Fall muss das Ereignis einen anderen Zustand haben, um es zu markieren, z. B. eine ungültige Visualisierung.

    Ein "off"-Trigger, gefolgt von einem weiteren "off"-Trigger, wird als Einzelereignislinie angezeigt.

    Ein "on"-Ereignis ohne abschließendes "off"-Ereignis wird kontinuierlich gezeichnet, bis der nächste "off"-Trigger auftritt.

  • Es wird empfohlen, die Y-Achse einer Ereigniskurve zu deaktivieren, da sie ohnehin nicht verwendet wird.

Übersetzung des Rechtsklick-Menüs des Trends

Um das Rechtsklick-Menü des Trends zu übersetzen, übersetzen Sie die Dateien der Benutzeroberfläche. Weitere Informationen finden Sie im Kapitel Übersetzung von UI-Einträgen.

Ereigniskurve mit String-DPEs/JSON

Die Ereigniskurve kann auch verwendet werden, um String-DPEs anzuzeigen. In diesem Fall wird der angezeigte Wert mit folgendem Verhalten bestimmt:

  • Wenn der String des DPE ein JSON-Format enthält, wird der "value"-Schlüssel des Strings angezeigt (siehe JSON-Format unten)
  • Wenn der String kein JSON enthält, wird der Wert wie bei einem CTRL-String bestimmt: Ein String, der entweder "0", "FALSE" oder "false" enthält, wird als FALSE betrachtet, alles andere wird als TRUE betrachtet.

JSON-Struktur

Der curveValue kann jetzt auch ein String-Attribut im JSON-Format sein. Folgende Schlüssel werden von der Ereigniskurve verwendet:

  • "value" - beliebiger Datentyp; Ein Wert > 0 wird als TRUE betrachtet und markiert ein "on"-Ereignis (siehe Beschreibung oben)
  • "text" - String; Text, der auf der Ereignislinie angezeigt werden soll
  • "alignment" - String; Die Ausrichtung relativ zur Ereignislinie für Text und Symbol. Folgende Ausrichtungsflags sind verfügbar:
    • AlignLeft - Ausrichtung links von der Linie
    • AlignHCenter - Ausrichtung horizontal zentriert zur Linie
    • AlignRight - Ausrichtung rechts von der Linie
    • AlignTop - Ausrichtung oben zur Linie
    • AlignVCenter - Ausrichtung vertikal zentriert zur Linie
    • AlignBottom - Ausrichtung unten zur Linie

    Horizontale und vertikale Flags können mit dem | Zeichen kombiniert werden, z. B. "AlignTop|AlignLeft".

    Bei Verwendung eines vertikalen Trends bleiben die Flags gleich, werden jedoch anders verwendet, z. B. wird "AlignTop" verwendet, um eine Ausrichtung zur rechten Seite zu erstellen, oder "AlignVCenter" wird verwendet, um eine Ausrichtung zur horizontalen Mitte der Linie zu erstellen.

    Dieses Verhalten wird verwendet, um die Kompatibilität des DPE in beiden Ausrichtungen zu gewährleisten.

  • "icon" - String; Dateiname des Symbols, das angezeigt werden soll. Der Pfad muss relativ zum Verzeichnis /pictures sein.

Beispiel

Folgender Beispielcode (Trend - Initialisierungsskript) füllt einen leeren Trend mit mehreren Ereigniskurven, um eine einfache Demonstration einer Produktionslinie zu geben. Siehe Abbildung Trend - Ereigniskurvenbeispiel.

Bitte beachten Sie, dass für dieses Beispiel alle Standardkurven des Trends manuell entfernt werden müssen, um eine ähnliche visuelle Darstellung zu erhalten.

// [myTrend] [1] - [Initialize] 
  main() 
{ 
  //Variable Definitions and Declarations 
  time t = getCurrentTime(); 
  const bit64 INVALID = "1000001100000000000000000000000000000000000100000000000100100001"; 
  //Trend Visible Area Configuration 
  this.scrollPercent(5); 
  this.visibleTimeRange(0,t-1650,t+200); 
  
  //Dynamically added the Event Curves ProductionLine, PreProduction, ProductionEvents 
  this.addCurve(0,"ProductionLine"); 
  this.addCurve(0,"PreProduction"); 
  this.addCurve(0,"ProductionEvents"); 
  this.curveType("ProductionLine",4); 
  this.curveType("PreProduction",4); 
  this.curveType("ProductionEvents",4); 
  
  this.curveLegendName("ProductionLine", "Production"); 
  this.curveLegendName("PreProduction", "Pre-Production"); 
  this.curveLegendName("ProductionEvents", "Events"); 
  
  //Display Height/Area of the Event Curves 
  this.curveMin("ProductionLine",15.0); 
  this.curveMax("ProductionLine",60.0); 
  this.curveMin("PreProduction",15.0); 
  this.curveMax("PreProduction",60.0); 
  this.curveMin("ProductionEvents",15.0); 
  this.curveMax("ProductionEvents",90.0);
   
  //Design Settings: Colors, Line Types, Fillings, etc. 
  this.backCol("SiemensStone35"); 
  this.curveFillType("ProductionLine", "[solid]"); 
  this.curveFillType("PreProduction", "[hatch,[cross,10,horizontal]]"); 
  this.curveFillType("ProductionEvents", "[solid]"); 
  this.curveLineType("ProductionLine", "[solid,oneColor,JoinMiter,CapButt,3]"); 
  this.curveLineType("PreProduction", "[solid,oneColor,JoinMiter,CapButt,3]"); 
  this.curveLineType("ProductionEvents", "[solid,oneColor,JoinMiter,CapButt,3]"); 
  this.curveColor("ProductionLine","SiemensNaturalBlueDark"); 
  this.curveColor("PreProduction","SiemensSnow"); 
  this.curveColor("ProductionEvents","SiemensNaturalYellowLight"); 
  this.curveFillColor("ProductionLine", "SiemensNaturalBlueLight"); 
  this.curveFillColor("PreProduction", "SiemensSnow"); 
  this.curveFillColor("ProductionEvents", "SiemensNaturalYellowLight");
   
  //mandatory for displaying the Event Curves! 
  this.curveFilled("ProductionLine",1); 
  this.curveFilled("PreProduction",1); 
  this.curveFilled("ProductionEvents",1); 
  
  //Events in displayed order 
  //Pre-Production 
  this.curveValue("PreProduction", "{\"value\":1, \"text\":\"Pre-Production Cycle\",\"icon\":\"scriptWriteOnly\",
                    \"alignment\":\"AlignLeft\"}", t-1400,0); 
  this.curveValue("PreProduction", "{\"value\":0}", t-1200,0); 
  
  //End of Pre-Production and Begin of "Production" 
  this.curveValue("ProductionEvents", "{\"value\":0, \"text\":\"Start Production\",\"icon\":\"vision\",
                    \"alignment\":\"AlignLeft\"}", t-1200, 0); 
  this.curveValue("ProductionLine", "{\"value\":1}", t - 1200, 0); 
  
  //Batch - Events 1-3 
  this.curveValue("ProductionEvents", "{\"value\":0, \"text\":\"Batch 1\", \"icon\":\"trendRuler_1\"}",t-1000, 0); 
  this.curveValue("ProductionEvents", "{\"value\":0, \"text\":\"Batch 2\", \"icon\":\"trendRuler_2\"}",t-750, 0); 
  this.curveValue("ProductionEvents", "{\"value\":0, \"text\":\"Batch 3\", \"icon\":\"trendRuler_3\"}",t-500, 0); 
  
  //Error Event 
  this.curveValue("ProductionEvents", "{\"value\":0, \"text\":\"Error\", \"icon\":\"disconnected\"}",t-400, 0); 
  this.curveValue("ProductionLine", 1.0, t - 400, INVALID); 
  
//Sets the current value invalid. Design can be changed by using the Config Entry "trendStatusPattern" 
  this.curveValue("ProductionEvents", "{\"value\":0, \"text\":\"Error Resolved\",\"icon\":\"apply_16\"}", t-300, 0); 
  
  //Batch - Event 4 
  this.curveValue("ProductionEvents", "{\"value\":0, \"text\":\"Batch 4\", \"icon\":\"trendRuler_4\"}",t-100, 0); 
  this.curveValue("ProductionLine", "{\"value\":1}", t-300, 0); 
  
  //End of Production Cycle 
  this.curveValue("ProductionLine", "{\"value\":0}", t, 0); 
  this.curveValue("ProductionEvents", "{\"value\":0, \"text\":\"End Production\",\"icon\":\"exit\"}", t, 0); 
}
Abbildung 1. Trend-Ereigniskurvenbeispiel

Viewport / Vorauswahl-Trend

Um einen bestimmten Zeitbereich der Trendkurve auszuwählen und zu zoomen, steht eine neue Viewport-Funktion zur Verfügung. Um den Viewport zu öffnen, kann die Funktion "areaViewportTimeRange" verwendet werden.

Beim Verwenden des Viewport-Widgets sollten folgende Hinweise und Einschränkungen beachtet werden:

  • Die Reihenfolge der verknüpften Bereiche kann für das Viewport-Widget nicht geändert werden.
  • Um das Lineal-Popup-Panel innerhalb des Hauptbereichs anstelle des Viewport-Bereichs anzuzeigen, muss das Popup-Panel angepasst werden. Der Funktionsaufruf "setPosition(area);" muss in "setPosition(<main display area>);" geändert werden.
  • Der Viewport-Bereich sowie der Haupttrendbereich müssen mit der Funktion "linkAreas" verknüpft werden. Es ist zu beachten, dass zuerst die Haupttrendbereichs-ID und danach die Viewport-Bereichs-ID verwendet werden muss: "linkAreas(<Main Area ID>, <Viewport Area ID>);"
  • Das Design des Viewport-Widgets kann mit CSS geändert werden. Die verfügbaren Klassen und Beispiele finden Sie hier, bzw. hier.
  • Beachten Sie, dass umfangreiches Zoomen in den Trend dazu führen kann, dass die Viewport-Schieberegler verschwinden, da der ausgewählte Zeitbereich nicht innerhalb der verfügbaren Pixelanzahl angezeigt werden kann.
  • Der Scrollmodus des Viewport-Widgets kann mit der Eigenschaft "areaViewportPageScrollMode" definiert werden.
  • Durch die Verwendung der Eigenschaft "areaMargins" kann der Rand des Viewports geändert werden, um z. B. eine andere Breite im Vergleich zum Trendbereich zu verwenden.
Abbildung 2. Trend mit einem Viewport-Widget darunter

Overlay-Text

Die Eigenschaft "areaPlotOverlayText" ermöglicht es, einen benutzerdefinierten Text und Inhalt über einem Bereich des Trends zu platzieren. HTML kann verwendet werden, um vollständig gestaltete Symbole und Beschriftungen für den Bereich zu platzieren.

Konfiguration der Interaktionsmöglichkeiten

Um die erlaubten Interaktionen mit den Trend-Elementen zu konfigurieren, stehen die Eigenschaften "areaInteractionFlag","areaInteractionFlags", "areaPlotInteractionFlag" und "areaPlotInteractionFlags" zur Verfügung. Sie können verwendet werden, um festzulegen, ob Schwenken, Zoomen oder das Kontextmenü verfügbar sind.

Anzeige-Bereichsbegrenzung

Um die maximale angezeigte Zeitspanne eines Bereichs zu begrenzen, kann die Eigenschaft "areaMaximumTimeSpan" verwendet werden.

Trendanzeige mit Lücken

Bei Verwendung der RDB-Archivierung kann eine Anzeigelücke in einem Trend zwischen den historischen Daten und den aktuellen Daten auftreten. Diese Lücke kann auftreten, wenn Daten (vor einigen Sekunden) derzeit nur im lokalen Puffer des RDB-Managers gespeichert werden und nicht in die Oracle-Datenbank übertragen wurden.

Der Trend zeigt Werte bis zum letzten Datenflush vom WinCC OA-Puffer zur Oracle-Datenbank an. Aktuelle neue Daten werden direkt vom Event Manager empfangen und müssen nicht aus der Datenbank gelesen werden.

Das Flush-Intervall für die RDB-Archivierung kann konfiguriert werden. Beachten Sie, dass ein kürzeres Flush-Intervall den Vorteil bietet, dass die Lücke kürzer sein könnte, aber die Belastung des RDB-Managers und des Netzwerkverkehrs erhöht. Die Konfiguration für das Flush-Intervall ist die maximale Zeit, die die Daten im Puffer verbleiben, bevor sie übertragen werden.

Ein Puffer wird geleert, wenn die definierte Blockgröße oder das Timeout für das Flush-Intervall erreicht ist. Die Blockgröße wird im RDB-Konfigurationspanel mit dem Parameter "Entries/Block" konfiguriert. Im RDB-Konfigurationspanel wird das Flush-Intervall mit dem Parameter "Flush interval" definiert. Wir empfehlen, ein Flush-Intervall >= 1000 msec zu verwenden. Dies ist eine allgemeine Empfehlung, und die Werte sollten unter Berücksichtigung der Projektgröße, des Netzwerkverkehrs usw. festgelegt werden.

Unendliche Werte

Unendliche Werte werden nicht gezeichnet (z. B.: nicht in Kurven, Füllungen, Markierungen usw.). Stattdessen markiert eine dünne gepunktete Linie senkrecht zur Wertachse den Anfang und das Ende jedes unendlichen Wertes, außer beim Ereignistrendtyp. Ein Label neben dieser Linie zeigt den tatsächlichen Wert an (z. B.: inf, -inf oder nan)
Anmerkung: Für Ereigniskurven werden die Sonderfälle (-inf, inf, nan) angezeigt, wenn die textuelle Anzeige (JSON) des Wertes aktiviert ist.

Ereigniskurve mit unendlichen Werten und zwei weiteren Kurven

main()
{
  time t = getCurrentTime();
  int count = 10;
  int timeStep = 30;
  bit64 status = 15;

  TREND1.curveType("#1_1", 4); // 4 = Event
  TREND1.curveLegendName("#1_1", "EventCurve");

  TREND1.addCurve(0, "#1_2");
  TREND1.curveColor("#1_2", "blue");
  TREND1.curveType("#1_2", 1); // 1 = Steps
  TREND1.curveLegendName("#1_2", "StepsCurve");
  TREND1.linkCurves("#1_2", "#1_1"); // all curves should have the same scale

  TREND1.addCurve(0, "#1_3");
  TREND1.curveColor("#1_3", "green");
  TREND1.curveType("#1_3", 2); // 2 = Linear
  TREND1.curveLegendName("#1_3", "LinearCurve");
  TREND1.linkCurves("#1_3", "#1_1"); // all curves should have the same scale

  t -= (long)(count * timeStep);

  TREND1.curveValue("#1_1", "{\"icon\": \"trendRuler_1.png\", \"text\": \"-Infinite\", \"value\": \"-inf\"}", t, status);
  TREND1.curveValue("#1_2", 5, t, status);
  TREND1.curveValue("#1_3", 10, t, status);
  t += timeStep;

  TREND1.curveValue("#1_1", "{\"icon\": \"trendRuler_2.png\", \"text\": \"+Infinite\", \"value\": \"inf\"}", t, status);
  TREND1.curveValue("#1_2", 40, t, status);
  TREND1.curveValue("#1_3", 80, t, status);
  t += timeStep;

  TREND1.curveValue("#1_1", "{\"icon\": \"trendRuler_3.png\", \"text\": \"noValue\", \"value\": \"NaN\"}", t, status);
  TREND1.curveValue("#1_2", 25, t, status);
  TREND1.curveValue("#1_3", 50, t, status);
  t += timeStep;

  TREND1.curveValue("#1_1", "{\"icon\": \"trendRuler_4.png\", \"value\": 12}", t, status);
  TREND1.curveValue("#1_2", 35, t, status);
  TREND1.curveValue("#1_3", 70, t, status);
  t += timeStep;

  TREND1.curveValue("#1_1", "{\"text\": \"'OA'\", \"value\": \"OA\"}", t, status);
  TREND1.curveValue("#1_2", 20, t, status);
  TREND1.curveValue("#1_3", 40, t, status);
  t += timeStep;

  TREND1.curveValue("#1_1", "{\"icon\": \"trendRuler_6.png\", \"text\": \"Number34\", \"value\": 34}", t, status);
  TREND1.curveValue("#1_2", 30, t, status);
  TREND1.curveValue("#1_3", 60, t, status);
  t += timeStep;
}
Abbildung 3. Unendliche Werte

Trendgitter

Das Gitter des Trendbereichs kann angepasst werden, um Ihre Designanforderungen zu erfüllen, indem folgende Funktionen verwendet werden: