Hallo, bin zwar schon eine Weile dabei, habe aber bei weitem noch nicht alles drauf was ich so gerne können würde, aber ich arbeite dran.
Nun stehe ich vor folgender Herausforderung:
Ich will verhindern, dass mein PC versehentlich ausgeschaltet wird. Der ist über den Schalter PC_Schalter und dem Taster Taster_PC_Schalter. Ich möchte, dass der PC_Schalter erst nach 3 mal Tastendruck Taster_PC_Schalter den Befehl toggle sendet.
Wie setzt man das um?
ZitatFebruar 2014
Sequence nutzen
Man kann Aktionen statt mit einem Tastedruck auch mit einer Sequenz von Tastendücken auslösen. Das Format des Befehle ist:
define <name> sequence <re1> <timeout1> <re2> [<timeout2> <re3> ...]
wobei <re1> ...<re_n> die Aktionen sind und <timeout_n> der maximale Abstand der Tastendrücke in Sekunden.
Angenommen, man wolle z.B. eine Lampe dann anschalten, wenn man zuerst Taste1 EIN, dann Taste2 AUS und dann wieder Taste1 EIN einer Fernbedienung drückt, könnte das konkret so aussehen:
define MeineLampenSequenz1 sequence Btn1:on 0.5 Btn2:off 0.5 Btn1:on
Zwischen jedem der Tastendrücke darf eine halbe Sekunde Abstand sein. Diese Definition selbst löst die Lampe nicht aus, sondern definiert nur wie die Sequenz aussehen soll. Um die Lampe bei erfolgreicher Betätigung der Sequenz auch einzuschalten, bedarf es zusätzlich etwas wie:
define MeineLampe notify MeineLampenSequenz1:trigger set Lampe on
Sequence kann man gut nutzen, um mit einer Fernbedienung mehr Funktionen zu schalten als Tasten zur Verfügung stehen. Ebenso könnte man damit simple Codeschlösser für Alarmanlagen bauen, z.B. um eine Anlage auszuschalten, wenn eine bestimmte Abfolge von Tasten gedrückt wird.
Je nach Funksystem nimmt die Zuverlässigkeit aber rasch ab. Angenommen im Bereich FS20 (das System ist etwas unzuverlässiger ist als z.B. HomeMatic) seien 95% aller Funktsignale ungestört übertragbar, dann würden in der Praxis von 100 Tastendrücken an einer Fernbedienung 95x Erfolg zeigen und 5x fehlschlagen; das ist sicher tolerabel.
Bei einer Sequenzlänge von nur 4 Tasten würde die kombinierte Erfolgsquote der Sequenz jedoch nur noch ca. 80% sein, zum Ausschalten einer Alarmanlage vermutlich bereits unpraktisch.
Da ist zuviel dabei, was irgendwie nicht richtig passt. Ich lerne besser am konkreten Beispiel, dafür mache ich alles erstmal im "Labor"
Wo setze ich das mit der Sequenz ein?
Der Sender:
defmod PC_Schalter notify MQTT2_Bridge2:RfReceived_Data:.9D28E2 set DummyschalterA1 toggle
attr PC_Schalter group Tastschalter
attr PC_Schalter room Labor
Die gewünschte Schlüsselsequenz zum Auslösen:
defmod DummyschalterA1Sequenz1 sequence PC_Schalter:on 0.5 PC_Schalter2:on 0.5 PC_Schalter1:toggle
attr DummyschalterA1Sequenz1 room Labor
setstate DummyschalterA1Sequenz1 active
Der durch den Schlüssel freigegebene Befehl:
defmod PC_SequenzSchaltbefehl notify DummyschalterA1Sequenz1:trigger set DummyschalterA1 toggle
attr PC_SequenzSchaltbefehl room Labor
setstate PC_SequenzSchaltbefehl active
setstate PC_SequenzSchaltbefehl 2019-10-20 12:49:28 state active
Der Empfänger:
defmod DummyschalterA1 dummy
attr DummyschalterA1 room Labor
attr DummyschalterA1 setList on off
attr DummyschalterA1 useSetExtensions 1
attr DummyschalterA1 webCmd on:off
setstate DummyschalterA1 on
setstate DummyschalterA1 2019-10-19 12:04:38 state on
Aber das funktioniert irgendwie nicht richtig. Mal erst nach dem Dritten, oder eben ganz wild, wie belieben. Was ist zu tun?
beim einfachen Tastendruck geht es an, beim zweifachen auch und beim Dritten aus
Im nächsten Schritt erst frage ich dann nach kurzem und langen Tastendruck. Erstmal ganz einfach. Das mit den 0,5 und 1 scheinen ja die Signaldauerzeiten in Sekunden zu sein.
Zitatdefmod DummyschalterA1Sequenz1 sequence PC_Schalter:on 0.5 PC_Schalter2:on 0.5 PC_Schalter1:toggle
Ich dachte, Du willst 3mal das gleiche bewerten? Was ist dann Schalter2 und Schalter1?
Also, angenommen, dass dein PC_Taster ein Event "on" bei jedem Druck sendet (die Events kannst Du im Eventmonitor prüfen), eher:
defmod DummyschalterA1Sequenz1 sequence PC_Schalter:on 0.5 PC_Schalter:on 0.5 PC_Schalter:on
oder?
Danach sollte
defmod PC_SequenzSchaltbefehl notify DummyschalterA1Sequenz1:trigger set DummyschalterA1 toggle
reichen.
Ich lese gerade, dass PC_Schalter in deinem Beispiel ein notify ist, der schon auf dem MQTT Device reagiert?
Du musst in Sequence direkt das Event von echten Taster bewerten.
Dann vermutlich die sequence eher so definieren:
defmod DummyschalterA1Sequenz1 sequence MQTT2_Bridge2:RfReceived_Data:.9D28E2 0.5 MQTT2_Bridge2:RfReceived_Data:.9D28E2 0.5 MQTT2_Bridge2:RfReceived_Data:.9D28E2
und das PC_Schalter notify löschen
Events im Eventmonitor prüfen: was kommt dort, wenn Du auf dem Taster druckst?
Der PC soll erst nach 3* Taster drücken an, bzw. wichtiger aus gehen.
Was ist der Taster, und welche Events schickt er beim Drucken?
2019-10-20 15:44:50 MQTT2_DEVICE Bridge RfReceived_High: 1070
2019-10-20 15:44:50 MQTT2_DEVICE Bridge RfReceived_Sync: 10790
2019-10-20 15:44:50 MQTT2_DEVICE Bridge RfReceived_Data: 9D28E2
2019-10-20 15:44:50 MQTT2_DEVICE Bridge RfReceived_Low: 350
2019-10-20 15:44:50 MQTT2_DEVICE Bridge RfReceived_RfKey: None
2019-10-20 15:44:50 dummy DummyschalterA1 off
2019-10-20 15:44:53 MQTT2_DEVICE Bridge RfReceived_Data: 9D28E2
2019-10-20 15:44:53 MQTT2_DEVICE Bridge RfReceived_RfKey: None
2019-10-20 15:44:53 MQTT2_DEVICE Bridge RfReceived_Low: 350
2019-10-20 15:44:53 MQTT2_DEVICE Bridge RfReceived_High: 1060
2019-10-20 15:44:53 MQTT2_DEVICE Bridge RfReceived_Sync: 10790
2019-10-20 15:44:53 dummy DummyschalterA1 on
2019-10-20 15:44:59 MQTT2_DEVICE Bridge RfReceived_High: 1070
2019-10-20 15:44:59 MQTT2_DEVICE Bridge RfReceived_Sync: 10780
2019-10-20 15:44:59 MQTT2_DEVICE Bridge RfReceived_Data: 9D28E2
2019-10-20 15:44:59 MQTT2_DEVICE Bridge RfReceived_Low: 350
2019-10-20 15:44:59 MQTT2_DEVICE Bridge RfReceived_RfKey: None
2019-10-20 15:44:59 dummy DummyschalterA1 off
2019-10-20 15:44:59 MQTT2_DEVICE Bridge RfReceived_High: 1070
2019-10-20 15:44:59 MQTT2_DEVICE Bridge RfReceived_Sync: 10780
2019-10-20 15:44:59 MQTT2_DEVICE Bridge RfReceived_Data: 9D28E2
2019-10-20 15:44:59 MQTT2_DEVICE Bridge RfReceived_Low: 350
2019-10-20 15:44:59 MQTT2_DEVICE Bridge RfReceived_RfKey: None
2019-10-20 15:45:01 dummy DummyschalterA1 on
2019-10-20 15:45:01 MQTT2_DEVICE Bridge RfReceived_High: 1060
2019-10-20 15:45:01 MQTT2_DEVICE Bridge RfReceived_Sync: 10800
2019-10-20 15:45:01 MQTT2_DEVICE Bridge RfReceived_Data: 9D28E2
2019-10-20 15:45:01 MQTT2_DEVICE Bridge RfReceived_Low: 350
2019-10-20 15:45:01 MQTT2_DEVICE Bridge RfReceived_RfKey: None
2019-10-20 15:45:03 dummy DummyschalterA1 off
2019-10-20 15:45:03 MQTT2_DEVICE Bridge RfReceived_High: 1060
2019-10-20 15:45:03 MQTT2_DEVICE Bridge RfReceived_Sync: 10790
2019-10-20 15:45:03 MQTT2_DEVICE Bridge RfReceived_Data: 9D28E2
2019-10-20 15:45:03 MQTT2_DEVICE Bridge RfReceived_RfKey: None
2019-10-20 15:45:03 MQTT2_DEVICE Bridge RfReceived_Low: 350
2019-10-20 15:45:06 dummy DummyschalterA1 on
2019-10-20 15:45:06 MQTT2_DEVICE Bridge RfReceived_High: 1070
2019-10-20 15:45:06 MQTT2_DEVICE Bridge RfReceived_Sync: 10790
2019-10-20 15:45:06 MQTT2_DEVICE Bridge RfReceived_Data: 9D28E2
2019-10-20 15:45:06 MQTT2_DEVICE Bridge RfReceived_Low: 350
2019-10-20 15:45:06 MQTT2_DEVICE Bridge RfReceived_RfKey: None
2019-10-20 15:45:09 dummy DummyschalterA1 off
2019-10-20 15:45:09 MQTT2_DEVICE Bridge RfReceived_Low: 350
2019-10-20 15:45:09 MQTT2_DEVICE Bridge RfReceived_RfKey: None
2019-10-20 15:45:09 MQTT2_DEVICE Bridge RfReceived_Data: 9D28E2
2019-10-20 15:45:09 MQTT2_DEVICE Bridge RfReceived_Sync: 10790
2019-10-20 15:45:09 MQTT2_DEVICE Bridge RfReceived_High: 1060
2019-10-20 15:45:14 dummy DummyschalterA1 on
ZitatWas ist der Taster, und welche Events schickt er beim Drucken?
Der Sender ist der Taster.
Das was als Signalsequenz gesendet werden soll, und durch das der Schaltvorgang am Schalter ausgelöst werden soll ist:
3 mal kurz den Taster drücken.
Zitat von: einfach am 20 Oktober 2019, 15:50:53
2019-10-20 15:44:50 MQTT2_DEVICE Bridge RfReceived_High: 1070
2019-10-20 15:44:50 MQTT2_DEVICE Bridge RfReceived_Sync: 10790
2019-10-20 15:44:50 MQTT2_DEVICE Bridge RfReceived_Data: 9D28E2
2019-10-20 15:44:50 MQTT2_DEVICE Bridge RfReceived_Low: 350
2019-10-20 15:44:50 MQTT2_DEVICE Bridge RfReceived_RfKey: None
2019-10-20 15:44:50 dummy DummyschalterA1 off
2019-10-20 15:44:53 MQTT2_DEVICE Bridge RfReceived_Data: 9D28E2
2019-10-20 15:44:53 MQTT2_DEVICE Bridge RfReceived_RfKey: None
2019-10-20 15:44:53 MQTT2_DEVICE Bridge RfReceived_Low: 350
2019-10-20 15:44:53 MQTT2_DEVICE Bridge RfReceived_High: 1060
2019-10-20 15:44:53 MQTT2_DEVICE Bridge RfReceived_Sync: 10790
2019-10-20 15:44:53 dummy DummyschalterA1 on
2019-10-20 15:44:59 MQTT2_DEVICE Bridge RfReceived_High: 1070
2019-10-20 15:44:59 MQTT2_DEVICE Bridge RfReceived_Sync: 10780
2019-10-20 15:44:59 MQTT2_DEVICE Bridge RfReceived_Data: 9D28E2
2019-10-20 15:44:59 MQTT2_DEVICE Bridge RfReceived_Low: 350
2019-10-20 15:44:59 MQTT2_DEVICE Bridge RfReceived_RfKey: None
2019-10-20 15:44:59 dummy DummyschalterA1 off
2019-10-20 15:44:59 MQTT2_DEVICE Bridge RfReceived_High: 1070
2019-10-20 15:44:59 MQTT2_DEVICE Bridge RfReceived_Sync: 10780
2019-10-20 15:44:59 MQTT2_DEVICE Bridge RfReceived_Data: 9D28E2
2019-10-20 15:44:59 MQTT2_DEVICE Bridge RfReceived_Low: 350
2019-10-20 15:44:59 MQTT2_DEVICE Bridge RfReceived_RfKey: None
2019-10-20 15:45:01 dummy DummyschalterA1 on
2019-10-20 15:45:01 MQTT2_DEVICE Bridge RfReceived_High: 1060
2019-10-20 15:45:01 MQTT2_DEVICE Bridge RfReceived_Sync: 10800
2019-10-20 15:45:01 MQTT2_DEVICE Bridge RfReceived_Data: 9D28E2
2019-10-20 15:45:01 MQTT2_DEVICE Bridge RfReceived_Low: 350
2019-10-20 15:45:01 MQTT2_DEVICE Bridge RfReceived_RfKey: None
2019-10-20 15:45:03 dummy DummyschalterA1 off
2019-10-20 15:45:03 MQTT2_DEVICE Bridge RfReceived_High: 1060
2019-10-20 15:45:03 MQTT2_DEVICE Bridge RfReceived_Sync: 10790
2019-10-20 15:45:03 MQTT2_DEVICE Bridge RfReceived_Data: 9D28E2
2019-10-20 15:45:03 MQTT2_DEVICE Bridge RfReceived_RfKey: None
2019-10-20 15:45:03 MQTT2_DEVICE Bridge RfReceived_Low: 350
2019-10-20 15:45:06 dummy DummyschalterA1 on
2019-10-20 15:45:06 MQTT2_DEVICE Bridge RfReceived_High: 1070
2019-10-20 15:45:06 MQTT2_DEVICE Bridge RfReceived_Sync: 10790
2019-10-20 15:45:06 MQTT2_DEVICE Bridge RfReceived_Data: 9D28E2
2019-10-20 15:45:06 MQTT2_DEVICE Bridge RfReceived_Low: 350
2019-10-20 15:45:06 MQTT2_DEVICE Bridge RfReceived_RfKey: None
2019-10-20 15:45:09 dummy DummyschalterA1 off
2019-10-20 15:45:09 MQTT2_DEVICE Bridge RfReceived_Low: 350
2019-10-20 15:45:09 MQTT2_DEVICE Bridge RfReceived_RfKey: None
2019-10-20 15:45:09 MQTT2_DEVICE Bridge RfReceived_Data: 9D28E2
2019-10-20 15:45:09 MQTT2_DEVICE Bridge RfReceived_Sync: 10790
2019-10-20 15:45:09 MQTT2_DEVICE Bridge RfReceived_High: 1060
2019-10-20 15:45:14 dummy DummyschalterA1 on
Welches dieser Events bedeutet Taster gedrückt, welches wertest du aus?
Habe es kapiert ;)
Das hier wäre die passende Sequenz.
defmod DummyschalterA1Sequenz1 sequence MQTT2_Bridge2:RfReceived_Data:.9D28E2 0.5 MQTT2_Bridge2:RfReceived_Data:.9D28E2 0.5 MQTT2_Bridge2:RfReceived_Data:.9D28E2
Das hier würde dann beim Triggern der Sequenz deinen Dummyschalter toggeln...
defmod PC_SequenzSchaltbefehl notify DummyschalterA1Sequenz1:trigger set DummyschalterA1 toggle
Was soll eigentlich dieser komische Umweg über Dummyschalter?
wenn dieses notify , bzw. der DummySchalterA1 irgendwas physisches schaltet, was mit dem PC zu tun hat, dann darfst du das in Verbindung mit der Sequenz nicht verwenden, denn es löst bei jedem Tastendruck aus und toggelt DummyschalterA1
defmod PC_Schalter notify MQTT2_Bridge2:RfReceived_Data:.9D28E2 set DummyschalterA1 toggle
ALso:
Der Dummyschalter DummyschalterA1 ist nur ein Platzhalter in meinem "FHM-Labor" und wir ersetzt, wenn es funktioniert. Tuts noch nicht.
Gibt es sowas wie ein Zählerbefehl, der, z. B. eine Dummy im Wert steigen lässt, der dann bei 3 einen Schaltbefehlt gibt und sich auf 0 zurück setzt?
Du kannst auch eine Art Schrittkette (oder State-Mashine) zur Lösung Deines Problems nutzen.
Hier ein Beispiel:
A) Definiere eine Dummy-Schalter mit 4 Zuständen (_init_,Zustand_1,Zustand_2,Zustand_3)
B) Definiere ein notify welches auf Deinen Taster reagiert
C) Programmiere im notify als Beispiel
- Wenn Taster-kurz dann => PC an -
- Wenn Taster-lang und _init_ dann => Zustand_1
- Wenn Taster-lang und Zustand_1 dann => Zustand_2
- Wenn Taster-lang und Zustand_2 dann => Zustand_3 und PC aus und Zustand_init
D) Wenn Du magst kannst Du anschließend noch WatchDogs auf die Zustände 1-2 legen und Dein System nach einer Zeit X in den Zustand "_init_" versetzen.
Mit diese Art kannst Du recht komplexe Schaltvorgänge recht simple und einfach abbilden und auch sauber warten/pflegen.
(siehe dazu z.B.: https://forum.fhem.de/index.php/topic,54292.msg458823.html#msg458823)
Das Beispiel: Aktion auslösen, wenn innerhalb einer bestimmten Zeitspanne ein Ereignis x mal eintritt
ist hier zu finden: siehe https://fhem.de/commandref_DE.html#DOIF_Anwendungsbeispiele_im_Perlmodus
ZitatState-Mashine
Aber um Himmels Willen doch nicht in der FHEM-Skriptsprache... Dafür sollte man unbedingt Perl verwenden.
LG
pah
Hier mal konkret, weil zeitkritisch in Perl-Performance (zum Definitionszeitpunkt wird alles in Perl übersetzt), ohne zusätzliche Module und ohne Dummys
define di_count DOIF {
if ([MQTT2_Bridge2:"RfReceived_Data: 9D28E2"] and !get_Exec("counter")) { # wenn Ereignis eintritt und kein Timer läuft
$_count=1; # setze count-Variable auf 1
set_Exec("counter",2,'fhem_set("PC_Schalter1 toggle") if ($_count >= 3)'); # setze Timer auf 2 Sekunden zum Toggeln, wenn mindestens bis drei gezählt wurde
} else {
$_count++; # wenn Timer bereits läuft zähle Ereignis
}
}
Zitat von: Prof. Dr. Peter Henning am 18 November 2019, 17:55:59
Aber um Himmels Willen doch nicht in der FHEM-Skriptsprache... Dafür sollte man unbedingt Perl verwenden.
LG
pah
Es gibt Menschen die überall etwas suchen, was sie aufregt.
Und solche, die etwas suchen, was sie inspiriert.
Ach, manche Leute glauben wirklich, aufregend zu sein... ;D
LG
pah
Um wieder zum Thema zu kommen :)
Bei meiner ersten Version musste man bis zum Ablauf des Timers mit der Ausführung warten.
Folgende Version dürfte praktikabler sein.
Hierbei hat man mehr Zeit (hier 5 Sekunden), sobald drei mal gedrückt wurde, wird Toggeln ausgeführt. Auf der einen Seite hat man mehr Zeit für die Wiederholung des Tastendrucks, auf der anderen Seite muss man nicht auf den Ablauf des Timers mit der Ausführung des Toggle-Befehls warten.
define di_count DOIF {
if ([MQTT2_Bridge2:"RfReceived_Data: 9D28E2"] and !get_Exec("counter")) { # wenn Ereignis eintritt und kein Timer läuft
$_count=1; # setze count-Variable auf 1
set_Exec("counter",5); # starte Timer für 5 Sekunden
} else {
if (++$_count >= 3) { # wenn Timer bereits läuft zähle Ereignis und prüfe, ob drei mal Ereignis eingetreten ist
del_Exec("counter"); # lösche Timer
fhem_set("PC_Schalter1 toggle"); # Toggle-Befehl ausführen
}
}
}
Hi Damian,
ich habe dein Script ausprobiert, leider funktioniert es nicht richtig, da es bei fast jedem Tastendruck auslöst.
Wo könnte da der Fehler sein?
Wenn ich das Zeitfenster kleiner mache ändert sich der Fehler auch nicht. Mal geht es nach dreimal, mal direkt, trotz Abwartens.
Aber an genau so ein Script habe ich gedacht.