Hallo,
ich nutze das readingsWatcher Modul um mehrere Module und Readings zu überwachen. readingsWatcher legt automatisch readings mit <device>_reading an. z.B.
Bewohner_residentsHome
Xiaomi_AirPurifier3_slave_temperature
Xiaomi_AirPurifier3_slave_humidity
...
Nun möchte ich alles vor und nach dem letzten Unterstrich in eine Variablen bekommen, um es per Telegram versenden zu können. Nur leider weiß ich nicht wie ich das in die Variable bekommen. Die Devicenamen können auch mehrere Unterstriche.
hier das aktuelle notify. $var1 soll dann alles vor dem letzten Unterstrich sein.
readingsWatcher.*:.timeout { my $var1=ReadingsVal($NAME,"Xiaomi_AirPurifier3_slave_humidity",""); fhem ("set Telegram msg $var1");}
Gruß
TWART016
$var1=ReadingsVal($NAME,"Xiaomi_AirPurifier3_slave_humidity","")
Damit liest Du aber den Inhalt von $NAME,"Xiaomi_AirPurifier3_slave_humidity" ein. Wie sieht der Inhalt den aus?
Hi,
als Idee zum Testen in der FHEM Kommandozeile:
{my $var1="2_1_slave_humidity";;(split("_",$var1))[-1]}
Gibt Dir den letzten Wert. [-2] wäre der Vorletzte.
Gruß Otto
Zitat von: Otto123 am 18 April 2020, 21:59:55
Hi,
als Idee zum Testen in der FHEM Kommandozeile:
{my $var1="2_1_slave_humidity";;(split("_",$var1))[-1]}
Gibt Dir den letzten Wert. [-2] wäre der Vorletzte.
Gruß Otto
sieht super aus. Und wie bekomme ich alles davor noch in die Variable $var2?
Hatte ich nicht komplett gelesen :(
{my $var1='2_1_slave_humidity';;my @arr=split('_',$var1);;my $var2=join('_',@arr[0..$#arr-1])}
@arr[-1] ist dann der bisherige Letzte ;)
Gruß Otto
In der FHEM Kommandozeile funktioniert es, nur im notify bekomme ich den ganzen String ausgegeben:
readingsWatcher:.*:.timeout {
my $var1="2_1_slave_humidity";;
(split("_",$var1))[-1];;
fhem ("set Telegram msg $var1");;
};
warum willst du dich unbedingt an das Reading timeout hängen ? das Modul liefert dir ein ganzes Bündel von Readings u.A. schon Komma getrennte Listen um genau diese Art von Weiterverarbeitung dem User leicht zu nachen.
Moin,
Zitatnur im notify bekomme ich den ganzen String ausgegeben:
Weil Du das was Du vorne reinsteckst hinten auch so wieder ausgibst. Deine Bearbeitung zwischendrin ist fürn alten Hutz.
Wenn das was Du gepostet hast, in der DEF steht, sind bei Dir zuviele ; drin. Ich habe aufgeräumt.
readingsWatcher:.*:.timeout {
my $var1="2_1_slave_humidity";
my $out=(split("_",$var1))[-1];
fhem ("set Telegram msg $out");
}
Gruß Otto
Zitat von: Wzut am 19 April 2020, 09:28:56
warum willst du dich unbedingt an das Reading timeout hängen ? das Modul liefert dir ein ganzes Bündel von Readings u.A. schon Komma getrennte Listen um genau diese Art von Weiterverarbeitung dem User leicht zu nachen.
Ich möchte mich benachrichtigen lassen, wenn ein Reading eines bestimmten Gerätes sich ändert. Mit timeoutdevs oder deadDevs sehe ich die Geräte, potenziell mehrere. Ich weiß nun aber nicht, welches Gerät das Event getriggert hat und welches Reading es ist.
Zitat von: Otto123 am 19 April 2020, 10:23:31
Moin,
Weil Du das was Du vorne reinsteckst hinten auch so wieder ausgibst. Deine Bearbeitung zwischendrin ist fürn alten Hutz.
Wenn das was Du gepostet hast, in der DEF steht, sind bei Dir zuviele ; drin. Ich habe aufgeräumt.
readingsWatcher:.*:.timeout {
my $var1="2_1_slave_humidity";
my $out=(split("_",$var1))[-1];
fhem ("set Telegram msg $out");
}
Gruß Otto
Oh, war vermutlich schon zu spät gestern ;)
Habe es jetzt so hinbekommen.
readingsWatcher:.*:.timeout {
my $var1="$EVTPART0";
my @arr=split('_',$var1);
my $var2=join('_',@arr[0..$#arr-1]);
my $var4=(split("_",$var1))[-1];
my $out=(split(':',$var4))[0];
fhem ("set Telegram msg $var2:$out ". ReadingsVal($var2,$out,""));
}
Geht das "besser" programmiert?
Das einzige Problem ist, dass ein Reading pm25_average heißt, also ein Unterstrich enthält. Das muss ich wohl noch mit einem if abfangen?
Zitat von: TWART016 am 19 April 2020, 19:22:09
Ich möchte mich benachrichtigen lassen, wenn ein Reading eines bestimmten Gerätes sich ändert.
dann würde ich das notify direkt auf dieses bestimmte Gerät:Reading triggern lassen und nicht erst mit der dicken Kelle alles nehmen um es dann durch ein Teesieb zu drücken :)
Tipp : den Ersatzwert verwenden und auf diesen triggern.
Zitat von: Wzut am 19 April 2020, 19:40:39
dann würde ich das notify direkt auf dieses bestimmte Gerät:Reading triggern lassen und nicht erst mit der dicken Kelle alles nehmen um es dann durch ein Teesieb zu drücken :)
Tipp : den Ersatzwert verwenden und auf diesen triggern.
Bzw. möchte ich mitbekommen, ob sich ein Reading in einer gewissen Zeit nicht ändert, daher readingsWatcher.
Zitat von: Wzut am 19 April 2020, 19:40:39
um es dann durch ein Teesieb zu drücken :)
und wieder ein kleines Klößchen formen 🤣
Aber man lernt bei einem solchen Code Beispiel doch immer wieder was dazu.
@TWART016 ich wüsste es nicht besser und eine Sonderlocke wirst Du für das eine Reading noch drehen müssen. Oder Du schwenkst jetzt auf den Tipp von Wzut der es sicher besser weiß als wir zwei. ;) Vielleicht schüttelt der ja noch ein Beispiel aus dem Ärmel :)
Das mit der Sonderlocke ist in dem Fall kein Problem. Hatte mich nur gefragt, ob man das "schöner" programmieren kann, als mein letztes Beispiel.
Ich möchte eben bestimmte Readings auf Nicht-Änderung überwachen, und auch wissen welches Gerät & Reading es betrifft.
readingsWatcher:.*:.timeout {
fhem ("set Telegram msg $EVENT");
my $var1="$EVTPART0";
my @arr=split('_',$var1);
my $var2=join('_',@arr[0..$#arr-1]);
my $var4=(split("_",$var1))[-1];
if ($var1 =~ /pm25_average/) {
my $varA=(split("_",$var1))[-1];
my $varB=(split("_",$var1))[-2];
my $var4=$varB ."_" .$varA;
fhem ("set Telegram msg test 01: $var4");
};
fhem ("set Telegram msg test 02: $var4");
my $out=(split(':',$var4))[0];
fhem ("set Telegram msg $var2:$out ". ReadingsVal($var2,$out,""));
}
Hier würde ich bei mit dem if prüfen ob das Reading pm25_average heißt, und dann die Variable $var4 einen neuen Wert zuweisen.
Bei bekomme ich bei test01 (richtig): pm25_average raus
Bei test02 (falsch): average
Wie kann ich die Variable in der if überschreiben?
Macht es Sinn das Reading pm25_average in eine Variable zu schreiben, um es mit mehreren erweitern zu können?
Zitat von: TWART016 am 20 April 2020, 00:36:47
Wie kann ich die Variable in der if überschreiben?
wenn du $var4 meinst -> das my weg lassen :)
Für mich sieht das aber alles recht gruselig aus, u.a. verstehe ich halt nicht wo bei der ganzen Aktion der tiefere Sinn liegt.
Besonderes der Abschnitt ReadingsVal($var2,$out,"") , der letzten Atmezug des Toten ?
Aber anyway, das Kernproblem ist doch hier der vom Modul fest vorrgebene Unterstrich _ als Trennzeichen zwischen Device_Reading.
Leider sind in FHEM die Anzahl der Sonderzeichen für so einen Trenner stark begrenzt, IMHO kommen da heute nur in Frage . - _ /
(Punkt, Minus, Underscore, Slash @all bitte mich verbessern wenn ich die Regex in goodReadingName falsch lese)
Man könnte 98_readingsWatcher auch ein neues Attribut spendieren mit dem der User festlegt wer von den vier möglichen Kandiaten benutzt wird.
my $var4=(split("_",$var1))[-1];
ist doch eigentlich:
my $var4=@arr[-1];
Warum das Array erzeugen und dann nie verwenden sondern immer wieder erzeugen?
Zu was ist die folgende Aktion gut?
if ($var1 =~ /pm25_average/) {
my $varA=(split("_",$var1))[-1];
my $varB=(split("_",$var1))[-2];
my $var4=$varB ."_" .$varA;
fhem ("set Telegram msg test 01: $var4");
};
Wenn §var1 pm25_average enthält wird es zerlegt und hinten wieder zusammengesetzt damit wieder pm25_average draus wird? Was ist da außer Stromverbrauch passiert? :D
Was hältst Du stattdessen von der zusätzlichen Zeile
$var4=$var1 if ($var1 =~ /pm25_average/);
Gruß Otto
Zitat(Punkt, Minus, Underscore, Slash @all bitte mich verbessern wenn ich die Regex in goodReadingName falsch lese)
die "perl-ecke" zeigte die tage, dass mit versteckten readings fast alles möglich ist. ;)
oder zb einfach 2 underscore hintereinander. das kann man auch gut über regex zerlegen.
Zitat von: Wzut am 20 April 2020, 07:58:41
wenn du $var4 meinst -> das my weg lassen :)
Für mich sieht das aber alles recht gruselig aus, u.a. verstehe ich halt nicht wo bei der ganzen Aktion der tiefere Sinn liegt.
Besonderes der Abschnitt ReadingsVal($var2,$out,"") , der letzten Atmezug des Toten ?
Deswegen würde ich das gerne verbessern ;) Korrekt, der letzte Wert des Readings.
Zitat von: Wzut am 20 April 2020, 07:58:41
Aber anyway, das Kernproblem ist doch hier der vom Modul fest vorrgebene Unterstrich _ als Trennzeichen zwischen Device_Reading.
Leider sind in FHEM die Anzahl der Sonderzeichen für so einen Trenner stark begrenzt, IMHO kommen da heute nur in Frage . - _ /
(Punkt, Minus, Underscore, Slash @all bitte mich verbessern wenn ich die Regex in goodReadingName falsch lese)
Man könnte 98_readingsWatcher auch ein neues Attribut spendieren mit dem der User festlegt wer von den vier möglichen Kandiaten benutzt wird.
Das wäre möglich, oder ein Reading, bei dem man das tote Reading in Verbindung mit dem Device sieht.
Zitat von: Otto123 am 20 April 2020, 09:01:31
my $var4=@arr[-1];
Warum das Array erzeugen und dann nie verwenden sondern immer wieder erzeugen?
Das wird unten bei $out verwendet.
Zitat von: Otto123 am 20 April 2020, 09:01:31
Zu was ist die folgende Aktion gut?
if ($var1 =~ /pm25_average/) {
my $varA=(split("_",$var1))[-1];
my $varB=(split("_",$var1))[-2];
my $var4=$varB ."_" .$varA;
fhem ("set Telegram msg test 01: $var4");
};
Wenn §var1 pm25_average enthält wird es zerlegt und hinten wieder zusammengesetzt damit wieder pm25_average draus wird? Was ist da außer Stromverbrauch passiert? :D
Wenn das Reading den Wert "pm25_average" enthält, wird Reading mit den letzten beiden Unterstrichen zusammen gebaut:
pm25_average
Davor war es ja nur average.
Zitat von: Otto123 am 20 April 2020, 09:01:31
Was hältst Du stattdessen von der zusätzlichen Zeile
$var4=$var1 if ($var1 =~ /pm25_average/);
Anstelle der ganz if?
Zitat von: frank am 20 April 2020, 09:18:48
oder zb einfach 2 underscore hintereinander. das kann man auch gut über regex zerlegen.
stimmt soweit hatte ich gar nicht gedacht. Ich habe dem Modul jetzt das neue Attribut delimiter verpasst, mögliche Werte - -- _ __ , default wie bisher _
Denke damit müsste jeder in irgend einer Art glücklich werden.
sorry aber Du musst meinen Text aufmerksamer lesen, eigentlich kann man den verstehen :o
Hier die DEF mit meinen Hinweisen eingearbeitet, vielleicht versteht man es so ;)
readingsWatcher:.*:.timeout {
fhem ("set Telegram msg $EVENT");
my $var1="$EVTPART0";
my @arr=split('_',$var1);
my $var2=join('_',@arr[0..$#arr-1]);
my $var4=@arr[-1];
$var4=$var1 if ($var1 =~ /pm25_average/);
fhem ("set Telegram msg test 02: $var4");
my $out=(split(':',$var4))[0];
fhem ("set Telegram msg $var2:$out ". ReadingsVal($var2,$out,""));
}
Oder ich habe was übersehen. :-\
Gruß Otto
Zitat von: Wzut am 20 April 2020, 13:23:46
stimmt soweit hatte ich gar nicht gedacht. Ich habe dem Modul jetzt das neue Attribut delimiter verpasst, mögliche Werte - -- _ __ , default wie bisher _
Denke damit müsste jeder in irgend einer Art glücklich werden.
Danke, so konnte ich es nun lösen.