Grenzen und Fallstricke

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

Serverseitige Skripte laufen in einer anderen Umgebung als Skripte im Browser. Die folgenden Punkte sind bewusst so gebaut. Wenn Sie sie kennen, ersparen Sie sich die Suche nach Fehlern, die keine sind.

Ein Skript läuft genau einmal

Serverseitige Skripte laufen einmal je Instanz, unabhängig von der Zahl geöffneter Visualisierungen. Ein Projekt kann seit QuickHMI 15 nur in einer Instanz betrieben werden; der Import in eine zweite Instanz wird abgelehnt und nennt die Instanz, die das Projekt bereits verwendet.

onServerStopped feuert nur beim geordneten Stopp

Beim regulären Herunterfahren läuft Ihr Handler noch, bevor die Datenquellen getrennt werden. Wird der Serverprozess hart beendet, etwa vom Betriebssystem, kann kein Skript mehr ausgeführt werden. Verlassen Sie sich für wichtige Zustände deshalb nicht allein auf dieses Ereignis, sondern schreiben Sie sie laufend in den Skriptspeicher.

Keine Systemvariablen im Server

Die Variablen der Datenquelle System, etwa System.clocktime, werden im Browser berechnet und bleiben im Server leer. Verwenden Sie stattdessen new Date() oder qhmi.getServerTime().

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

Kein Zugriff auf Netzwerk und Dateisystem

Serverseitige Skripte laufen abgeschottet. Sie können keine Dateien lesen oder schreiben und keine Verbindungen nach außen aufbauen. Das ist Absicht und Teil der Sicherheitsarchitektur: Ein Projekt, das auf einem Server ausgeführt wird, soll dort nicht mehr dürfen als das, was QuickHMI selbst anbietet. Für den Austausch mit anderen Systemen nutzen Sie die vorgesehenen Wege, also Datenquellen, Datenbankabfragen und die Datenbereitstellung.

Verpasste Zeitpunkte werden nicht nachgeholt

Ein Zeitplan mit qhmi.onSchedule feuert nur, wenn der Server zum vorgesehenen Zeitpunkt läuft. War er um 06:00 nicht in Betrieb, geschieht an diesem Tag nichts. Wenn Sie sicherstellen müssen, dass ein Ablauf nachgeholt wird, halten Sie im Skriptspeicher fest, wann er zuletzt ausgeführt wurde, und prüfen Sie das beim Serverstart.

qhmi.onServerStarted(function () {
    const heute = new Date().toDateString();

    if (qhmi.storage.get("berichtVom", "") !== heute) {
        qhmi.sendMailTemplate("Tagesbericht");
        qhmi.storage.set("berichtVom", heute);
    }
});

Ein geschlossener Browser meldet sich nicht ab

Wer das Browserfenster einfach schließt, löst nicht sofort onClientDisconnected aus. Der Server erkennt das Ende der Sitzung erst, wenn sie abgelaufen ist. Für Zählungen offener Visualisierungen ist das genau genug, für sicherheitsrelevante Entscheidungen nicht.

Mailversand aus dem Skript kennt keine Sperrzeit

Eine E-Mail-Vorlage kann im Editor eine Sperrzeit haben, damit dieselbe Meldung nicht mehrfach hintereinander verschickt wird. Für den Versand aus dem Skript gilt sie nicht: Wer in einem Intervall sendet, verschickt auch im Intervall. Bauen Sie eine solche Begrenzung bei Bedarf selbst ein, etwa über einen Merker im Skriptspeicher.

Alle Skripte teilen sich einen Ablauf

Sämtliche Handler, Timer und Zeitpläne aller serverseitigen Skripte laufen nacheinander. Das erspart Ihnen jede Absicherung gegen gleichzeitige Zugriffe, bedeutet aber auch: Ein langsamer Handler verzögert die anderen. Vermeiden Sie lange Schleifen und wartende Aufrufe. Ein Skript, das gar nicht mehr zurückkehrt, wird nach einer Zeitgrenze abgebrochen; der Server läuft weiter, und im Serverlog steht eine Warnung.

Werte und Datentypen unterscheiden sich vom Browser

Im Server sind Werte typgerecht: Eine Zahl ist eine Zahl, ein Wahrheitswert ein Boolean. Im Browser ist jeder Variablenwert Text. Ebenso ist der Datentyp im Server der genaue Typ der Steuerung, etwa Int oder Real, im Browser dagegen eine gröbere Kategorie wie NUMERIC. Wenn Sie ein Skript vom Browser in den Server übernehmen, prüfen Sie Vergleiche und Umrechnungen.

Datenbankwerte sind immer Text

Die Zeilen aus qhmi.getQueryData enthalten ausschließlich Text, auch bei Zahlenspalten und Zeitstempeln. Ein Zeitstempel erscheint in der Schreibweise der Datenbank, etwa 2026-09-04 08:53:52.0. Rechnen Sie mit den Werten erst, nachdem Sie sie umgewandelt haben.

const zeile = qhmi.getQueryData("Auftraege").rows[0];
const menge = parseFloat(zeile.Menge);

Der Skriptspeicher ist für Merker gedacht

Je Wert sind 64 KB möglich, insgesamt 4 MB. Wird eine Grenze erreicht, liefert qhmi.storage.set den Wert false und schreibt eine Warnung ins Serverlog. Geschrieben wird gebündelt, nicht bei jedem Aufruf; ein hart beendeter Server kann daher die Änderungen der letzten Sekunden verlieren.