API-Funktionen

ℹ️ Verfügbar ab QuickHMI 15 (Ultimate-Lizenz). Diese Version ist noch nicht veröffentlicht.

Serverseitige Skripte sprechen den Server über das globale Objekt qhmi an. Anders als im Browser liegen Aktionen und Ereignisse unter demselben Objekt. Die Ereignisse sind auf der Seite Ereignisse und Zeitpläne beschrieben.

Variablen werden immer mit ihrem vollen Namen angesprochen, also Datenquelle.Variable.

Variablen

qhmi.getVariable(name)

Liefert den aktuellen Wert einer Variablen, und zwar typgerecht: Zahlen als Zahl, Wahrheitswerte als Boolean, alles Übrige als Text. Unbekannte Variablen liefern null und eine Warnung im Serverlog. Auch eine Variable, für die noch kein Wert vorliegt, liefert null.

const wert = qhmi.getVariable("SPS.Kessel_Temp");

//Zahlen sind Zahlen, kein Text: Rechnen funktioniert direkt.
qhmi.log(wert + 1);

qhmi.getVariableInfo(name)

Liefert die Variable mit ihrem Umfeld statt nur dem Wert. Verwenden Sie diese Funktion überall dort, wo Ihr Skript von sich aus liest, also in Zeitplänen und Intervallen: getVariable allein verschweigt, ob der Wert überhaupt noch aktuell ist. Eine seit Stunden nicht erreichbare Steuerung liefert weiterhin ihren letzten bekannten Wert, erkennbar allein an quality. Das Feld lastvalue ist nur gefüllt, solange auf der Variablen ein Handler registriert ist.

const info = qhmi.getVariableInfo("SPS.Kessel_Temp");

if (info !== null && info.quality === "GOOD") {
    qhmi.log(info.value + " von " + new Date(info.timestamp).toLocaleString());
}

// info enthält:
// { datasource_name, name, value, lastvalue, quality, timestamp, datatype }

qhmi.getVariables(namen)

Liest mehrere Variablen auf einmal und gibt ein Objekt zurück, dessen Schlüssel die Variablennamen sind. Unbekannte Namen stehen mit null darin. Das Ergebnis hat dieselbe Form, die setVariables entgegennimmt.

const werte = qhmi.getVariables(["SPS.Druck", "SPS.Temperatur"]);

qhmi.log(werte["SPS.Druck"]);

qhmi.setVariable(name, wert)

Schreibt einen Wert über denselben Weg, den auch ein Bediener nutzt. Liefert true, wenn die Datenquelle den Schreibvorgang bestätigt hat; Einzelheiten zu einem Fehlschlag stehen im Serverlog.

if (qhmi.setVariable("SPS.Sollwert", 42)) {
    qhmi.log("Sollwert übernommen");
}

qhmi.setVariables(werte)

Schreibt mehrere Variablen. Liefert true, wenn alle Schreibvorgänge bestätigt wurden.

qhmi.setVariables({
    "SPS.Sollwert": 42,
    "SPS.Freigabe": true
});

Zustand über Neustarts hinweg

Der Skriptspeicher gehört zum Projekt und übersteht einen Neustart des Servers. Er ist für Zähler, Merker und kleine Konfigurationen gedacht, nicht für Messreihen: Je Wert sind 64 KB möglich, insgesamt 4 MB.

qhmi.storage.set(schluessel, wert)

Legt einen Wert ab. Erlaubt ist alles, was sich als JSON schreiben lässt: Zahl, Text, Wahrheitswert, Objekt, Array. Liefert false, wenn eine der Größengrenzen erreicht ist.

qhmi.storage.set("schichtStart", Date.now());
qhmi.storage.set("konfiguration", { ziel: 1000, schicht: "A" });

qhmi.storage.get(schluessel, standardwert)

Liest einen Wert. Ist der Schlüssel unbekannt, wird der zweite Parameter zurückgegeben, ohne ihn null. Rechnen Sie immer damit, dass ein Schlüssel beim ersten Lauf fehlt.

//Beim allerersten Lauf gibt es den Schlüssel noch nicht.
let zaehler = qhmi.storage.get("teile", 0);

zaehler = zaehler + 1;
qhmi.storage.set("teile", zaehler);

qhmi.storage.remove(schluessel), qhmi.storage.keys(), qhmi.storage.clear()

Entfernt einen Wert, listet alle vergebenen Schlüssel auf oder leert den Speicher des Projekts vollständig.

qhmi.storage.remove("schichtStart");
qhmi.log(qhmi.storage.keys().join(", "));
qhmi.storage.clear();

Meldungen

qhmi.log(meldung), qhmi.logWarning(meldung), qhmi.logError(meldung)

Schreibt eine Meldung ins Serverlog, als Information, Warnung oder Fehler. Das ist der übliche Weg, um während der Entwicklung nachzuvollziehen, was ein Skript tut.

qhmi.log("Charge 47 begonnen");
qhmi.logWarning("Füllstand niedrig");
qhmi.logError("Rezept konnte nicht geladen werden");

Alarme

qhmi.getActiveAlarms()

Liefert alle anstehenden Alarme. Ohne diese Abfrage müsste ein Skript jedes Alarmereignis selbst mitschreiben und verlöre den Überblick bei jedem Neustart.

for (const alarm of qhmi.getActiveAlarms()) {
    qhmi.log(alarm.variable + " (" + alarm.alarmclass + ") seit "
        + new Date(alarm.timestamp).toLocaleString()
        + (alarm.acknowledged ? ", quittiert" : ""));
}

// je Alarm:
// { variable, datasource_name, name, alarmclass, message, location, timestamp, acknowledged }

qhmi.getActiveAlarmCount(alarmklasse)

Zählt die anstehenden Alarme. Ohne Argument alle, sonst nur die der angegebenen Alarmklasse.

const alle = qhmi.getActiveAlarmCount();
const fehler = qhmi.getActiveAlarmCount("Fehler");

qhmi.isAlarmActive(name)

Fragt für eine einzelne Variable, ob gerade ein Alarm ansteht.

if (qhmi.isAlarmActive("SPS.Kessel_Temp")) {
    qhmi.setVariable("SPS.Sammelstoerung", true);
}

qhmi.acknowledgeAlarm(name)

Quittiert den Alarm einer Variablen, so wie es sonst ein Bediener tut. Im Alarmprotokoll erscheint Script als Quelle. Nicht quittierbare Alarmklassen lassen sich auch aus dem Skript nicht quittieren; die Funktion liefert dann false.

qhmi.acknowledgeAlarm("SPS.Kessel_Temp");

Datenquellen

qhmi.getDatasourceStatus(name), qhmi.getDatasourceStatuses()

Liefert den Zustand einer einzelnen Datenquelle oder aller Datenquellen des Projekts, jeweils mit name, quality und message. Damit muss ein Skript nach dem Start nicht auf die nächste Statusänderung warten, um zu wissen, ob eine Quelle läuft.

const sps = qhmi.getDatasourceStatus("SPS");

if (sps !== null && sps.quality !== "GOOD") {
    qhmi.logWarning("SPS nicht erreichbar: " + sps.message);
}

for (const ds of qhmi.getDatasourceStatuses()) {
    qhmi.log(ds.name + ": " + ds.quality);
}

Verbundene Clients

qhmi.getConnectedClients(), qhmi.getLoggedInUsers()

Liefert die verbundenen Sitzungen mit id und user beziehungsweise die angemeldeten Benutzer, jeden einmal. Ohne aktives Sicherheitssystem tragen Sitzungen keinen Benutzer, die Liste der Benutzer ist dann leer.

qhmi.log(qhmi.getConnectedClients().length + " Visualisierungen offen");
qhmi.log("Angemeldet: " + qhmi.getLoggedInUsers().join(", "));

E-Mail

Beide Wege nehmen Mailserver, Port, Verschlüsselung, Zugangsdaten und Absender aus einer im Editor angelegten Vorlage. Der Versand läuft im Hintergrund; der Rückgabewert sagt, ob die Vorlage gefunden und der Versand angestoßen wurde, nicht ob die Mail zugestellt wurde.

qhmi.sendMailTemplate(vorlage)

Versendet eine Vorlage unverändert, mit dem Text und den Empfängern, die im Editor hinterlegt sind.

qhmi.sendMailTemplate("Tagesbericht");

qhmi.sendMail(vorlage, empfaenger, betreff, text)

Versendet eine frei zusammengestellte Mail über den Versandweg der angegebenen Vorlage. Empfänger, Betreff und Text kommen aus dem Skript.

qhmi.sendMail("Stoerung", "leitstand@example.com", "Kessel 2",
    "Temperatur bei " + qhmi.getVariable("SPS.Kessel_Temp") + " Grad");

//Leerer Empfänger: die Empfänger der Vorlage werden verwendet.
qhmi.sendMail("Stoerung", "", "Kessel 2", "Grenzwert überschritten");

Datenbankabfragen

qhmi.executeQuery(name)

Führt eine im Projekt hinterlegte Datenbankabfrage aus. Die Abfrage muss auf manuelle Ausführung eingestellt sein; Abfragen mit Intervall laufen ohnehin von selbst.

qhmi.executeQuery("Tagesreport");

qhmi.getQueryData(name)

Liefert das Ergebnis der letzten Ausführung einer Abfrage, nicht eine neue. Wenn Sie frische Daten brauchen, rufen Sie vorher executeQuery auf. Jede Zeile ist ein Objekt, dessen Schlüssel die Spaltennamen sind. Alle Werte sind Text, auch Zahlen und Zeitstempel. Sehr große Ergebnisse werden für Skripte bei 10.000 Zeilen abgeschnitten, erkennbar an truncated; die Anzeige in der Visualisierung bleibt davon unberührt.

qhmi.executeQuery("Auftraege");

const ergebnis = qhmi.getQueryData("Auftraege");

if (ergebnis !== null) {
    for (const zeile of ergebnis.rows) {
        qhmi.log(zeile.Auftragsnummer + ": " + zeile.Menge);
    }
}

// ergebnis enthält:
// { columns, rows, truncated, timestamp }

Rezepte

qhmi.loadRecipe(name), qhmi.listRecipes()

Wendet ein im Projekt hinterlegtes Rezept an, schreibt also alle Zutaten auf ihre gespeicherten Werte, und liefert die Namen aller Rezepte. Gedacht für Abläufe ohne geöffnete Visualisierung, etwa einen Rezeptwechsel bei einem Auftragswechsel. Abgewandelte Zutaten kann ein Skript nicht übergeben, das bleibt der Rezeptmaske vorbehalten.

for (const name of qhmi.listRecipes()) {
    qhmi.log("Rezept: " + name);
}

if (qhmi.loadRecipe("Charge_A.qrec")) {
    qhmi.log("Rezept übernommen");
}

Umgebung

qhmi.getServerTime()

Liefert die Serverzeit in Millisekunden seit 1970, also dasselbe Zeitmaß, das auch die Zeitstempel der Ereignisse verwenden. Die Variablen der Datenquelle System helfen hier nicht: Sie werden im Browser berechnet und bleiben im Server leer.

const jetzt = new Date(qhmi.getServerTime());

qhmi.log("Serverzeit: " + jetzt.toLocaleString());

qhmi.getProjectName(), qhmi.getInstanceName(), qhmi.getServerVersion()

Liefern den Namen des laufenden Projekts, den Namen der Instanz und die Version des Servers. Der Instanzname ist vor allem für Meldungen nützlich, damit der Empfänger erkennt, woher sie stammt.

qhmi.sendMail("Stoerung", "", "Meldung aus " + qhmi.getInstanceName(),
    "Projekt " + qhmi.getProjectName() + ", Server " + qhmi.getServerVersion());