Moin,
Ich habe ein device ,,ALARM_SENDER", dieser hat einen Kanal ,,ALARM_SENDER_3_BYTE", dieser ein Reading ,,ALARM_INPUT"
Es wird ein 8 Bit Wert erzeugt zB: 00000100.
Nun möchte ich das 6. Bit abfragen und wenn es eins ist den dummy ,,ALARM_IST_SCHARF" auf ,,on" setzen und umgekehrt.
Mein ,,notify" dachte ich gestalte ich mal so.
if (substr(ReadingsVal("ALARM_SENDER_3_BYTE","ALARM_INPUT",""),6,1) eq "1"){
fhem("set ALARM_IST_SCHARF on");;
}
if (substr(ReadingsVal("ALARM_SENDER_3_BYTE","ALARM_INPUT",""),6,1) eq "0"){
fhem("set ALARM_IST_SCHARF off");;
}
Kurz gefragt: was ist falsch?
Danke im Voraus
KASPI :-\
https://perldoc.perl.org/functions/substr
Es wird mit NULL begonnen zu zählen...
Vorausgesetzt der Rest vom notify tut, weil man ja nichts sieht...
...es fehlen:
ein list des GESAMTEN notify und Auszüge aus dem Eventmonitor, mit relevanten Daten.
Gruß, Joachim
defmod ALARM_ZUSTAND notify \
if (substr(ReadingsVal("ALARM_SENDER_3_BYTE","ALARM_INPUT",""),6,1) eq "1"){\
fhem("set ALARM_IST_SCHARF on");;;;\
}\
\
if (substr(ReadingsVal("ALARM_SENDER_3_BYTE","ALARM_INPUT",""),6,1) eq "0"){\
fhem("set ALARM_IST_SCHARF off");;;;\
}\
\
Und im eventmonitor werden die Bits entsprechend gesetzt.
Das ist kein list...
...verm. ein RawDef...
ABER: das ist doch kein vernünftiges notify!!
https://wiki.fhem.de/wiki/Notify
Es fehlt doch komplett die Trigger-Regex...
...und bevor du Perl nutzen kannst, musst du doch erst mal nach Perl "schalten": geschweifte Klammer!
https://wiki.fhem.de/wiki/Klammerebenen
Gibt es keine Fehler?
Fhem-Log?
Am einfachsten geht ein notify anlegen per Eventmonitor.
Die relevante Zeile markieren -> create/modify und dann die Ausführung anpassen...
https://wiki.fhem.de/wiki/Event_monitor
Gruß, Joachim
;D
Mit dem Eventmonitor usw. wusste ich nicht.
Das ist ja einfach.
Danke :)
Alles gut.
Ähhhmmmm...
Nochmal ich.
Folgendes wurde erzeugt:
ALARM_SENDER_3_BYTE:ALARM_INPUT:.00000100 set ALARM_EIN_AUS 1
Wie filtere ich denn genau das eine Bit raus?
So wird ja nur bei exakt 00000100 geschaltet.
Die anderen Bits können sich aber auch ändern.
Bei zB. 0010000 soll was anderes geschaltet werden und bei 00100100 beides.
KASPI ;)
Es wird beim Erzeugen doch gefragt, ob GENAU die FOLGE oder alle Werte.
Entweder RegEx lernen...
...oder das notify mit z. B. .* statt 00000100 und mit richtiger Klammer- und Strichpunktsetzung deinen if-Code inkl. beachten, dass substr ab 0 zählt...
Gruß, Joachim
Du setzt zuviel voraus.
Ich komme so leider nicht weiter.
Schade.
KASPI :-\
Zitat von: Kaspi am 12 August 2021, 15:45:57
Du setzt zuviel voraus.
Ich komme so leider nicht weiter.
Schade.
KASPI :-\
Du brauchst doch nur zu tun was ich geschrieben habe:
00000100 -> .*
EDIT: aufpassen, du hast schon einen Punkt vor 00000100! Der muss zusätzlich bleiben. Da ist wohl ein Leerzeichen im Event...
Alternativ das notify noch mal anlegen lassen, diesmal eben "für alle Werte"...
EDIT: RegEx für 6te Stelle eine 1 wäre z.B. .....1.. ;)
EDIT: irgendwie so [0-9]{5}1[0-9]{2} sollte auch gehen bzw. reicht wohl [0-1]{5}1[0-1]{2}
EDIT: RegEx-Tester https://regex101.com/
Dann geschweifte Klammern für Perl (sollten nach dem Anlegen des notify eh schon da sein).
Da dann deinen Code von oben...
...Aber: substr fängt halt bei 0 an zu zählen und nicht bei 1
Und je nachdem WO/WIE du das notify anpasst eben mit den Strichpunkten aufpassen...
Bin grad nur mit dem Handy zugange, sonst hätte ich auch den Code posten können...
...aber: über kurz oder lang kommst du um etwas RegEx und Perl nicht drumrum...
Gruß, Joachim
So klappt's...
ALARM_SENDER_3_BYTE:ALARM_INPUT:.* {
if (substr(ReadingsVal("ALARM_SENDER_3_BYTE","ALARM_INPUT",1),6,1)){
fhem("set ALARM_IST_SCHARF on");;
}
if (substr(ReadingsVal("ALARM_SENDER_3_BYTE","ALARM_INPUT",0),6,1)){
fhem("set ALARM_IST_SCHARF off");;
}
}
Danke :)
Das wage ich zu bezweifeln...
Weil deine if-Abfragen nicht richtig sind...
...und substr immer noch bei 0 beginnt, wenn du also Stelle 6 willst, muss als Index eine 5 hin...
Aber wenn du denkst es geht: viel Erfolg.
Gruß, Joachim
Hallo Kaspi,
gebe doch mal folgendes oben in die fhem commandozeile ein (genau so mit dem doppelten";;":
Zitat{my $byte=12345678;; return substr($byte,6,1)}
Da kommt bei mir eine '7' zurueck. Wenn man die 6-te Stelle will, muss man auf die 5 abfragen, also {my $byte=12345678;; return substr($byte,5,1)}.
Dann, statt "ReadingsVal("ALARM_SENDER_3_BYTE","ALARM_INPUT",1)" kannst Du wahrscheinlich auch $EVTPART1 nehmen, also "if (substr($EVTPART1,6,1)) ......"
Beim notify steht in der Variable $EVENT das komplette EVENT, in der variable $EVTPART0/1/2/ die durch Leerzeichen getrennten Teile des Events.
Ist effizienter als da nochmal ReadingsVal zu bemuehen.
Manmanman...
jetzt aber
ALARM_SENDER_3_BYTE:ALARM_INPUT:.* {
if (substr(ReadingsVal("ALARM_SENDER_3_BYTE","ALARM_INPUT",""),0,1) eq"1"){
fhem("set ALARM_12V_OK on");;
}
if (substr(ReadingsVal("ALARM_SENDER_3_BYTE","ALARM_INPUT",""),0,1) eq"0"){
fhem("set ALARM_12V_OK off");;
}
if (substr(ReadingsVal("ALARM_SENDER_3_BYTE","ALARM_INPUT",""),1,1) eq"1"){
fhem("set ALARM_GND_OK on");;
}
if (substr(ReadingsVal("ALARM_SENDER_3_BYTE","ALARM_INPUT",""),1,1) eq"0"){
fhem("set ALARM_GND_OK off");;
...
...
...
:) ;) :D ::)
Nur so nebenbei: binäre Werte (Bitfolgen) könnte man ja auch binär vergleichen, dann braucht man überhaupt kein substr()
Hallo Kaspi,
da Du weisst das der Wert nur entweder '0' oder '1' annehmen kann, brauchst Du auch nur auf die 1 abfragen (und eine 1 ist immer true, da musst Du auch nicht explizit auf 'eq "1" ' checken), also:
if (substr($EVTPART1,6,1)) {fhem("set ALARM_12V_OK on");;else {fhem("set ALARM_12V_OK off");;}}
Kannst Du auch testen, einfach mal folgendes oben in die fhem Kommandozeile eingeen:
{my $byte=10101100;; my $res = substr($byte,5,1);; if ($res) {return "res = $res gefunden"} else {return "res = $res gefunden"} }
Getz aber
ALARM_SENDER_3_BYTE:ALARM_INPUT:.* {
if (substr($EVTPART1,0,1)){
fhem("set ALARM_12V_OK on");;}
else{
fhem("set ALARM_12V_OK off");;}
if (substr($EVTPART1,1,1)){
fhem("set ALARM_GND_OK on");;}
else{
fhem("set ALARM_GND_OK off");;}
if (substr($EVTPART1,2,1)){
fhem("set ALARM_EIN_AUS on");;}
else{
fhem("set ALARM_EIN_AUS off");;}
...
...
...
Yep, sieht fast gut aus! Aber wegen den doppelten ";;" :
In der Definition selber muss nur nur ein ; sein, und selbst das kannst Du weglassen.
Es muss also so aussehen:
...
if (substr($EVTPART1,0,1)){
fhem("set ALARM_12V_OK on");}
else{
fhem("set ALARM_12V_OK off");}
oder
if (substr($EVTPART1,2,1)){
fhem("set ALARM_EIN_AUS on")}
else{
fhem("set ALARM_EIN_AUS off")}
Ich frage weil Du das notify nicht in in der RAW definition gezeigt hast, dann hätten wir noch einen \ als Zeilentrenner gesehen.
Aber zwei ;; in der definition des notify sind falsch.
Wenn man etwas tiefer in Perl steckt, dann kann man es auch etwas kürzer schreiben:
ALARM_SENDER_3_BYTE:ALARM_INPUT:.* {
my @a=("off","on");;
fhem ("set ALARM_12V_OK ".$a[$EVTPART1 & "1"]);;
fhem ("set ALARM_GND_OK ".$a[$EVTPART1 & "01"]);;
fhem ("set ALARM_EIN_AUS ".$a[$EVTPART1 & "001"]);;
....
}