Runtime Skript

Note

Die Runtime Skript wird dafür verwendet, Programmecode zu erstellen und auslöserbasiert ablaufen zu lassen. Hiermit können z. B. Signalwerte abgefragt, Sollwerte ereignisbasiert gesetzt, ein Chargenstart bzw. -stopp realisiert oder ein Kamerabild ins Archiv übernommen werden. Ebenso kann per Skript überprüft werden, ob in einem bestimmten Zeitraum ein Kamerabild im Archiv vorhanden ist.

Die zugrunde liegende Programmiersprache ist JavaScript.

Über das Plus kann direkt ein neues Runtime Skript angelegt werden. Sollten Sie ein Runtime Skript bearbeiten wollen oder suchen, klicken Sie auf die Schaltfläche (Der Bereich um das Plus herum), um eine Liste aller bestehender Runtime Skripte angezeigt zu bekommen. Dort können Sie das Runtime Skript auswählen, welches bearbeitet werden soll.

../../../../_images/runtimeScriptSymbol.png

Basiskonfiguration

Der Name des Runtime Skripts muss vergeben werden. Zusätzlich kann optional ein Beschreibungstext ergänzt werden. Das Feld „Gruppe“ zeigt, in welcher Gruppe diese Rolle angelegt wurde. Der Pfad wird systemseitig automatisch generiert. Ist die Checkbox Aktiviert angewählt, so wird das konfigurierte Runtime Skript zu Laufzeit der Anwendung ausgeführt.

../../../../_images/runtimeScriptBasicConfig.png

Auslöser

Der Auslöser gibt an, wann bzw. in welchem Zyklus das nachfolgende Skript ausgeführt werden soll. Es stehen verschiedene Möglichkeiten zur Verfügung. Um einen Auslöser für Ihr Runtime Skript hinzuzufügen, klicken Sie auf das “+” Icon im unteren Bereich der Tabelle. Anbei ein Beispiel mit allen verfügbaren Optionen.

Typ

Wert

Aktion

Beschreibung

Cyclic Trigger

Ganze Zahlen

Zyklischer Auslöser: Das Skript wird entsprechend dem eingetragenen Wert alle n Sekunden ausgeführt.

Event Trigger

Ereignisdefinition

Entered
Dropped
Acknowledged

Eventbasierter Auslöser: Das Skript wird ausgeführt sobald die ausgewählte Ereignisdefinition Eingegangen/Ausgegangen/Quittiert wurde.

Condition Trigger

Signalbedingung

Raised
Dropped

Signalbedingung als Auslöser: Das Skript wird ausgeführt sobald die ausgewählte Signalbedingung aktiv/inaktiv ist.

Batch Trigger

Chargendefinition

Started
Stopped

Chargenstart bzw. -stopp als Auslöser

../../../../_images/runtimeScriptTrigger.png

Variablen

Um das Runtime Skript für die Objektorientierung nutzbar zu machen oder um übersichtlich die Variablen im Skript darzustellen, können außerhalb des Skripts sog. Statische Variablen angelegt werden, die dann innerhalb des Skripts verwendet werden können:

../../../../_images/runtimeScriptVariable.png

Die Variable SignalID kann dann so im Skript bzw. im Editor verwendet werden. Weitere Informationen sind im Kapitel Editor aufgeführt.

../../../../_images/runtimeScriptEditorCodeFragment.png

Editor

Mit dem Skript-Editor wird der eigentliche Programmablauf ermöglicht. Die Programmiersprache ist JavaScript. Der Funktionsumfang von JavaScript (ES2022) steht größtenteils zur Verfügung, eine detaillierte Liste was unterstützt wird, findet sich auf: https://github.com/sebastienros/jint.

Note

Über die Buttons “Testen” und “Ausführen” kann das Skript manuell ausgeführt werden. Diese manuellen Aktionen werden erfasst und im Reiter “Historie” geloggt. Ein Klick auf “Testen” erzeugt einen “Dry Run” in der Historie. Hierbei werden keine Sollwerte gesetzt, Chargen gestartet bzw. gestoppt oder Kamerabilder ins Archiv gelegt. Unter Historie kann der Anwender jedoch berechnete Werte oder Skript-Feedback einsehen. Ein Klick auf “Ausführen” führt das Skript vollständig aus.

../../../../_images/runtimeScriptEditor.png

Beispiel in dem ein virtuelles Sollwertsignal immer um 10 niedriger ist als ein reales Sollwertsignal

Um in dem Skript mit der audako Anwendung zu interagieren, werden einige Funktionen und Namespaces zur Verfügung gestellt. Um eine Funktion auf einem Namespace aufzurufen, schreibt man:

{Namespace}.{Funktionsaufruf}

Es folgen nun die Namespaces und deren Funktion

Note

Kursiv geschriebene Ausdrücke in geschweiften Klammern werden als Platzhalter verwendet, d.h. in einem richtigen Anwendungsfall müssen diese durch Variablen oder Werte ersetzt werden. {SignalID}


Signal Access

Note

Der Namespace SignalAccess stellt Funktionen bereit, um Werte von Signalen auszulesen und Sollwerte zu setzen.

Wie erhalte ich die SignalID?

Um die Id einer Entität möglichst schnell zu erhalten, klicken Sie mit der rechten Maustaste auf die jeweilige Reihe Ihrer Entität und wählen Sie “ID kopieren” aus, die Id wurde nun in Ihre Zwischenablage kopiert und kann via “Strg + V” oder “Rechtsklick + Einfügen” in ein Textfeld/Text eingefügt werden.

../../../../_images/copyId.png

Mit der Funktion SignalAccess.GetValue({SignalID}): number | string kann der aktuellen Live-Wert des Signals, der über den Parameter spezifiziert wurde, ausgelesen werden. Der Wert wird als Nummer oder String zurückgegeben. Existiert das Signal nicht oder ist der Parameter {SignalID} leer, wird null zurückgegeben.

SignalAccess.GetValue({SignalID}): number | string

Mit der Funktion GetValueWithTimestamp({SignalID}): {Value: number | string, Timestamp: Date} kann der aktuellen Live-Wert zusammen mit dem dazugehörigen Zeitstempel des Signals, der über den Parameter spezifiert wurde, ausgelesen werden. Existiert das Signal nicht oder ist der Parameter {SignalID} leer, wird null zurückgegeben.

SignalAccess.GetValueWithTimestamp({SignalID}): {Value: number | string, Timestamp: Date}

Mit der Funktion SignalAccess.SetValue({SignalID}, {Value}): void kann der Wert eines Signals (Ausgang) gesetzt werden, d.h. der im zweiten Parameter {Value} spezifizierte Wert wird an das Gateway gesendet oder im Fall eines virtuellen Signals (Signal ohne Datenquelle und Datenverbindung) als Live-Wert erzeugt. Das Signal wird über den ersten Parameter {SignalID} spezifiziert.

SignalAccess.SetValue({SignalID}, {Value}): void

Note

Virtuelle Signale ohne Datenquelle und Datenverbindung werden aktuell nicht historisch gespeichert.


BatchAccess

Note

Der Namespace BatchAccess stellt Funktionen bereit, um Chargen zu starten bzw. zu stoppen und aktive Chargen abzufragen.

Wie erhalte ich die BatchDefinitionID?

Um die Id einer Entität möglichst schnell zu erhalten, klicken Sie mit der rechten Maustaste auf die jeweilige Reihe Ihrer Entität und wählen Sie “ID kopieren” aus, die Id wurde nun in Ihre Zwischenablage kopiert und kann via “Strg + V” oder “Rechtsklick + Einfügen” in ein Textfeld/Text eingefügt werden.

../../../../_images/copyId.png

Mit der Funktion BatchAccess.GetRunningBatches({BatchDefinitionID}): Batch[] können die aktiven laufenden Chargen, die über den Parameter {BatchDefinitionID} spezifizierten Chargendefinition, abgefragt werden.

BatchAccess.GetRunningBatches({BatchDefinitionID}): Batch[]

Mit der Funktion BachAccess.StartBatch({BatchDefinitionId}, {MetadataValues}): Batch können neue Chargen gestartet werden. Der Parameter {BatchDefinitionID} spezifiziert hierbei die gewünschte Chargendefinition. Die Kopfdaten werden über den zweiten Parameter {MetadataValues} übergeben. Hierbei muss der exakte Name des Kopfdatenfeldes aus der Chargendefinition übernommen werden. Nachfolgend wird durch Doppelpunkt der entsprechende Wert spezifiziert. Zum Beispiel {Produkttyp: 300} oder {Produktname: Produkt1}. Werden mehrere Kopfdaten gesetzt, so können diese durch Komma nacheinander aufgeführt werden {Produkttyp: 300, Produktname: “Wiener Würstchen”}.

BachAccess.StartBatch({BatchDefinitionId}, {MetadataValues}): Batch

Mit der Funktion BachAccess.StopBatch({BatchDefinitionId}, {BatchId}, {MetadataValues}): Batch können laufende Chargen gestoppt werden. Der Parameter {BatchDefinitionID} spezifiziert hierbei die laufende Chargendefinition. Der Parameter {BatchId} spezifiziert die jeweilige Charge. Die Kopfdaten werden über den dritten Parameter {MetadataValues} übergeben. Hierbei muss der exakte Name des Kopfdatenfeldes aus der Chargendefinition übernommen werden. Nachfolgend wird durch Doppelpunkt der entsprechende Wert spezifiziert. Zum Beispiel {Produkttyp: 300} oder {Produktname: Produkt1}. Werden mehrere Kopfdaten gesetzt, so können diese durch Komma nacheinander aufgeführt werden {Produkttyp: 300, Produktname: “Wiener Würstchen”}.


Wie erhalte ich die BatchID?

Um die ID der laufenden Charge zu erhalten, kann die Funktion GetRunningBatches({BatchDefinitionID}) wie oben beschrieben benutzt werden. In der Historie wird beim Skript “Testen” der ID-Wert geloggt (sofern die * Environment.Print()* Funktion verwendet wird (siehe weiter unten))

BatchAccess.GetRunningBatches({BatchDefinitionID}): Batch[]

BachAccess.StopBatch({BatchDefinitionId}, {BatchId}, {MetadataValues}): Batch

Camera Access

Note

Der Namespace CameraAccess stellt Funktionen bereit, um Archivbilder von Kameras zu erstellen und abzufragen.


Wie erhalte ich die CameraID?

Um die Id einer Entität möglichst schnell zu erhalten, klicken Sie mit der rechten Maustaste auf die jeweilige Reihe Ihrer Entität und wählen Sie “ID kopieren” aus, die Id wurde nun in Ihre Zwischenablage kopiert und kann via “Strg + V” oder “Rechtsklick + Einfügen” in ein Textfeld/Text eingefügt werden.

../../../../_images/copyId.png

Mit der Funktion CameraAccess.AnyArchiveImage({CameraID}, {From}, {Till}): boolean kann überprüft werden, ob ein Archivbild existiert oder nicht. Der Parameter {CameraID} spezifizierte die jeweilige Kamera. Der Parameter {From}, {Till} spezifiziert den Zeitraum, in dem abgefragt werden soll, ob ein Archivbild existiert.

CameraAccess.AnyArchiveImage({CameraID}, {From}, {Till}): boolean

Mit der Funktion CameraAccess.TakeArchiveImage({CameraId}): void kann ein Archivbild aufgenommen werden. Der Parameter {CameraID} spezifizierte die jeweilige Kamera.

CameraAccess.TakeArchiveImage({CameraId}): void

Environment

Note

Der Namespace Environment stellt allgemeine Hilfsfunktionen bereit, um das Erstellen von Skripten zu vereinfachen und Logeinträge in der Historie zu generieren.

Mit der Funktion Environment.Print({Message}) können Nachrichten aller Art als Logeinträge in die Historie des Skripts geschrieben werden, um diese einfacher zu debuggen. Die Werte müssen jedoch serialisierbar sein.


Note

Was ist {Message}? In diesem Ausdruck kann sowohl reiner Text als auch ein Skriptwert stehen. Die Bezeichnung in Anführungszeichen wird als reiner Text übernommen.

Skript Editor:

var setpointID = "62f4a519a56fe6b36a40578f";
var outputID = "64b4ebe8ce556c1cf04d435d";

var setpointValue = SignalAccess.GetValue(setpointID);

Enviroment.Print("Received Setpoint Value:" + setpointValue);

SignalAccess.SetValue(outputID, setpointValue - 10);

Ausgabe Historienlog:
../../../../_images/outputWindow.png

Environment.Print({Message})

Mit der Funktion Environment.GetCurrentUtcDateTime() kann die aktuelle Zeit in UTC abgefragt werden.

Environment.GetCurrentUtcDateTime()

Status über mehrere Skriptausführungen hinweg speichern

Note

Es kann vorkommen, dass man bestimmte Variablen oder Werte {Message} persistent speichern will, um sie bei der nächsten Ausführung des Skriptes zu verwenden. Dies ermöglicht das Objekt ScriptResources[{Message}] {Message} wird hierbei als Platzhalter für die jeweilige Variable genutzt, es ist nicht möglich den gleichen Namen mehrmals zu vergeben, dies würde zum Überschreiben der Variable führen, beim Aufruf muss der Name identisch dem Platzhalternamen sein.

ScriptResources[{Message}]
../../../../_images/multipleScriptRunningCode.png

Historie

Jede Auslösung des Skriptes wird in der Historie gespeichert. Eine Manuelle Auslösung über den “Testen” oder “Ausführen” Button wird als Manueller Eintrag festgehalten. Ein “Testen” erzeugt einen “Dry Run”, in dem keine tatsächlichen Skript-Aktionen ausgeführt werden.

Note

Über das Plus Symbol rechts kann das Log angeschaut werden. Hier werden Aktionen des Skripts aufgeführt und errechnete bzw. abgefragte oder gesetzte Werte eingesehen werden.

../../../../_images/runtimeScriptHistory.png ../../../../_images/runtimeScriptHistoryLogs.png