Hallo,
Ich erzähl mal kurz was ich suche,
Ich habe mir ein LoRa ( Nicht LoRaWAN ) Gateway gebaut, das die empfangenen Daten von LoRa in einem String per MQTT an FHEM sendet.
Als Testbeispiel sieht das im Fhem so aus
2020-04-30_20:39:42 MQTT2_TTGO MESSAGE: hello 28 RSSI: -94
2020-04-30_20:39:43 MQTT2_TTGO MESSAGE: hello Arduino Radio 12 RSSI: -104
Wenn ich jetzt den Wert hinter "RSSI:" in eine Getrennte Variable schreiben will, wie kann ich das am geschicktesten anstellen?
Später sollen hier von verschiedenen Sensoren die Daten ausgelesen werden, statt RSSI kann dann hier auch Temp, Hu, press, Wind usw. stehen
Ich hatte mir schon Gedanken gemacht mit userReadings und split, das würde gehen wenn jeder LoRa Sensor an der gleichen stelle den richtigen Wert liefert, was wird aber nicht möglich sein, daher müsste man gezielt in diesem Beispiel nach RSSI: suchen und den Wert dahinter lesen.
Z.B. mit Regex?
RSSI:.(.*)
Das Zauberwort heißt "regular expression"
Wenn man die Gewißheit hat, dass der Wert immer an letzter Stelle steht, geht es auch einfacher, indem man split benutzt und dann den letzten Wert des splits verwendet.
Genau das ist es ja es werden verschiedene Wert drin stehen und nicht immer als letztens.
Bin leider nicht ganz so tief drin wie ich das mit Regex machen soll.
Könntest du mir ein Beispiel geben?
Zitat von: Edi77 am 30 April 2020, 23:14:24
Könntest du mir ein Beispiel geben?
steht doch schon weiter oben?
Hi,
Ich glaube man kann das beliebig kompliziert machen. So habe ich mal in der FHEM Kommandozeile getestet:
{my $val="hello 28 RSSI: -94 falls da noch was kommt";;$val=~s/RSSI:.([-\d.]+)/$1/eg;;return $1}
Zum Testen und lernen https://regex101.com/
Gruß Otto
Ok Danke
Habe es fürs erste mal hin bekommen
attr MQTT2_TTGO userReadings RSSI {my $val=ReadingsVal("MQTT2_TTGO", "MESSAGE", 0);;$val=~s/RSSI:.([-\d.]+)/$1/eg;;return $1}
Der Link regex101.com finde ich interessant wobei ich noch nicht weiß wie man das richtig benutzt ::)
Würde gerne verstehen wie genau "$val=~s/RSSI:.([-\d.]+)/$1/eg;;return $1" funktioniert, gibt es da eine Übersicht?
Man brauch hier keine Substitution (s). Ein simple Match (m) reicht
{my $val="hello 28 RSSI: -94 falls da noch was kommt";;$val=~m/RSSI:.([-\d.]+)/;;return $1}
Das "g" Modifier ist nicht nötig, da wir so wie so nur den ersten Match wollen.
Wie RSSI:.([-\d.]+)
funktioniert kriegst Du genau Schritt für Schritt auf Regex101 exklärt (oben rechts)
return $1 bringt einfach die erste (und hier einzige) "capturing group" zurück
Die Variante von Otto macht dazu eine (meiner Meinung nach unnötige) Ersetzung: die ersetzt in $val "RSSI:.([-\d.]+)" durch die capturing group, und dann macht ein return von der capturing group. Also, im Beispiel:
"hello 28 RSSI: -94 falls da noch was kommt" ==> "hello 28 -94 falls da noch was kommt" und dann -94 zurück
Das "e" Modifier ist ebenso nicht nötig, da wir keine besondere Kalkulation in dem Ersatz machen.
Danke für die später Erklärung ;D
Wenn ich jetzt den Counter hinter Radio also die "12" auslesen will und dies als Wert hinzufügen will
attr MQTT2_TTGO userReadings Counter {my $val=ReadingsVal("MQTT2_TTGO", "MESSAGE", 0);;$val=~s/Radio:.([-\d.]+)/$1/eg;;return $1}
geht das leider nicht. Kann man immer nur ein "userReadings" erstellen?
Habe ich das so richtige eingestellt?
Zitat von: Edi77 am 01 Mai 2020, 02:50:16
Kann man immer nur ein "userReadings" erstellen?
Siehe Doku
ZitatuserReadings
Komma getrennte Liste von benutzerdefinierten Readings. Jede Definition hat folgendes Format:
<reading>[:<trigger>] [<modifier>] { <perl code> }
Das hier ist deine Regular Expression (Feld oben):
RSSI:.([-\d.]+)
Das ist Dein Teststring (Feld unten):
hello 28 RSSI: -94 falls da noch was kommt
Zitat von: Edi77 am 30 April 2020, 22:16:25
Ich habe mir ein LoRa ( Nicht LoRaWAN ) Gateway gebaut, das die empfangenen Daten von LoRa in einem String per MQTT an FHEM sendet.
Kannst du den String beeinflussen? Wenn ja, sende die Daten doch in einem JSON Format.
Dann könntest du das dynamischer auslesen im MQTT Device:
attr MQTT_DEVICE readingList Device:topic/bla/blub:.* { json2nameValue($EVENT,'',$JSONMAP) }