Skript über Variable starten, warum springt die Variable zurück?

Servus,

bin noch neu im Geschäft, hatte jetzt ein paar Monate pause, jetzt mit neuen Komponenten, werden auch neue Ideen umgesetzt.

Ich will nur ne Kleinigkeit machen, funktioniert aber leider nur halb! :slight_smile:

Ich hab ne Variable (Boolean, Fals), ID 14762, angelegt, welche ein „Switch“ Profil hinterlegt hat, (false = aus, true = an) so der Plan.

Dann habe ich ein Skript „dahinter“:

<?

$Request = GetValue(14762);


if ($Request = false) 
    {
          
    } 
    else 
    {
        HM_WriteValueBoolean(17228, "STATE", true);
        IPS_Sleep(1000);
        HM_WriteValueBoolean(17228, "STATE", false);
        HM_WriteValueBoolean(57134, "STATE", true);
        IPS_Sleep(1000);
        HM_WriteValueBoolean(57134, "STATE", false);
        HM_WriteValueBoolean(17838, "STATE", true);
        IPS_Sleep(1000);
        HM_WriteValueBoolean(17838, "STATE", false);
        HM_WriteValueBoolean(42620, "STATE", true);
        IPS_Sleep(1000);
        HM_WriteValueBoolean(42620, "STATE", false);
        HM_WriteValueBoolean(19492, "STATE", true);
        IPS_Sleep(1000);
        HM_WriteValueBoolean(19492, "STATE", false);
        HM_WriteValueBoolean(15067, "STATE", true);
        IPS_Sleep(1000);
        HM_WriteValueBoolean(15067, "STATE", false);
    }

?>

Soweit so gut. Wenn ich jetzt die Variable „anklicke“ läuft mein Skript auch an. Das ist die Hälfte die Funktioniert. Aber leider bleibt das "An"nicht Blau sondern die Variable scheint direkt wieder auf fals (=Aus) zu springen. Gut sonst würde mein Skript auch wieder von vorne los laufen, aber das wäre mir dann aufgefallen und nicht jetzt beim Tippen! :slight_smile: Aber grundsätzlich müsste die Variable doch auf true stehen und nicht wieder „von allein“ zurück springen, oder?

Gruß Sven

wenn die Variable auf true stehen würde, könne ich das gleich als anzeige nutzten, das das skript am laufen ist.

so war der Plan…

Da ist kein SetValue in deinem Script, welches die Variable jemals setzen könnte.
Somit bleibt die immer im alten Zustand.
Das AktionsSkript in der Doku zeigt die eine Zeile welche es braucht damit die Variable umspringt.
Beispiel 1:
Aktionsskripte — IP-Symcon :: Automatisierungssoftware

Da Scripte nach Möglichkeit niemals so lange mit Sleep pausieren sollten, löst man das mit einer weiteren Variable als Zähler und einem ScriptTimer.
Das Beispiel finde ich aber von unterwegs gerade nicht :frowning:
Michael

Du willst auf false prüfen das wäre


if($Request == false)

oder


if(!$Request) 

Wenn Du nur ein = setzt heisst das, dass Du den Wert auf false setzt nicht das Du auf false vergleichst. Dazu musst Du == benutzten.

Morgen,

bin ja auch doof :slight_smile: Das Skript startet ja nicht, weil die Prüfung klappt, sonder weil es eine Aktion der Variablen ist.

Habe es jetzt auch anders gelöst. Ich habe 2 Variablen gemacht. Mit der Einen starte ich nur das Skript als Aktion, dann schreibt das Skript in die andere Variable „1“ beim start und „0“ beim ende. Diese Variable zeigt dann bei „1“ das es Läuft und bei „0“ das es Aus ist.

So passt mir das. Hoffe das ist auch von der Umsetzung her Ok. Leider komme ich gerade nicht an mein Skript ran, sonst hätte ich den Code noch zum Verständnis gepostet, werde ich nachholen.

Nächste Baustelle. Der „IPS_Sleep(1000)“ ist nur ein Zwischenschritt. genau genommen muss dazwischen 15-20min gewartet werden.

Irgendwo habe ich im Hinterkopf, gelesen zu haben, dass ein Skript nur 30sek dauern darf, stimmt das?

Wie kann ich das dann realisieren?

Viele Grüße

Hi
ich mach das mit den Pushbuttons generell so:

„SetValue($_IPS[‚VARIABLE‘], $_IPS[‚VALUE‘]);“
Dies wird als Aktionsscript bei der Buttonvariable hinterlegt. Damit toggelt schon mal der Button im WF, tut aber noch nichts.

Um nun ein oder mehrere Scripte durch den Button zu starten füge ich dem Script ein Ereignis hinzu welches durch die Buttonvariable ausgelöst wird. Da kann man dann schon mal gleich vorauswählen ob das Ereignis bei True/False usw. auslöst und man spart sich die Abfrage im Script.

Weiters läßt sich sich damit das Script für debugzwecke auch jederzeit händisch starten. Hast du nämlich IPS_[Value] oder so im Script läuft es nicht händisch, da ihm ja IPS[Value] fehlt.

Für Quick/Dirty Sachen finde ich die Methode recht brauchbar, bei komplexeren Aufgaben lohnt es sich aber den Button anzeigen zu lassen ob die Aufgabe auch erforlgreich war.

Zu IPS_Sleep: Ja lange „Sleep“ oder „Wait“ haben in einem ereignisgesteuertem System nichts zu suchen.
Die Vorgehensweise ist folgende: Dort wo du das Sleep benötigst startets du einen Timer mit der gewünschten Wartezeit und terminierts das Script.
Dann brauchst ein Ereignis welches durch den Timer ausgelöst wird. d.h. der Timer startet nach Ablauf der Zeit das Script neu.
Innerhalb des Scriptes fragst du nun ab wer es gestartet hat.
War es der Timer wird der Teil ausgeführt welcher nach Ablauf des Sleep vorgesehen war.
War es etwas anderes, dann normaler Start.

Ich glaub irgendwo in der Hilfe gibt es auch ein schönes bsp. dazu, finds aber grad net.

gruß
bb

Richtig.

Du realisierst es so, wie es Dir weiter oben vorgeschlagen wurde. Beispielsweise über eine Hilfsvariable, die bei jedem Aufruf des Skriptes um 1 hochgezählt wird. Beim Aufruf des Skriptes fragst Du die Variable ab. Ich nutze dazu PHP switch. Innerhalb der case Angaben setzt Du einen Skripttimer auf das Skript und zählst die Hilfsvariable um 1 hoch. Im letzten Schritt setzt Du den Timer auf 0 und die Hilfsvariable ebenfalls.

Morgen,

Ok, leider weiß ich noch absolut nicht, wie ich das umsetzten kann, wenn du nen Anleitung kennst oder ein Beispiel schick mal bitte, damit ich mich da schlau machen kann.

Danke! Gruß
Sven

Wie kann ich … ?

Fonzo hats gefunden und war mal wieder schneller.

Ein Beispiel kann ich dir gerne geben, allerdings wurden durch den aktuellen Hype alles in ein Modul zu pressen viel meiner älteren Scripte entsorgt.
Dieses ist mir geblieben, da es recht einfach ist könntest du evtl. was nützliches rauslesen:
Das Script kann folgendes:
Per Variable im Webfront kann man verschiedene Modi der Gartenbewässerung einstellen.
Ein / Aus / 1x Ein für bestimmte Zeit / jeden Tag ein für bestimmte Zeit Ein
Die Zeit wie lange die Bewässerung eingeschaltet sein soll ist auch per Webfront einstellbar.

Und darum geht es auch bei dir. Die Einschaltzeit (bei mir mehrere Minuten, bei dir Sekunden) darf man nicht per IPS_Sleeep erzeugen.
Daher wird das über einen Timer gemacht.

<?

$idEventDay =12301 /*[Program\Bewässerung\Blumenbeet & Garten\Ein]*//*[Program\Bewässeung\Blumenbeet & Garten\]*/;
$idEventDayOff = 13138 /*[Program\Bewässerung\Blumenbeet & Garten\Aus]*/;
$idEventDuration = 44905 /*[Program\Bewässerung\Blumenbeet & Garten\setStatus Blumenbeet\Täglich alle 15 Minuten]*/;
$idDuration = 46669 /*[Program\Bewässerung\Blumenbeet & Garten\Dauer]*/;
$idSelection = 36555 /*[Program\Bewässerung\Blumenbeet & Garten]*/;
$idValveStatus = 52873 /*[Program\Bewässerung\Garten_Status]*/;

Switch ($_IPS['SENDER'])
	{
	Default:
	   break;

	Case "TimerEvent":
     if ($_IPS['EVENT']== $idEventDuration) {
         if (GetValue($idSelection)==2) {
		 	SetValue($idSelection,0);
         	IPS_SetEventActive($idEventDuration,False);
         	}
		 }
	  break;

   Case "Execute":

	Case "Variable":
	
	$callerVar = $_IPS['VARIABLE'];
	If ($callerVar == $idDuration) {
			IPS_SetEventCyclic ($idEventDuration , 0, 0, 0, 0, 2,GetValue($idDuration));
			 IPS_SetEventCyclicTimeFrom($idEventDuration,date('H', time()),date('i', time()),date('s', time()));
         if (GetValue($idSelection)==2) {
				IPS_SetEventActive($idEventDuration,True);
         	SetValue($idValveStatus,True);
         }
		}

	if ($idSelection) {
		if (GetValue($idSelection) ==0) {   /* AUS*/
			SetValue($idValveStatus,False);
			IPS_SetHidden ($idDuration,True);
			IPS_SetHidden ($idEventDay,True);
			IPS_SetHidden($idEventDayOff,True);
            IPS_SetEventActive($idEventDuration,False);
			IPS_SetEventActive($idEventDay,False);
			IPS_SetEventActive($idEventDayOff,False);
			
		}

		if (GetValue($idSelection)==1) {  /*EIN*/
			SetValue($idValveStatus,True);
			IPS_SetHidden ($idDuration,True);
			IPS_SetHidden ($idEventDay,True);
			IPS_SetHidden($idEventDayOff,True);
			IPS_SetEventActive($idEventDuration,False);
			IPS_SetEventActive($idEventDay,False);
			IPS_SetEventActive($idEventDayOff,False);
		}

		if (GetValue($idSelection)==2) { /* Timer 1x*/
            IPS_SetEventCyclicTimeFrom($idEventDuration,date('H', time()),date('i', time()),date('s', time()));
			SetValue($idValveStatus,True);
			IPS_SetHidden ($idDuration,False);
			IPS_SetHidden ($idEventDay,True);
			IPS_SetHidden($idEventDayOff,True);
			IPS_SetEventActive($idEventDuration,True);
		}

		if (GetValue($idSelection)==3) { /* Timer täglich */
			IPS_SetHidden ($idDuration,True);
			IPS_SetHidden ($idEventDay,False);
			IPS_SetHidden($idEventDayOff,false);
			IPS_SetEventActive($idEventDuration,False);
			SetValue($idValveStatus,False);
			IPS_SetEventActive($idEventDay,true);
		}

      if (GetValue($idSelection)==4) { /* Timer täglich ausgelöst durch Timer*/
			IPS_SetHidden ($idDuration,False);
			IPS_SetHidden ($idEventDay,False);
			IPS_SetEventActive($idEventDuration,True);
			SetValue($idValveStatus,true);
			IPS_SetEventActive($idEventDay,true);
		}


	}
}

?>

der Verzeichnisbaum dazu sieht so aus:

schöne Grüße
Bernhard

Guten Tag,

musste leider ein paar Tage „aussetzten“ sitze aber wieder an meinem Problemchen.

Die Grundvoraussetzung habe ich denke ich geschaffen, jetzt fehlt mir nur noch ein Skript welches nach einander Geräte (bei mir auch die Bewässerung) ein und aus schaltet.

Wenn Zeitsteuerung aktiv (wird per Variable im WF eingestellt) dann starte täglich um 6 Uhr (ist einfach ein Ereignis mit der Bedingung das die Variable true sein muss) folgendes Skript)

schalte sprinkler 1 ein
warte 20min
schalte sprinkler 1 aus
schalte sprinkler 2 ein
warte 20min
schalte sprinkler 2 aus
schalte sprinkler 3 ein
warte 20min
schalte sprinkler 3 aus


Die Sprinkler sind Magnetventiele die per HomeMatic IP Wired Schaltaktor angesteuert werden, das funktioniert soweit auch, ich hänge einfach nur an der Umsetzung des Scripts mit den 20min „delays“…

Ich verstehe, das es über die Timergeschichte gemacht werden soll, blicke aber noch nicht wie…

Vielleicht hat noch jemand nen guten Tipp…

Gruß Sven

Du möchtest hier die Funktion IPS_SetScriptTimer verwenden. Damit rufst du das Ereignis nach einer vorgegebenen Zeit erneut auf. Im Skript kannst du dann schauen, welcher Sprinkler gerade an ist und handelst entsprechend. Danach setzt du den SkriptTimer erneut, damit nach 20 Minuten der nächste Durchlauf erfolgt oder auch nach dem Ausschalten von Sprinkler 3 nichts mehr passiert.

Wenn du eine Skriptärmere Lösung suchst, dann kannst du natürlich auch 3 weitere zyklische Ereignisse für 6:20, 6:40 und 7:00 erstellen.

Hallo,

ja daran hab ich auch schon gedacht, mehrere Ereignisse zu machen, ich würde aber auch gerne per Schalter sagen können, so, jetzt mal bewässern, das wiederum geht dann mit mehreren Ereignissen ja nicht.

Also muss ich lernen wie „IPS_SetScriptTimer“ funktioniert, wo ich auch nichts gegen hab, lernen ist immer gut, mach es mir grad nur glaub ich etwas schwer…

Wenn mir jemand den Anfang etwas für dummies kann zeigen, klappt das schon…

steht schon grundsätzlich auf dem schlauch, das funktioniert doch fast wie ne schleife, der macht alle (in meinem fall) 20 min das selbe. bis man sagt, schluss.

oder?

Vielleicht kann mir jemand den Anfang zeigen?

macht das irgendwie sinn?

die idee ist, das der timer alle 20min, zum testen alle 2 sek das skript startet.

jetzt muss in dem skript ja entschieden werden, was zu tun ist.

also variable für die 4 abschnitte definiert und per if überprüft, was zu tun ist…

<?

SetValue(34376, 1);

$Sprinkler = "1";

if($_IPS['SENDER'] == "TimerEvent")
{
    //Aus Befehl
    
 
    //Timer ausschalten
    IPS_SetScriptTimer($_IPS['SELF'], 0);
} else {
    
    $Sprinkler = "1";

    if ($Sprinkler == 1) 
        {
            HM_WriteValueBoolean(49862, "STATE", true);
            $Sprinkler = "++";
        }
    if ($Sprinkler == 2) 
        {
            HM_WriteValueBoolean(49862, "STATE", false);
            HM_WriteValueBoolean(33399, "STATE", true);
            $Sprinkler = "++";
        }
    if ($Sprinkler == 3) 
        {
            HM_WriteValueBoolean(33399, "STATE", false);
            HM_WriteValueBoolean(44103, "STATE", true);
            $Sprinkler = "++";
        } 
    if ($Sprinkler == 4) 
        {
            HM_WriteValueBoolean(44103, "STATE", false);
            $Sprinkler = "++";
        }
    //Timer anschalten
    IPS_SetScriptTimer($_IPS['SELF'], 2);
}

SetValue(34376, 0);

?>

Deine Verwendung von $Sprinkler wird so nicht funktionieren, da dies eine lokale Variable ist, die bei jedem Skriptaufruf neu initialisiert wird. Außerdem wirst du so direkt nach der ersten Ausführung ausschalten, da du ja bei einem TimerEvent aufhörst. Dies triggert auch bei einem SkriptTimer.

Mein Ansatz wäre also etwas in der Form:



// Alle aus -> Erste Ausführung
if (!GetValue(11111 /* Sprinkler 1 */) && !GetValue(22222 /* Sprinkler 2 */) && !GetValue(33333 /* Sprinkler 3 */) { 
  RequestAction(11111, true); 
  IPS_SetScriptTimer($_IPS['SELF'], 1200); 
}
// TODO: Hier mit den dazwischenliegenden Fällen auffüllen ...
// Nur der dritte an -> Abschalten
else if (!GetValue(11111 /* Sprinkler 1 */) && !GetValue(22222 /* Sprinkler 2 */) && GetValue(33333 /* Sprinkler 3 */) {
  RequestAction(33333, false);
  IPS_SetScriptTimer($_IPS['SELF'], 0);   
}