Hallo,
was verstehe ich an der Doku falsch ?
ZitatdisabledAfterTrigger <sekunden>
deaktiviert die Ausführung für <sekunden> nach dem das notify ausgelöst wurde.
Ich möchte das die Befehle zeitverzögert ausgeführt werden, zum Test hier 10 Sekunden (eigentlich etwa 2,5 Sekunden)
Der Ausführungsteil wird aber sofort ausgeführt, InternalVal holt sich immer den EACH_INDEX vor dem betätigen der Taste, der Scriptaufruf wird nicht verzögert ausgeführt.
Wo ist mein Denkfehler, was hab ich nicht verstanden ?
defmod FB_433_2_TasteC_notify_1 notify FB_433_2_TasteC:off {InternalVal("FB_433_2_TasteC","EACH_INDEX","") eq "1" ? system("/opt/fhem/voucher.sh &") : system("/opt/fhem/voucherx.sh &")}
attr FB_433_2_TasteC_notify_1 disabledAfterTrigger 10
setstate FB_433_2_TasteC_notify_1 2020-07-29 16:27:22
setstate FB_433_2_TasteC_notify_1 2020-07-29 16:10:14 state active
Gruß
Thomas
vielleicht ist es besser noch zu zeigen was wie zusammen spielt:
if ($NAME eq "FB_433_2_TasteC" && $EVENT eq "off")
{Each($NAME, ReadingsVal($NAME,"count","0"));fhem("set EG_Echo_Kueche sounds Glocken")}
defmod FB_433_2_TasteC IT 0FF0FFF0FF 0F F0
attr FB_433_2_TasteC IODev sduino
attr FB_433_2_TasteC group Fernbedienung_Küche
attr FB_433_2_TasteC room IT
setstate FB_433_2_TasteC off
setstate FB_433_2_TasteC 2020-07-28 19:08:24 count 1,2
setstate FB_433_2_TasteC 2020-07-28 21:50:10 protocol 0
setstate FB_433_2_TasteC 2020-07-29 16:27:22 state off
Bei disabledAfterTrigger geht es um die _wiederholte_ Ausführung. Das Attribut bewirkt also "nur", dass weitere Ereignisse dann nicht zur erneuten Ausführung des Anweisungsteils führen, verzögert wird der Ausführungsteil aber nicht, wenn der (noch nicht) deaktivierte trigger kommt.
Ist z.B. hilfreich, wenn man mehrere OMG-Gateways hat und dann z.B. dieselbe Temperaturinfo über mehrere Kanäle an den m2Server abgeliefert werden (andere Module, z.B. IT-Module+CUL würden sowas direkt verwerfen).
Muss ich mein Vorhaben jetzt verwerfen oder gibt es eine Möglichkeit ein sleep zu machen, ohne das das System steht ?
edit:
2 Tasten oder DOIF verwenden ist klar
Du willst die sh Datei verzögern?
system("/opt/fhem/voucher.sh &") : system("/opt/fhem/voucherx.sh &")
mach doch ein sleep in der sh Datei.
Oder versuch ein
defmod FB_433_2_TasteC_notify_1 notify FB_433_2_TasteC:off sleep 3;;{InternalVal("FB_433_2_TasteC","EACH_INDEX","") eq "1" ? system("/opt/fhem/voucher.sh &") : system("/opt/fhem/voucherx.sh &")}
Sollte auch gehen.
Gruß Otto
Sehr cool Danke Otto :)
defmod FB_433_2_TasteC_notify_1 notify FB_433_2_TasteC:off sleep 2;;{InternalVal("$NAME","EACH_INDEX","") eq "1" ? system("/opt/fhem/voucher.sh &") : system("/opt/fhem/voucherx.sh &")}
Der oben gezeigte Code ist meine ausgedachte Alternative (https://forum.fhem.de/index.php/topic,113183.msg1074962.html#msg1074962) zum Modul Taster, um auf zwei Tastendrücke zu reagieren.
Die Alternative ist aber noch nicht ganz fertig.
Ich bekomme es einfach nicht hin noch ein delete($defs{FB_433_2_TasteC}{EACH_INDEX}) an die system-Befehle anzuhängen.
Wie macht man es denn, ich mein ich hab alle mir bekannten Möglichkeiten durch und sitze schon ewig daran.
Einfach
;;{Befehl}
am Ende des define Kommandos anhängen sollte gehen.
Reicht es nicht, EACH_INDEX auf 0 zu setzen?
Zitat von: amenomade am 29 Juli 2020, 18:34:44
Einfach
;;{Befehl}
am Ende des define Kommandos anhängen sollte gehen.
Komm ich nicht mit, gehts bitte genauer.
Ziel ist sowas in der Art
... system("/opt/fhem/voucher.sh &"); delete{($defs{FB_433_2_TasteC}{EACH_INDEX})}...
ZitatReicht es nicht, EACH_INDEX auf 0 zu setzen?
EACH_INDEX muss auf jedenfall wieder von vorne anfangen, ob 0 zielführend wäre müsst ich ausprobieren, weiß aber ehrlich gesagt nicht wie ich ihn setzen kann.
Zitat von: TomLee am 29 Juli 2020, 19:03:03
Ziel ist sowas in der Art
... system("/opt/fhem/voucher.sh &"); delete{($defs{FB_433_2_TasteC}{EACH_INDEX})}...
Und was geht damit nicht?
delete argument is not a HASH or ARRAY element or slice at (eval 70171) line 1.
mit modify FB_433_2_TasteC_notify_1
Wie gesagt ich hab schon einige Varianten durch auch wieder mit{}
Wahrscheinlich weil der schon gelöscht wurde?
delete ist eine Funktion
also delete() ist richtig, delete{} falsch
Setze den doch auf 0 statt zu löschen.
Sry, hab irgendwas kopiert gehabt, mein Code von dem ich die ganze Zeit ausgehe das er richtig ist, ist dieser:
delete($defs{FB_433_2_TasteC}{EACH_INDEX})
Mit dem gibts beim modify des notify
syntax error at (eval 85614) line 1, at EOF
syntax error at (eval 85614) line 1, near "):"
ZitatWahrscheinlich weil der schon gelöscht wurde?
sry das ist Quatsch :) , ich definiere doch nur das notify.
ZitatSetze den doch auf 0 statt zu löschen.
Zitat von: TomLee am 29 Juli 2020, 19:03:03
... ob 0 zielführend wäre müsst ich ausprobieren, weiß aber ehrlich gesagt nicht wie ich ihn setzen kann.
Wie gesagt ich hab keine Vorstellung was Each dann macht und wieder von vorne beginnt.
Hatte nicht verstanden, dass es beim mod
ify des notifies kommt.
Zitatsyntax error at (eval 85614) line 1, near "):"
Woher kommt der Doppelpunkt nach Klammer? Wie machst Du genau deine Änderung?
EDIT: bei mir passt in der DEF:
FB_433_2_TasteC:off sleep 2;{InternalVal("$NAME","EACH_INDEX","") eq "1" ? system("/opt/fhem/voucher.sh &") : system("/opt/fhem/voucherx.sh &");delete($defs{FB_433_2_TasteC}{EACH_INDEX})}
Ah... ich glaube, ich habe verstanden. Wiederum Perl Grundlagen... Es wäre Zeit, dass Du dich einarbeitest.
Du versuchts das nicht an der Stelle hinzuzufügen, wo ich es hieroben gemacht habe, sondern direkt in dem Perl ternary Operator. Das geht natürlich nicht, und Du musst auf die normale if Struktur wechseln.
EDIT: es gibt eine Alternativ mit bedingung ? do {Befehl1; Befehl2, ...} : do {Befehl3; Befehl4}
aber das wird total unübersichtlich im Vergleich mit einem normalen if
Mit
defmod FB_433_2_TasteC_notify_1 notify FB_433_2_TasteC:off sleep 3;;{if (InternalVal("$NAME","EACH_INDEX","") eq "1")\
{system("/opt/fhem/voucher.sh &");;delete($defs{FB_433_2_TasteC}{EACH_INDEX})}\
else {system("/opt/fhem/voucherx.sh &");;delete($defs{FB_433_2_TasteC}{EACH_INDEX})}}\
macht das sleep Probleme, im Log steht:
2020.07.29 21:41:18 3: sduino IT_set: FB_433_2_TasteC off
2020.07.29 21:41:19 3: Das ist FB_433_2_TasteC off off
2020.07.29 21:41:21 2: After sleep: Unknown command {if, try help.
Unknown command delete($defs{FB_433_2_TasteC}{EACH_INDEX})}
else, try help.
Unknown command delete($defs{FB_433_2_TasteC}{EACH_INDEX})}}
, try help.
ohne sleep hab ich zwar erstmal keine Möglichkeit für einen zweiten Tastendruck die Datei wird gedruckt aber EACH_INDEX wird nicht gelöscht:
2020.07.29 21:42:34 3: sduino IT_set: FB_433_2_TasteC off
2020.07.29 21:42:34 3: FB_433_2_TasteC_notify_1 return value: 2
2020.07.29 21:42:34 3: Das ist FB_433_2_TasteC off off
Das mit do schau ich mir später sonst morgen an.
Weil das {if }nach sleep kommt musst Du innerhalb des if die Semikola 2x verdoppeln... also 4.
defmod FB_433_2_TasteC_notify_1 notify FB_433_2_TasteC:off sleep 3;;{if (InternalVal("$NAME","EACH_INDEX","") eq "1")\
{system("/opt/fhem/voucher.sh &");;;;delete($defs{FB_433_2_TasteC}{EACH_INDEX})}\
else {system("/opt/fhem/voucherx.sh &");;;;delete($defs{FB_433_2_TasteC}{EACH_INDEX})}}
Ja, super sieht gut aus.
Für morgen liegt an herauszufinden weshalb jetzt bei 2 Tastendrücken die voucherx.sh zweimal gedruckt wird, die voucher.sh wird wie vorgesehen nur einmal gedruckt.
2020.07.29 22:48:46 3: sduino IT: FB_433_2_TasteC off->off
2020.07.29 22:48:46 3: Das ist FB_433_2_TasteC off off
2020.07.29 22:48:49 2: After sleep: 1
2020.07.29 22:50:15 3: sduino IT_set: FB_433_2_TasteC off
2020.07.29 22:50:15 3: Das ist FB_433_2_TasteC off off
2020.07.29 22:50:16 3: sduino IT_set: FB_433_2_TasteC off
2020.07.29 22:50:16 3: Das ist FB_433_2_TasteC off off
2020.07.29 22:50:18 2: After sleep: 2
2020.07.29 22:51:43 3: sduino IT_set: FB_433_2_TasteC off
2020.07.29 22:51:43 3: Das ist FB_433_2_TasteC off off
2020.07.29 22:51:44 3: sduino IT_set: FB_433_2_TasteC off
2020.07.29 22:51:44 3: Das ist FB_433_2_TasteC off off
2020.07.29 22:51:46 2: After sleep: 2
2020.07.29 22:53:16 3: sduino IT_set: FB_433_2_TasteC off
2020.07.29 22:53:16 3: Das ist FB_433_2_TasteC off off
2020.07.29 22:53:20 2: After sleep: 1
DANKE
Habs.
Das notify merkt sich auch die Events die während dem dem sleep 3 (... sleep 3;;{if (I...) stattfanden, wird die Taste x mal betätigt wird auch x-mal ausgedruckt.
Abhilfe schafft ein disabledAfterTrigger 3 :)
Danke für die Hilfe mit dem if.
Und was das angeht ist mir jetzt immer noch nicht klar wie man das "kurze" if beim Namen nennt.
Einfach ternärer Operator, ternärer Operator if, bedingter Operator, bedingtes Operator if ? ? ?
if ist für mich einfach (Perl-) if...
Und das notify merkt sich auch nichts, das setzt einfach ein unbenanntes sleep ab. Die Alternative zu "disabledAfterTrigger wäre, benannte sleep zu verwenden:A sleep with an <id> will replace a sleep with the same <id> and can be canceled by cancel. When called in a notify/at/etc, then nonempty return values of the following commands are logged to the global logfile with loglevel 2.
If quiet is specified, then skip this logging.
Hätte also indirekt dieselbe Folge, wie wenn du ein defmot-at absetzen würdest...
Kann solange darüber nachdenken wie ich möchte, komm nicht drauf, wie mach ich das mit dem sleep dann in einer MyUtils ?
Hab noch nichts ausprobiert, nur philosophiert, ich kann doch nicht einfach ein fhem("sleep 3")
ohne darauffolgenden Befehl machen nach if ($NAME eq "FB_433_2_TasteD" && $EVENT eq "off")
?
Oder Ist der Perl-Code {if (InternalVal("$NAME","EACH...
dann der "darauffolgende Befehl", so hab ich es zumindest im notify verstanden ?
if ($NAME eq "FB_433_2_TasteD" && $EVENT eq "off") {
if (InternalVal("$NAME","EACH_INDEX","") eq "1")
{system("/opt/fhem/voucher.sh &");delete($defs{$NAME}{EACH_INDEX})}
else {
system("/opt/fhem/voucherx.sh &");delete($defs{$NAME}{EACH_INDEX})}}
Hier das notify nochmal:
defmod FB_433_2_TasteC_notify_1 notify FB_433_2_TasteC:off sleep 3;;{if (InternalVal("$NAME","EACH_INDEX","") eq "1")\
{system("/opt/fhem/voucher.sh &");;;;delete($defs{$NAME}{EACH_INDEX})}\
else {system("/opt/fhem/voucherx.sh &");;;;delete($defs{$NAME}{EACH_INDEX})}}
attr FB_433_2_TasteC_notify_1 disabledAfterTrigger 3
setstate FB_433_2_TasteC_notify_1 2020-08-24 13:25:20
setstate FB_433_2_TasteC_notify_1 2020-08-23 16:53:01 state active
Korrekt, auch wenn du das "sleep" in einen fhem-Aufruf verpackst, MUSS danach ein Befehl kommen. Sollte also ggf. so aussehen:
fhem("sleep 3;;..")
Allerdings ist das m.E. "von hinten durch die Brust"... Denn eigentlich willst du einen InternalTimer definieren, und damit kannst du auch gleich direkt das machen, was
CommandSleep in fhem.pl tut, ohne das erst umständlich in fhem-Aufrufe zu verpacken (ok, die Syntax und die Vorgehensweis ist anders, aber das war es dann auch. Muß man halt - wie vieles andere auch - einmalig verstanden haben.)
Hi,
abgesehen davon was Beta-User schreibt und ich mit dem Konstrukt $defs() nicht viel anfangen kann:
Rudi warnt davor FHEM Kommandotypen zu mischen - auch wenn es funktioniert. Siehe hier (https://forum.fhem.de/index.php?topic=109354.0).
Der Fall sleep x;{Perlcode} bildet aus meiner Sicht da eine Ausnahme die funktioniert, da FHEM aus dem sleep x ein at mit dem Befehl {Perlcode} macht. Ich verwende das öfters mal.
Am Ende wird es durch {fhem("sleep x;;{Perlcode}")} nicht anders.
Dein notify sieht nicht schlecht aus, auch wenn ich nicht verstehe was es tun soll :)
Gruß Otto
ZitatDein notify sieht nicht schlecht aus, auch wenn ich nicht verstehe was es tun soll :)
Dir kann ich gleich antworten, die "Beate" muss noch warten bis ich das verarbeitet habe. ;D
Es gibt noch ein weiteres (ausgelagertes) notify , so in der Art (hat sich heute an den Tasten und Readingnamen was geändert im Vergleich zu oben):
Auszug aus der myUtils (Taste C off ist jetzt D on):
if ($NAME eq "FB_433_2_TasteD" && $EVENT eq "on")
{Each($NAME, ReadingsVal($NAME,"count","0"));fhem("set EG_Echo_Kueche sounds Glocken")}
Es werden bei einem oder zwei Tasten-Betätigungen innerhalb von 3 Sekunden jeweils andere Scripts aufgerufen.
Beim ersten Tastendruck wird ein voucher mit Überschrift der SSID mittig einer A6 Seite ausgedruckt, beim zweiten Tastendruck zwei voucher mit Überschrift der SSID, jeweils mittig der A6 Seite oben und unten.
So in der Art ( wie gesagt hat sich heute einiges geändert) sieht das eine Script aus:
#!/bin/bash
voucher=$(perl fhem.pl 7072 "{ReadingsVal('Unifi','voucher_7d1x','unknown')}");
IFS=',' arr=($voucher);
sed -i 's/^\/Courier.*$/\/Courier findfont 20 scalefont setfont 70 290 moveto (SSID: '"${arr[0]}"') show 75 270 moveto ('"${arr[1]}"') show 70 85 moveto (SSID: '"${arr[0]}"') show 75 65 moveto ('"${arr[2]}"') show showpage/' /opt/fhem/voucherx.ps;
lpr -P HL-2035 -o media=Custom.95x138mm /opt/fhem/voucherx.ps;
So die dazugehörige .ps (unrelevant sieht man ja was sed oben macht):
%!
/Courier findfont 20 scalefont setfont 70 290 moveto (SSID: Gast1) show 75 270 moveto (1687752668) show 70 85 moveto (SSID: Gast1) show 75 65 moveto (1319214911) show showpage
So das andere Script:
#!/bin/bash
voucher=$(perl fhem.pl 7072 "get Unifi voucher 7d1x");
voucherssid=$(perl fhem.pl 7072 "{ReadingsVal('Unifi','voucher_7d1x','unknown')}");
IFS=',' arr=($voucherssid);
sed -i 's/^\/Courier.*$/\/Courier findfont 20 scalefont setfont 70 195 moveto (SSID: '"${arr[0]}"') show 75 170 moveto ('"$voucher"') show showpage/' /opt/fhem/voucher.ps;
lpr -P HL-2035 -o media=Custom.95x138mm /opt/fhem/voucher.ps;
Die dazugehörige .ps ( ebenfalls unrelevant wie oben):
%!
/Courier findfont 20 scalefont setfont 70 195 moveto (SSID: Gast1) show 75 170 moveto (1319214911) show showpage
Ich hab kein Problem, ich will nur das eine notify auslagern.
Also das klappt so wie von euch auch bestätigt, hätt ich es doch einfach vorher mal ausprobiert.
my $NAME = shift;
{fhem('sleep 3;{if (InternalVal("$NAME","EACH_INDEX","") eq "1")
{system("/opt/fhem/voucher21.sh &");;delete($defs{$NAME}{EACH_INDEX})}
else
{system("/opt/fhem/voucher21x.sh &");;delete($defs{$NAME}{EACH_INDEX})}}')}
}
Was den InternalTimer angeht, mein ich den zweiten Parameter halbwegs verstanden zu haben, beim dritten brauchts noch Zeit.