Ereignis per Script starten

Hallo Leute!

Ich suche eine Möglichkeit, ein Ereignis per Skript zu starten. Ich verwende Ereignisse um bei An- bzw. Abwesenheit bestimmte Aktionen auszuführen. Wenn ich nun beispielsweise von Anwesenheit auf Abwesenheit umschalte passiert folgendes:
Alle Ereignisse für Modus „Anwesend“ werden deaktiviert
Alle Ereignisse für Modus „Abwesend“ werden aktiviert

Nehmen wir an, dass es ein Ereignis „Licht aus“ im Modus „Abwesend“ mit der Ausführungszeit 14:00 gibt. Wenn ich um 15:00 auf „Abwesend“ umschalte, liegt dieses Ereignis in der Vergangenheit; das Licht sollte aber trotzdem ausgehen.

Ich würde nun also per Skript nach Ereignissen suchen die in der Vergangenheit liegen und dem aktuellen Präsenzmodus entsprechen. Wenn ein solches Ereignis gefunden wird, soll es sofort ausgeführt werden.

Hat jemand eine Tipp wie ich das umsetzen kann?

LG
Hugo

Schon mal einen Blick hier rein geworfen.

Ereignisverwaltung: IP-Symcon :: Automatisierungssoftware

Aber klar doch. Das Ereignis zu finden ist kein Problem. Nur so etwas wie „event_execute“ gibt es nicht. Ich habe schon überlegt, die Ausführungszeit mit der aktuellen Zeit + 1 Minute zu überschreiben; ist aber auch keine Lösung weil es dann mitunter bis zu einer Minute geht bis das Ereignis ausgelöst wird.

LG
Hugo

Dein Konzept ist etwas seltsam, aber IPS_SetEventCyclicTimeBounds kann ein Event doch auf die Sekunde genau setzen.

Wieso findest du das Konzept seltsam? Wie würdest du das umsetzen?

Ich habe ein Anwesenheitsscript welches durch alle Aktoren getriggert wird welche dafür relevant sind. Hier wird für jeden Raum ein entsprechendes Flag gesetzt. Sonst schalte ich eher nicht zeitgesteuert, sondern durch andere Events (Taster, Touch, Scriptbezogen etc.)

Hallo Thomas!

Hatte ich zuerst auch so. Ich versuche es aber nun mit Events umzusetzen - hauptsächlich aus folgenden Gründen:

  • Skript muss regelmäßig aufgerufen werden (jede Minute oder so)
  • Für jede Änderung muss das Skript editiert werden - ist also nicht Ehefraukompatibel :slight_smile:

Ich habe nun im Webfront eine Seite, ähnlich wie in dein Wecker gemacht, bei dem die Konfigurationen der Aktoren definiert werden können abhängig von Uhrzeit, Anwesenheitsprofil und Sonnenstand. So kann auch meine Frau bequem einstellen, dass sie bei Anwesenheit und intensiver Sonneneinstrahlung gerne die Rollos auf Halbmast hätte oder Dimmer bei Sonnenuntergang bei 10%, bei Sonnenuntergang + 5 Minuten bei 20% …
Ich habe ein Skript, das um Mitternacht ausgeführt wird und abhängig von den eingestellten Konfigurationsparametern Events generiert und nur die Events des aktuellen Anwesenheitsprofils aktiviert. Die Events des Vortages werden mit dem selben Skript gelöscht.

Ich habe auf deine Empfehlung hin die Ausführung der Events in der Vergangenheit, mit IPS_SetEventCyclicTimeBounds gemacht. Das funktioniert nach einigem Try and Error. Problem hierbei ist, dass je nach Anzahl an Events es einige Zeit dauert bis die Zeit gesetzt wird. Ich rechne nun 10 Sekunden zu der aktuellen Zeit dazu und beobachte, ob es zuverlässig funktioniert.

Danke für deine Hilfe!
LG
Hugo

Schau dir an, wie Ereignisse in IP-Symcon funktionieren. Es gibt so gesehen 2 Arten von Ereignissen. Die erste startet beim Auslösen ein Skript. Die andere startet beim Auslösen ein inline Skript.

Du sucht also wie beschrieben deine Ereignisse raus, und dann startest du bei Art1 das verknüpfte Skript (= Der Parent vom Ereignis) per IPS_RunScript. Bei Art2 liest du das inline Skript über die ScriptText Eigenschaft aus und lässt es per PHP und eval ausführen.

Tricky ist ein wenig die $_IPS[li] Variablen zu emulieren. Das musst du dir dann anhand der Doku und den verfügbaren Systemvariablen ein wenig selber zusammenfummeln.[/li]
paresy

Hallo Paresy!

Ich kann deinen ausführungen bis „eval“ folgen (was meinst du damit?). Ich verwende demnach die Art 2 und kann auch die ScriptText Eigenschaft auslesen. Mir ist nur nicht klar, wie ich aus einem Script heraus eine RegisterVariable ändern kann, da die ja mit der Instanz verknüpft und sonst auf ReadOnly ist. Das Ereignis geht auf die Instanz los und führt Befehle wie z.B: SC_MOVE oder so aus … vielleicht verstehe ich da auch was falsch.

LG
Hugo

Erklär mal ein wenig mehr was du machen willst. Ich vermute eher, dir ist noch nicht so richtig bewusst, wie genau IP-Symcon funktioniert bzw. willst du an der falschen Stelle etwas verändern :slight_smile:

Hier zu eval:
PHP: eval - Manual

paresy

Hallo Paresy!

Vielen Dank für die rasche Rückmeldung. Du hast sicherlich nicht ganz Unrecht mit deiner Vermutung, aber ich beschäftige mich intensiv mit dem Thema und mache Fortschritte :slight_smile:

Ich versuche es mal anhand eines Beispiels zu erklären.

Um Mitternacht wird über ein Ereignis ein Script angetriggert, das u.a. einen Event anlegt, der einen Dimmer im Wohnzimmer auf 70% stellen soll.


$Befehl = array(1 => "HM_WriteValueFloat(\$IPS_TARGET, 'LEVEL', $Aktion);", 2=> "HM_WriteValueBoolean(\$IPS_TARGET, 'STATE', " . ($Aktion ? 'true' : 'false') . ");", 3 => "SC_MoveUp(\$IPS_TARGET, $Aktion);");
$eid = IPS_CreateEvent(1);
IPS_SetEventCyclic($eid, 0, 0, 0, 2, ($Zeit["repeat"] ? 2 : 0) ,1); //Zeitintervall auf eine Minute stellen, bei "repeat=true" jede Minute wiederholend
IPS_SetEventCyclicTimeBounds($eid, mktime($Zeit["hour"], $Zeit["minute"], 0), 0); 
IPS_SetName($eid, ($Praesenz ? "Anwesend " : "Abwesend ") . ips_GetName($ObjectID*1)); 
IPS_SetParent($eid*1,$ObjectID*1); //Event an den richtigen Ort verschieben
IPS_SetEventScript($eid, $Befehl[$Typ*1]); 
IPS_SetEventActive($eid,false);  

Abhängig vom Name des Events werden danach die Events die dem aktuellen Anwesenheitsprofil entsprechen aktiviert (Anwesend oder Abwesend).

Wenn sich nun im Laufe des Tages das Anwesenheitsprofil ändert (z.B. von Anwesend auf Abwesend) wird geprüft, ob es im nun aktuellen Profil (Abwesend) ein Ereignis gibt das in der Vergangenheit liegt und noch nicht ausgeführt wurde. Wenn solche Ereignisse gefunden werden, wird das jüngste Ereignis verwendet und ausgeführt (und das mache ich jetzt mal übergangsweise mit der oben beschriebenen Variante mit IPS_SetEventCyclicTimeBounds). Also am Beispiel Dimmer:

Profil Anwesend: 17:00 Uhr Dimmer 60%
Profil Anwesend: 20:00 Uhr Dimmer 80%
Profil Abwesend: 18:00 Uhr Dimmer 0%
Profil Abwesend: 19:00 Uhr Dimmer 50%

Um 18:15 wird von Anwesend auf Abwesend gewechselt. Der Dimmer ist bei 60% (Anwesend) und muss auf 0% (jüngstes Event in der Vergangenheit) schalten. Um 19:00 schaltet der Dimmer auf 50%.
Wenn um 19:15 wieder auf Anwesend gewechselt wird, muss der Dimmer auf 60% (jüngster Event um 17:00 Uhr).

So habe ich es mir vorgestellt und auch schon umgesetzt. Wenn ich die Ausführungszeit der Events auf 10 Sekunden nach der aktuellen Zeit ändere werden sie auch ausgeführt, aber ich habe die Befürchtung, dass je nach Auslastung des Systems das unzuverlässig ist (ich habe beobachtet dass es mitunter mehrere Sekunden dauert, bis der Skriptbefehl beim Ereignis ankommt).

Ich hoffe, ich habe es halbwegs verständlich erklärt was ich machen will.

Danke für die Tipps im Voraus!
LG
Hugo

Ja. Dann starte doch einfach direkt den Befehl über eval($Befehl[$Typ*1]). Wie du dann merken wirst, wird $IPS_TARGET fehlen, welches du dann noch definieren musst. Oder du trägt direkt deine IDs hardcoded rein.

paresy

Hallo Paresy!

Und schon wieder was gelernt! Funktioniert perfekt!

Vielen Dank!
LG
Hugo