ich stehe auf dem Schlauch. Ich fahre mit einem einfachen Script meinen Rolladen runter. Dafür habe ich Ereignis eingerichtet, welches mir täglich zur gleichen Zeit das Script ausführt. Das geht auch gut.
Da ich jeodch nicht den Jalousieaktor verwende, möchte ich einen Status am Ende des Scripts setzen („Geschlossen“). Im Script verwende ich im HM-Befehl die Option „ON_TIME“, welche meinen Aktor für die eingestellte Zeit betätigt. Auch das geht. Setze ich die Variable Zustand nun auf „Geschlossen“, geschieht das gleich nach Absetzen des Schaltbefehls. Das möchte ich aber erst beim Abschalten des Aktos haben. Daraufhin habe ich einen Scripttimer gesetzt, der das Script erneut ausführen und die Zustand-Variable dabei setzen soll, ohne einen neuen Schaltbefehl zu senden.
Script ist hier:
<?
// Es wird der Rolladen für die ON_TIME-Zeit bewegt, über die gleiche Zeit ein Scripttimer im else-Zweig gesetzt, da
// das Script trotz Aktivität des Motors beendet ist.
// Nach Ablauf dieser Zeit wird das Script erneut gestartet - nun jedoch per TIMER-EVENT! Erst jetzt wird die
// Zustandsvariable gesetzt, um erst nach dem vollständigen Öffnen bzw. Schließen den Zustand richtig anzuzeigen.
if($IPS_SENDER == "TimerEvent" and $IPS_EVENT == "50359")
{
setvalue (33578 /*[Küche\Rolladen\eventid]*/ ,$IPS_EVENT);
// Zustand des Rolladens: offen -> false; geschlossen -> true
SetValue(14100 /*[Küche\Rolladen\aktueller Zustand]*/, true);
//Timer ausschalten
IPS_SetScriptTimer($IPS_SELF, 0);
setvalue(57692 /*[Küche\Rolladen\if]*/ ,true);
}
else
{
setvalue (40714 /*[Küche\Rolladen\else]*/ ,true);
// HM_WriteValueBoolean(30586 /*[Küche\Rolladen\Küche Rolladen hoch]*/ , "STATE", false);
// IPS_Sleep(500);
// HM_WriteValueFloat(54128 /*[Küche\Rolladen\Küche Rolladen runter]*/ , "ON_TIME", 25);
// HM_WriteValueBoolean(54128 /*[Küche\Rolladen\Küche Rolladen runter]*/ , "STATE", true);
//Timer anschalten
IPS_SetScriptTimer($IPS_SELF, 25);
}
?>
Leider wird das tägliche Event scheinbar nicht beachtet. Deshalb frage ich nach TIMER-EVENT und ID (50359 ist die ID des Scripttimers). Aber irgendwie durchläuft das Script nur den IF-Zweig. (Um dies nachvollziehen zu können, habe ich zum Test die Variablen if und else mal angelegt.) Auch ohne Tüttelchen (… and $IPS_EVENT == „50359“) oder mit einfachen will es nicht werden.
prinzipiell sehe ich hier keinen Fehler, bei mir funktioniert der Timer mit der if Konstrukition. Bau Dir doch mal einige Log Messages zur Kontrolle ein …
Hattest du mein Script mal probiert? Bin auch weiter gekommen. Hat scheinbar was mit dem Format der EVENT_ID zu tun. Habe nun beoachtet, dass der Scripttimer den Namen „ScriptTimer“ hat. Dazu habe ich dann die Funktion IPS_GetEventIDByName verwendet. Damit geht es (zumindest der Trockenlauf ohne die Motoren anzusprechen - Kommentare) ohne Probleme. Beim täglichen Event wird das else bearbeitet, dort der Scripttimer gesetzt. Beim erneuten Aufruf wird dann geprüft, ob der Aufruf durch genau diesen erfolgte -> if-Zweig . Und alles gut.
Kann man sich eigentlich auch Ausgaben einbauen (echo greift nicht), die dann im Meldungsfenster erscheinen, ohne im IPS Variablen anlegen zu müssen? Dein Logger wäre wohl eine Alternative, jedoch für mich auf die Schnelle nicht zu überblicken. Darum vielleicht vorerst kleine Schritte:)
Habe mein Script nun seit einigen Wochen lauffähig. Für jede Richtung eines Rolladens ein Sript. Nun sollen statt der bisherigen 2 Rolläden nach und nach alle über HM laufen. Da drängt sich der Gedanke auf, ein einziges Script für alle Richtungen und Rolläden zu machen.
Ich verwende als Grundgerüst eines der ehemaligen. Gespickt mit einigen Definitionen von Variablen mittels Swich-Anweisung, die die scriptauslösende Variable auswertet:
<?
// Es wird der Rolladen für die ON_TIME-Zeit bewegt, über die gleiche Zeit ein Scripttimer im else-Zweig gesetzt, da
// das Script trotz Aktivität des Motors beendet ist. Nach Ablauf dieser Zeit wird das Script erneut gestartet - nun
// jedoch per TIMER-EVENT! Erst jetzt wird die Zustandsvariable gesetzt, um erst nach dem vollständigen Öffnen bzw. Schließen den Zustand richtig anzuzeigen.
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
// Konfig
switch ($IPS_VARIABLE)
{
case 49652 :
$aktor_id = 30586 /*[Küche\Rolladen\Strassenfenster\Küche Rolladen hoch]*/;
$gegen_aktor_id = 54128 /*[Küche\Rolladen\Strassenfenster\Küche Rolladen runter]*/;
$fahrzeit = 25;
$akt_zustand_id = 14100 /*[Küche\Rolladen\Strassenfenster\aktueller Zustand]*/;
break;
case 10926 :
$aktor_id = 11820 /*[HWR\Rolladen\Strassenfenster\Rolladenmotor hoch]*/;
$gegen_aktor_id = 39125 /*[HWR\Rolladen\Strassenfenster\Rolladenmotor runter]*/;
$fahrzeit = 25;
$akt_zustand_id = 31338 /*[HWR\Rolladen\Strassenfenster\aktueller Zustand]*/;
break;
}
if($IPS_SENDER == "TimerEvent" and $IPS_EVENT == @IPS_GetEventIDByName("ScriptTimer", $IPS_SELF))
{
// zu setzender Zustand des Rolladens: offen -> false; geschlossen -> true
SetValue($akt_zustand_id, false);
//Timer ausschalten
IPS_SetScriptTimer($IPS_SELF, 0);
}
else
{
HM_WriteValueBoolean($gegen_aktor_id, "STATE", false);
IPS_Sleep(500);
HM_WriteValueFloat($aktor_id, "ON_TIME", $fahrzeit);
HM_WriteValueBoolean($aktor_id, "STATE", true);
//Timer anschalten
IPS_SetScriptTimer($IPS_SELF, $fahrzeit);
// Eintrag ins IPS-Log (Meldungen)
$objekt = IPS_GetObject($IPS_SELF);
IPS_LogMessage("Script ".$objekt['ObjectName'],"Schaltaktion wurde erfolgreich ausgeführt!");
}
?>
Bisher habe ich auch für jede Richtung und Script einen Scripttimer anlegen lassen, der nach Beenden der Fahrt eine Variable „aktueller Zustand“ entsprechend setzt.
Wie kann ich jetzt für jede Richtung und Rolladen einen Scripttimer anlegen bzw. wieder eindeutg auslesen? Macht es Sinn, eine zweite Switch-Anweisung anzulegen, in der ich die verschiedenen Scripttimer definiere (z.B. „ScriptTimer12345“ und per
switch ($IPS_EVENT)
auswerte? Oder gibt es eine elegantere Art der Lösung?
Ziel ist:
jeden Rolladen zu einer bestimmten Tageszeit fahren zu lassen
auf jeden Tastendruck der Rolladentaster entsprechend zu reagieren
für jeden Rolladen nach Ablauf den dann aktuellen Zustand zu schreiben. (Dabei gehe ich von entweder oben oder unten aus - also keine keine Zwischenzustände.)
Bin wieder bei o.g. Thema. Nun sind alle Rolläden dran. Somit habe ich 14 gleich aussehende Scripts. Diese würde ich dann auf zwei (oder sogar eines) reduzieren wollen.
Mein Problem ist weiterhin der Scripttimer, der ja nur für das ganze Script gilt. Wenn dieser läuft (und bei erneutem Durchlauf nur den Status in eine Boolean-Var. schreibt) könnte in dieser Zeit ein weiterer Scripttimer eines anderen Rolladens aktiviert werden. Der würde den alten doch überschreiben, oder? Wie halte ich diese dann auseinander?