Kurzer / Langer Tastendruck auswerten

Hallo,

ähnlich zu diesem Thema von 2010 (https://www.symcon.de/forum/threads/10385-Auswertung-Kurzer-langer-Tastendruck) bin ich dran, einen Taster mit Shelly 2.5 in IPS einzubinden.

Ich brauche innerhalb des Skriptes die Dauer, wie lange die Taste gedrückt wird. Ich hatte gedacht, dass mittels microtime() zu realisieren, ich weiß aber nicht, wie ich den Zeitstempel auslesen kann, wann die Variable das letzte Mal aktualisiert wurde und das dann als Zeitspanne darstellen kann. Ich habe zwar die Hilfe https://www.symcon.de/forum/threads/28210-IP-Symcon-Wie-kann-ich-2-0?p=259927#post259927 gefunden, wie das mit time() funktioniert, aber ich benötige es mit microtime(), um genauer steuern zu können.

Hat jemand einen Tipp für mich?

Hi,
ich weiß jetzt nicht wie dein Schalter reagiert aber ich könnte mir vorstellen das es wie folgt geht könnte:
Ereignis auf Änderung des Tastendrucks.

Im Script dann
wenn Taste gedrückt microtime auslesen und in Variable speichern
wenn Taste losgeless microtime auslesen und variable abziehen.

Wenn Differenz > x microsekunden dann lang sonst kurz.

Ralf

Wenn die Variable geloggt ist, musst du die Zeit gar nicht abspeichern und kannst sie dir stattdessen aus den geloggten Daten holen

Geht das dann auch so genau wie bei microtime oder im Sekundentakt?

Ah, du hast recht. Die geloggte Zeit wäre nur sekundengenau. Damit funktioniert mein Vorschlag nicht.

Was ist mit:

$_IPS[‚OLDCHANGED‘]
(ab Version 5.1)
Zeitstempel der letzten Änderung des alten Wertes

https://www.symcon.de/service/dokumentation/konzepte/skripte/systemvariablen/

Ist das genauer als Sekunden?

Hi,
ich schätze nicht. Das wird einfach der ausgelesene Wert sein der vorher der Variablen zugeordnet war.

Ralf

„Zeitstempel der letzten Änderung des alten Wertes“, die Frage ist nur, in welcher Auflösung ;).

Hallo Ralf,

danke erstmal, vom Ansatz her ist das richtig. Wie bekomme ich aber denn die While-Bedienung hin?
Ich muss ja irgendwie prüfen, ob die Taste noch gedrückt ist.

Gruß, Peter

Dann antwortet mal der andere Ralf :D.

Keine while Bedingung sondern zwei Ereignisse für das Script, eines auf TRUE und eines auf FALSE.


<?php

if ($_IPS['SENDER'] == "Variable") {
	switch ($_IPS['EVENT']) {
		case "46315":     // Taster gedrückt
            $time_start = microtime(true);
            SetValueFloat(42023, $time_start);
		break;
		case "22145":     // Taster losgelassen
            $time_end = microtime(true);
            $time_start = GetValueFloat(42023);
            $time_pressed = $time_end - $time_start;
            echo "LongPressTest Drückdauer: " . $time_pressed;
		break;
    }
}

Update:
Gerade mit einem Enocean Taster getestet und es funktioniert. Das wollte ich schon immer mal ausprobieren :).

Wenn deine Hardware/Taster nur TRUE liefert, dann klappt das so nicht.

Update2:
Jetzt wieder ordentlich mit PHP Tags und Code.

Hallo Ralf,

Super, das probiere ich heute Abend mal aus. Mein Shelly liefert True und False - True halt dann, wenn die Taste gedrückt wird.

Melde mich, ob es geklappt hat.

Gruß Peter

Hi,
kleine Idee für Erweiterungen. So kann man auch auf mehrfachen Druck reagieren wenn man möchte. Das wird ein klein wenig aufwendiger aber nicht wirklich schwer.

Ich stelle mir gerade vor wie man es seiner/n Frau/Mann erklärt: Mit einem 13fachen Druck schaltest Du die Heizung an und mit 14fach wieder aus:-) Aber im Ernst zweifach ist manchmal ganz nützlich. Mein Z-Wave-Schalter hat so einen Zähler schon fest eingebaut und bis 7fach habe ich es schon geschafft.

Ralf

Hallo Ralf,

sieht gut aus - funktioniert bei mir aber nicht :slight_smile:

Hier mein Aufbau:

<?php

if ($_IPS['SENDER'] == "Variable") {
    $SenderID = $_IPS['VARIABLE'];
}

if ($SenderID == 28335) {
    
       if ($_IPS['SENDER'] == "Variable") {
            switch ($_IPS['EVENT']) {
            case "26073":     // Taster AB gedrückt, ID des Skriptes
                $time_start = microtime(true);
                //SetValueFloat(32446, $time_start);
                break;
            case "48134":     // Taster AB losgelassen, ID des Skriptes
                $time_end = microtime(true);
                //$time_start = GetValueFloat(32446);
                $Druckdauer = (($time_end - $time_start)/1000000000);
                SetValueFloat(32446,$Druckdauer);
                break;
            }
       }

       if (GetValueFloat(32446)<1) {
            SHELLY_Stop(34718); 
        } 
        
        if (GetValueFloat(32446) > 1) {
            SHELLY_MoveDown(34718); 
        }
}

Beim Skript, das auf „False / Aus“ reagiert, musste ich noch die Bedingung reinnehmen, das es nur dann ausgeführt wird, wenn „Ab“ true ist (das Shelly-Modul schickt alle 5 Sekunden den Status per MQTT, damit läuft das Skript sonst alle 5 Sekunden.

Die Variable „Druck Start“ ist viel zu groß und der Raffstore fährt nicht runter (Shelly_MoveDown).

P.S.: Die erste Abfrage mache ich, da ich EIGENTLICH ein universelles Skript wollte, das ich für alle Taster nehmen kann - habe ja nicht nur 1 Raffstore im Haus…

Was mache ich denn falsch?
Danke schonmal für die Hilfe!

Schau mal:

            case "48134":     // Taster AB losgelassen, ID des Skriptes
                $time_end = microtime(true);
                //$time_start = GetValueFloat(32446);
                $Druckdauer = (($time_end - $time_start)/1000000000);
                SetValueFloat(32446,$Druckdauer);
                break;
            }

Dir fehlt die Variable $time_start, oder nicht?
Die hast du auskommentiert.
Ich habe das jetzt nur schnell überflogen.

Grüße,
Kai

Hi,
Warum sind „//SetValueFloat(32446, $time_start)“ und „//$time_start = GetValueFloat(32446);“ auskommentiert. So hätte $time_start beim loslassen immer 0 da die Variable nicht global ist. Die folgende IF-Anweisung sollte auch nur beim loslassen kommen denn sonst würde beim Drücken immer Stop kommen.

Ohne diese Kommentare müsstest Du vermutlich „nur“ 31.7 Jahre drücken dann kommt MoveDown. microtime(true) liefert einen Float-Wert so das die Differenz alleine ohne Division durch 1 Milliarde schon in Sekunden sein sollte.

Ich würde es mal so versuchen:


 <?php

if ($_IPS['SENDER'] == "Variable") {
    $SenderID = $_IPS['VARIABLE'];
}

if ($SenderID == 28335) {
    
       if ($_IPS['SENDER'] == "Variable") {
            switch ($_IPS['EVENT']) {
            case "26073":     // Taster AB gedrückt, ID des Skriptes
                $time_start = microtime(true);
                SetValueFloat(32446, $time_start);
                break;
            case "48134":     // Taster AB losgelassen, ID des Skriptes
                $time_end = microtime(true);
                $time_start = GetValueFloat(32446);
                $Druckdauer = $time_end - $time_start;
                SetValueFloat(32446,$Druckdauer);
                if (GetValueFloat(32446)<1) {
                     SHELLY_Stop(34718); 
                } 
                else{
                     SHELLY_MoveDown(34718); 
                }
                break;
            }
       }
} 

Ralf

Wie Kay schon gesehen hat, ohne die Speicherung der Startzeit kannst du nichts sinnvolles berechnen.

Und mit deiner Division

$Druckdauer = (($time_end - $time_start)/1000000000);

müsstest du ca. 278.000 Stunden lang drücken ;).

Da hatten wir ja beide die gleiche Sichtweise/Korrektur :D.

Hi,
muss am Namen liegen:-)

Ralf

Habe es gerade mal ausprobiert. Es sieht jetzt so aus, als geht IPS nicht in case „48134“ und rechnet somit nicht Druckdauer es. Kann es sein, dass das Skript danach einfach abbricht?

Gib doch einfach mal $_IPS[‚EVENT‘] aus, dann weißt du welche ID dort drin steht.

Grüße,
Kai

Gute Idee, die meine These untermauert. Nach case „26073“ wird das Skript verlassen.