WinLIRC Event Trigger

Hallo Forum,

habe folgendes Problem:
Über das Auswerten meiner WINLIRC Button Variable möchte ich bei dem Druck auf eine bestimmte Taste ein Skript auslösen (Je nach Status -> TV an/aus, Reciever an/aus, Strom an/aus). Der gesamte an/aus Vorgang dauert jeweils circa 7 Sekunden.

Ich triggere das Toggle Skript auf „Bestimmter Wert [z.B. eHome = grüner Windows Button auf der MCE FB] der Variable …\WinLIRC\Taste“

Soweit kein Problem.

Mein Problem ist, wenn man die Taste an der FB länger gedrückt hält, dann kommt der gleiche Tastendruck mehrfach bei IPS an, und das Skript wird mehrfach gestartet, je nach Toggle Status schaltet es dann an und aus und alles kommt durcheinander.

Sonstige Triggerevents die IPS anbietet wären:

  • Bei Variablenänderung -> Geht nicht, da ich ja eine bestimmte FB Taste als Trigger will
  • Bei Variablenaktualisierung -> Geht auch nicht, weil ich dann selbigen oben beschriebenen Effekt hätte.

Irgendwie sehe ich gerade keinen Lösungsweg, hat jemand vieleicht eine Idee?

Gruss,

wupperi

Mach den Haken „Nachfolgende Ereignisse ausführen“ weg. Dann kannst du jede Taste nur 1mal drücken und musst danach eine andere drücken, bevor die alten wieder geht. Ist also eine Kombination aus „Bei Änderung“ + „Bestimmter Wert“

Alternative b)


if (IPS_SemaphoreEnter($IPS_SELF, 1000)) //1 Sekunde totzeit
{
  //Befehle ausführen
  //...
  

  //Semaphore wieder freigeben!
  IPS_SemaphoreLeave($IPS_SELF);
}

Danke für die schnelle Antwort.
Methode 1 hatte ich schon probiert, geht nicht, da ja meine „ehome“ Taste ja ein toggle ist, diese also immer mindestens 2x gedrückt wird. (1x an 1x aus) mit o.g. Methode geht „aus“ dann nicht mehr.

Auch mit Methode b startet IPS mehrere Threads mit dem gleichen Skript.
Habe bei in der Doku gelesen, dass EnterSemaphore ja nicht verhindert, dass ein neues Skript gestartet wird, sondern nur die Abarbeitung aussetzt.

Ich muss aber doch verhindern, dass das Skript bei 5 Impulsen von FB überhaupt 5x gestartet wird.

Irgendwie stehe ich auf dem Schlauch!

Dann frag deine Triggervariable im Script ab.

Mal schnell getippselt.

$triggerVariable = IPS_GetVariable(12345);
if((time() - $triggerVariable['VariableUpdated']) < 2) return;

Hmmm…


 //Fügen Sie hier ihren Skriptquellcode ein
$triggerVariable = IPS_GetVariable(44957);
$zeit = time() - $triggerVariable['VariableUpdated'];
echo ($triggerVariable['VariableUpdated'] . "
");
echo $zeit;
if((time() - $triggerVariable['VariableUpdated']) < 2) return;

ergibt:


1293295789.808
5.1919996738434

egal in welchen Abständen ich drücke.

Ich poste mal mein Skript:


<?

 //Fügen Sie hier ihren Skriptquellcode ein
$triggerVariable = IPS_GetVariable(44957);
$zeit = time() - $triggerVariable['VariableUpdated'];
echo ($triggerVariable['VariableUpdated'] . "
");
echo $zeit;
if((time() - $triggerVariable['VariableUpdated']) < 2) return;




$id = 33616 /*[Hifi\Wohnzimmer\WinLIRC]*/;
$status = GetValueBoolean(54678 /*[Hifi\Wohnzimmer\Radio\Radiomodus]*/);



//Funktion zum ausschalten
   if ($status == 1) {
      ZW_SwitchMode (36481 /*[Hifi\Wohnzimmer\Z-Wave Strom Hifi Geraete (NodeID 020)]*/,false);
		setvalueboolean (54678 /*[Hifi\Wohnzimmer\Radio\Radiomodus]*/, false);

   }
	else
	{
//Funktion zum Einschalten
			setvalueboolean (54678 /*[Hifi\Wohnzimmer\Radio\Radiomodus]*/, true);
		 	setvalueboolean (17750 /*[Hifi\Wohnzimmer\Fernsehen\TV Modus]*/, false);
		 	zw_switchmode(36481 /*[Hifi\Wohnzimmer\Z-Wave Strom Hifi Geraete (NodeID 020)]*/, true);
			IPS_Sleep (2000);
			
			if (getvalue(34916 /*[Hifi\Wohnzimmer\Fernsehen\TV ausgefahren]*/) == 1){
				winlirc_SendOnce ($id, "fb_mce", "power");
				ips_sleep(1000);
				winlirc_SendOnce($id, "fb_tv", "tv_power");
		 		winlirc_SendOnce($id, "fb_tv", "tv_power");

				 setvalue (34916 /*[Hifi\Wohnzimmer\Fernsehen\TV ausgefahren]*/, false);
		 		}

			IPS_Sleep(5000);
	    	winlirc_SendOnce($id, "FB_Kenwood", "dvd/6ch");

		 
		}
	


?>

Kann dir jetzt nicht ganz folgen. Der Schnippsel funktioniert einwandfrei.

Ich glaub, Du hast da einen Denkfehler. Du musst in den Meldungen nachsehen. Wenn Du das Script von Hand startest, musst Du schon schnell sein. :wink:

Noch ein Tip, alles was größer 1sec Wartezeit ist, ist es besser einen Scripttimer zuverwenden. Ansonsten blockierst Du dir den Thread

Ich verstehe es irgendwie nicht.

 $zeit = time() - $triggerVariable['VariableUpdated']; 

wirft mir im Meldungfenster immer irgendwelche negativen Zahlen raus, egal wie schnell oder langsam ich die FB Taste drücke. Zwischen -0.000xxxx - -0.8xxxxxx. Demzufolge greift auch immer „if“ und das Skript wird nie zu Ende ausgeführt.

ist es besser einen Scripttimer zuverwenden

Meinst Du IPS_SetScriptTimer ($IPS_SELF,$time) ?
Die setzte mir doch nur einen Event, der das Skript nochmals nach $time auslöst, oder? Was ich brauch ist ja eine Verzögerung der sequenziellen Abarbeitung des Skripts?

Ich glaube ja, dass der Code keinen Fehler wirft, ich verstehe es nur nicht. Ist halt wie immer, das Problem ist an der Tastatur…

Vielleicht wird es dir damit klarer.

$triggerVariable = IPS_GetVariable(44957);
$zeit = time() - $triggerVariable['VariableUpdated'];
echo "Der letzte Trigger erfolgte am ".date('d.m.y - H:i:s' , $triggerVariable['VariableUpdated'])."
";
echo "Seit der letzten Ausführung sind ".gmdate('H:i:s', $zeit)." vergangen!";
if((time() - $triggerVariable['VariableUpdated']) < 2) return;

In welchen Abständen kommen denn die Befehle von der Fernbedienung, eventuell muss man mit microtime arbeiten.

Ok, date formatiert und gibt mir den Timestamp ‚VariableUpdated‘ raus.
GMDate macht das Gleiche nur auf GMT bezogen.

Wenn ich das Skript ausführe zeigt er mir auch tatsächlich 00:05:42 als $zeit…

Denke das hat mir schonmal wieder ein Stück weitergeholfen, sobald ich unten am TV es live probiert habe melde ich mich.
Wenn man den Knopf gedrückt hält kommen die Befehle alle ca 300-500ms.

Aber irgendwie habe ich noch einen Denkfehler:

Ich will ja verhindern, dass ein Druck auf der FB von ca. 2 sekunden das Skript neu startet.
Wenn ich das Schalten m Skript nur ausführe, wenn $zeit grösser 2 Sekunden und jemand dauernd drückt, dann wird das Skript ja nie zu Ende ausgeführt, weil ‚VariableUpdated‘ ja auch permanent mit der aktuellen Zeit upgedatet wird?

Vielen Dank für Deine Hilfe. Unsere vorherigen Posts hatten sich zeitlich überschnitten, ggfls. kannst Du nach dem Skripttimer auch mal sehen [Schamesröte on…]

Probier das mal, das sperrt das Script für eine angegebene Zeit.

switch ($IPS_SENDER)
{
    case "Variable":                              
    if (IPS_GetScriptTimer($IPS_SELF) == 0)
    {                                           
        IPS_SetScriptTimer($IPS_SELF, 60); //Zeit anpassen
        $id = 33616 /*[Hifi\Wohnzimmer\WinLIRC]*/;
        $status = GetValueBoolean(54678 /*[Hifi\Wohnzimmer\Radio\Radiomodus]*/);
        //Funktion zum ausschalten
        if ($status == 1)
        {
            ZW_SwitchMode (36481 /*[Hifi\Wohnzimmer\Z-Wave Strom Hifi Geraete (NodeID 020)]*/,false);
            setvalueboolean (54678 /*[Hifi\Wohnzimmer\Radio\Radiomodus]*/, false);
        }
        else
        {
            //Funktion zum Einschalten
            setvalueboolean (54678 /*[Hifi\Wohnzimmer\Radio\Radiomodus]*/, true);
            setvalueboolean (17750 /*[Hifi\Wohnzimmer\Fernsehen\TV Modus]*/, false);
            zw_switchmode(36481 /*[Hifi\Wohnzimmer\Z-Wave Strom Hifi Geraete (NodeID 020)]*/, true);
            IPS_Sleep (2000);

            if(getvalue(34916 /*[Hifi\Wohnzimmer\Fernsehen\TV ausgefahren]*/) == 1)
            {
                winlirc_SendOnce ($id, "fb_mce", "power");
                ips_sleep(1000);
                winlirc_SendOnce($id, "fb_tv", "tv_power");
                winlirc_SendOnce($id, "fb_tv", "tv_power");
                setvalue (34916 /*[Hifi\Wohnzimmer\Fernsehen\TV ausgefahren]*/, false);
            }
            IPS_Sleep(5000);
            winlirc_SendOnce($id, "FB_Kenwood", "dvd/6ch");
        }
    }
    else return;
    break;
    case "TimerEvent":
    IPS_SetScriptTimer($IPS_SELF, 0);
    break;
}  

Hallo Rainer,

[EDIT: Gerade obigen Beitrag gepostet, als ich schrieb, deswegen gelöscht.]

Auch mit Methode b startet IPS mehrere Threads mit dem gleichen Skript.

Das ist doch auch egal. :slight_smile: Du willst ja, dass dein Code nicht doppelt ausgeführt wird… Ob nun das Skript ansich mehrfach ausgeführt wird, ist doch egal. RWNs Vorschlag macht das selbe… Ich mag aber meine zwei Zeilenlösung lieber :slight_smile:

Es ist übrigens nicht möglich, dass das Skript nicht mehrfach ausgeführt wird. Auch wenn du den Timer deaktivierst, und wieder reaktivierst… Das sind auch 2 Vorgänge… und wenn jetzt der zweite Tastendruck schneller ist, als die Ausführung des ersten Skripts… Juhu…

paresy

Parse error: syntax error, unexpected T_CASE in [Hifi\Wohnzimmer\Radio\Radio toggle] on line 36

Fehlt da nicht eine Variable? Case (xy = „text“):

Selbst wenn ich die Semaphorendauer auf 10s setze wird bei einem Dauerdruck auf die FB der Code ausgeführt.

Das gibts doch gar nicht, es muss doch eine Möglichkeit geben eine Fernbedienungstaste die ein Skript triggert innerhalb von IPS zu „entprellen“ ??? :confused:

Ich will einfach nur, dass ein zu langer Tastendruck nicht gleich ein doppeltes Schalten auslöst…

Semaphore geht bei mir auch nicht. Mein Script von oben führt den Befehl genau einmal aus.

@Rainer:

Jetzt gehts-ich Idiot hatte zwei Zeilen nicht kopiert…grrr…Danke Dir.