Ersatz für system.Exec()

Knackige Kurzanleitung, um die undokumentierte system.Exec() zu ersetzen

Um aus HomeMatic-Scripten heraus Systemfunktionen aufzurufen, kann der Befehl system.Exec() verwendet werden. Dieser hat jedoch allerlei Nachteile:

Der CUx-Daemon bietet eine alternative Funktion zur Ausführung von Systembefehlen an. Dafür muss das entsprechende Systemgerät installiert sein wie hier beschrieben. Anschließend kann die system.Exec()-Funktion ersetzt werden.

Das virtuelle Gerät (wie überhaupt der gesamte CUx-Daemon) bietet noch sehr viel mehr Funktionen, als ich hier vorstelle. An dieser Stelle soll es jedoch nur um den einfachstmöglichen Ersatz von system.Exec() gehen.

Aufruf eines Befehls ohne Rückmeldung

Wenn es nur darum geht, einen Befehl auszuführen, ist es ein Einzeiler im Script oder in der WebUI.

dom.GetObject("CUxD.CUX2801001:4.CMD_EXEC").State ("ether-wake 00:00:00:00:00:00");

Die CCU greift hier auf den vierten virtuellen Kanal des Exec-Gerätes zu und setzt einen Befehl über den Datenpunkt CMD_EXEC ab. In diesem Fall wird ether-wake ausgeführt. Das Script wartet nicht darauf, dass das Programm beendet wird, sondern setzt die Ausführung gleich fort.

Der Befehl kann auch direkt in einem WebUI-Programm in den Datenpunkt geschrieben werden, wie ich es bei meinem Etherwake-Programm gemacht habe.

Auswertung einer Konsolenausgabe

Befehle, die auf Systemebene ausgeführt werden, können natürlich auch Informationen zurückliefern. Die kann man auswerten.

Im folgenden Script wird ein Befehl ausgeführt und das Ergbenis in eine Variable geschrieben:

dom.GetObject ("CUxD.CUX2801001:2.CMD_SETS").State ("uptime");
dom.GetObject ("CUxD.CUX2801001:2.CMD_QUERY_RET").State (1);
var x = dom.GetObject ("CUxD.CUX2801001:2.CMD_RETS").State();

Ich spreche hier den zweiten Kanal meines virtuellen CUxD-Gerätes an.

Zeile 1

Der auszuführende Befehl wird festgelegt, indem er in den Datenpunkt CMD_SETS geschrieben wird, hier uptime.

Zeile 2

Wird CMD_QUERY_RET auf 1 gesetzt, so kann anschließend mit CMD_RETS der Output abgefragt werden.

Zeile 3

Mit der Abfrage von .State() des Datenpunktes CMD_RETS wird das Befehl ausgeführt und das Ergebnis zurückgeliefert – aber nur, wenn CMD_QUERY_RET zuvor auf 1 gesetzt wurde.

Die Scriptausführung auf der CCU wartet so lange, bis der Befehl abgeschlossen ist. Man sollte also darauf achten, diese Funktion nur dann zu verwenden, wenn sie nicht zu lange läuft.

Ich kloppe mein Script mal in den Script-Parser und bekomme tatsächlich das erwartete Ergebnis.

Was es mit der Uptime auf sich hat, steht hier.

Asynchrone Auswertung des Exit-Codes

Mit dem CUxD kann man ein Programm durch ein Script ausführen lassen, das seinerseits bei Beenden ein anderes Programm startet.

Im ersten Programm wird der Befehl gestartet.

CMD_SETS

Auch hier wird der auszuführende Befehl zunächst in CMD_SETS gespeichert.

Tastendruck kurz

Mit einem kurzen Tastendruck auf das virtuelle Gerät wird der Befehl ausgeführt.

Das virtuelle Gerät bietet auch einen langen Tastendruck. Der Befehl, der mit einem langen Tastendruck ausgeführt würde, müsste in CMD_SETL geschrieben werden.

Wenn der Befehl, der durch das erste Programm angestoßen wurde, abgeschlossen ist, wird dessen Exit-Code in CMD_RETS geschrieben (CMD_RETL bei langem Tastendruck). Darauf kann das zweite Programm reagieren: Wenn CMD_RETS aktualisiert wird, ist der Befehl abgeschlossen.

Hier prüfe ich, ob der Befehl aus dem ersten Programm fehlerfrei ausgeführt wurde (Exit-Code 0 bedeutet, dass kein Fehler aufgetreten ist). Wie man diese Funktion nutzen kann, um automatisch die Anwesenheit festzustellen, steht hier.

An dieser Stelle sieht man das unterschiedliche Verhalten von CMD_RETS:

Für CMD_SETL, CMD_RETL und den langen Tastendruck gilt dies analog.

Navigation