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)
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);
}

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.

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
inf, -inf oder nan
)
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;
}

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