[gelöst] Teil eines Readings in eine Variable

Begonnen von TWART016, 18 April 2020, 21:50:32

Vorheriges Thema - Nächstes Thema

TWART016

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

CoolTux

$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?
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

Otto123

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
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

TWART016

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?

Otto123

#4
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
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

TWART016

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");;
};

Wzut

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.
Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher

Otto123

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
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

TWART016

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?

Wzut

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.
Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher

TWART016

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.

Otto123

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  :)
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

TWART016

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.

TWART016

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?

Wzut

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.
Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher