Ablaufsteuerung

Hallo Allerseits

Seit einem Jahr setze ich IP-Symcon ein und bin sehr zufrieden damit.
Fast am meisten überraschte mich, wie robust diese Software läuft.
Eigentlich der einzige Bug, der das Gesamtbild geringfügig trübt, steckt im EnOcean-Modul, also in einem Teil, der für Viele kaum von Bedeutung sein dürfte. Vielleicht ist auch das der Grund, weshalb der Bug noch immer nicht behoben ist… (vgl. http://www.ip-symcon.de/forum/f18/enocean-id-not-valid-integer-value-7031/).

Als kleines Dankeschön möchte ich quasi als Weihnachtsgeschenk mal was an die IPS-Community zurück geben.

Am Anfang stand der Wunsch, eine Abwesenheits-Simulation zu realisieren. Sprich eine Kette von Aktionen in unregelmässigen zeitlichen Abständen.

Wie setzt man sowas in IPS um? Naheliegend wäre, die Wartezeiten durch Aufrufe einer Warte-Funktion zu codieren. Doch leider ist die Funktion IPS_Sleep() gem. Dokumentation für Wartezeiten länger als 1 Sekunde nicht geeignet.
(Nebenbei erwähnt kann ich die Logik dahinter nicht ganz nachvollziehen. Wäre es denn eine grosse Geschichte, IPS_Sleep im Hintergrund durch Timer zu realisieren?)
Die in IPS vorgeschlagene Alternative mit Script-Timern gefiel mir gar nicht, weil zu unhandlich und unübersichtlich.

Deshalb schrieb ich eine Klasse für die Ablaufsteuerung in grösseren Zeitdimensionen. Ziel war, eine Form zu finden, in welcher der eigentliche Ablauf möglichst kompakt und leicht lesbar abgebildet werden kann.
Das Resultat, eine PHP-Klasse namens sequencer.class.php veröffentliche gleich anschliessend in diesem Thread.

Schöne Festtage wünscht euch
Dieter

Hier also der Code.

Der Aufruf der Klasse:


$schedObj = new Sequencer();
if ($schedObj->is_initialized) {
	$schedObj->exec_scheduled_action();

} else {
	$schedule = array(
		array('delay' => 10, 'function' => 'fun1()'),
		array('delay' => 5, 'function' => 'fun2()')
	);
	$schedObj->initialize($schedule);
}

Der Ablauf wird also in einem Array abgelegt, für jede Aktion gibt’s einen Aktions-Eintrag. Ein Aktions-Eintrag besteht seinerseits aus einem Array, welches verschiedene Felder enthalten kann:

[ul]
[li]‚delay‘ => t: Eine Verzögerungszeit in Sekunden[/li][li]‚at‘ => t: Eine Startzeit im Unix-Format (z.B. mktime(11,8,14) )[/li][li]‚at+‘ => t: Eine Verzögerungszeit analog zu ‚delay‘, nur wird sofort ein Ereignis (Timer) erzeugt[/li][li]‚randomDelay‘ => t: Eine zufällige Verzögerungszeit, welche zu ‚delay‘, ‚at‘ oder ‚at+‘ addiert wird[/li][/ul]

Die auszuführenden Aktionen werde so definiert:

[ul]
[li]‚function‘ => ‚fun()‘: Der Name einer Funktion[/li][li]‚eval‘ => ‚php-code…;‘: PHP-Code, der mit eval() ausgeführt werden soll[/li][li]‚code‘ => ‚php-code…;‘: Synonym für ‚eval‘[/li][li]‚exec‘ => ‚DOS Befehl‘: Der Befehlt wird an die Command-Line übergeben[/li][/ul]

Einer Funktion kann man einen Parameter übergeben mittels

[ul]
[li]‚parameter‘ => ‚irgendwas…‘[/li][/ul]

Bei der Erzeugung des Sequencer-Objektes gibt’s noch die Möglichkeit, das Verhalten zu definieren im Fall, dass das Script mehrmals aufgerufen wird:

$schedObj = new Sequencer(<Parameter>);

Wobei <Parameter> folgende Werte haben kann:

[ul]
[li]RESTART: ein laufender Ablauf wird abgebrochen und erneut gestartet[/li][li]TOGGLE: falls eine Sequenz bereits läuft, wird diese abgebrochen, sonst neu gestartet. Z.B. nützlich, falls ein Ablauf mit einem Wandschalter verknüpft ist[/li][li]MULTIPLE: die Ereignisse werden kumuliert bzw. verschachelt ausgeführt[/li][li]IGNORE_MULTIPLE: solange eine Sequenz abläuft, werden erneute Aufrufe ignoriert [/li][/ul]

Im Anhang der Code der Klasse und eines einfachen Testprogramms.

Beste Grüsse,
Dieter

Sequencer.zip (3.36 KB)

Hallo zurisee,

da darf ich mich als erster für dieses tolle Skript bedanken.

Habs grad mal ausprobiert und bin begeistert, ist wieder ein gutes Beispiel was so machbar ist, wenn man entsprechend php-fest ist.

Gruß
m-f-a