RegEx Problem (war "readingsGroup Wert aufsplitten")

Begonnen von der_da, 19 Mai 2016, 13:58:56

Vorheriges Thema - Nächstes Thema

der_da

Hallo!

Ich habe eine readingsGroup "statisticsTerrasse" angelegt, in der unter anderem folgendes Reading enthalten ist:
Terrasse:statTemperatureDay Min: 11.2 Avg: 15.2 Max: 23.0
Mein Problem ist, dass ich nur den Durchschnittswert (im Beispiel also 15.2) aus dem String rausholen möchte, um ihn weiter zu verarbeiten.
Kann mir bitte jemand einen Tipp geben?

Elektrolurch

Leider ist nicht ganz klar, was Du machen möchtest und was das mit einer readingsGroup zu tun hat.
Wie soll die "Weiterverarbeitung" geschehen?

Ich denke, dass Du ohne perl da nicht weiter kommen wirst.
1. Den Wert eines readings erhälst Du mit der perl-Funktion ReadingsVal($device$readingname,'default')
bzw. wird der perl-Ausdruck innerhalb der Attribut-Definition der readingsGroup veerwendet, so stehen Dir die Platzhalter: $DEVICE, $READING bzw. $VALUE zur Verfügung.
2. Den teilwert kannst Du mit einer regex z.B. so extrahieren:

=~m/avg:([\d.]+) /
In der perl-Variable $1 müsste dann der Wert hinter avg: extrahiert sein.

Elektrolurch
configDB und Windows befreite Zone!

der_da

Ok, dann hole ich doch noch etwas weiter aus:
Ich habe mittels dem Modul statstics meinem Thermometer auf der Terrasse weitere berechnete Werte hinzugefügt. So enthält mein Thermometer "Terrasse" nun neben den gemessenen Werten auch noch solche statistischen Werte (Readings) wie eben auch "statTemperatureDay Min: 11.2 Avg: 15.2 Max: 23.0"

Nun möchte ich am Abend den Tages-Durchschnittswert der Temperatur heranziehen und entscheiden, ob die automatische Bewässerung nur normal bewässert oder wegen großer Hitze etwas länger laufen soll. So in etwa:
Wenn Tagesdurchschnittstemperatur < 25 (°C) dann bewässere normal
DOELSIF
Wenn Tagesdurchschnittstemperatur >=25 (°C) dann bewässere mehr.

"Leider" liefert das statistics-Modul diese Durchschnittstemperatur aber nicht als Einzelwert.
Ich werde mal versuchen, deine Tipps umzusetzen.

der_da

Tja, das liebe Perl ist noch nicht so meins  :-\.
Ich habe folgendes DOIF
([19:00]) ({
  my $x_statTemperatureDay = ReadingsVal("Terrasse","statTemperatureDay",'');;
  my $x_statTemperatureDay = ~m/avg:([\d.]+) /;;
  my $x_avgTempDay = $1;;
  fhem("set du_avgTemp $x_avgTempDay");;
})

welches aber nicht funtioniert.

Die Variable $x_avgTempDay ist nicht gefüllt. Also scheint das RegEx nicht korrekt zu sein. Oder?

igami

Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

Elektrolurch

Du kannst das auch schrittweise testen, in dem Du den Ausdruck, der in {...} steht (perl), in dem fhem - Kommandozeile eingibst.

z.B. erst nur den Aussdruck mit ReadingsVal, fhem ruft dann den perl - Interpreter auf und rechts im Fenster siehst Du dann das Ergebnis. Ausgegeben wird eigentlich immer das Ergebnis des letzten (rechten) Ausdrucks. Du kannst aber auch eine einzelne Variable mit return <$variable> ausgeben. Auf diese Weise kannst Du das Ganze schrittweise durchprobieren....

{ my $t = ReadingsVal("Terrasse","statTemperatureDay",'avg:99');;$t = ~m/avg:([\d.]+) /;;  t = $1;;
  fhem("set du_avgTemp $t");;
}
Fehlerhaft war schon mal, dass vor jeder Anweisung das "my" stand. Die Variable $t muss nur einmal deklariert werden!
Schrittweise von links nach rechts hinter jedem ;; ein return $t einfügen, dann kannst Du die Abarbeiten durchtesten.
Die regex geht davon aus, dass da avg:15.5 (ohne Leerzeichen nach dem :) steht. Bittte prüfen.

Elektrolurch
configDB und Windows befreite Zone!

der_da

#6
{my $t = ReadingsVal("Terrasse","statTemperatureDay",'Avg:99')}
liefert:
Min: 11.2 Avg: 15.2 Max: 23.0

{$t = ~m/Avg:([\d.]+) /}
liefert:
Global symbol "$t" requires explicit package name at (eval 90135) line 1.

:-[

Elektrolurch

Entschuldigung, aber ein bisserl Mitdenken wäre auch schon angebracht:

1. der ReadingsVal - Ausdruck ist ok.
2. Mit dem Ergebnis davon wird danach in dem GLEICHEN  perl-Ausdruck das Suchen mit der regex aufgerufen.
Alleine nur die regex aufrufen macht doch keinen Sinn, dann ist doch klar, das $t da nicht mehr definiert ist.

Und: Wie man an dem Ergebnis der ersten Zeile sieht, ist da hinter dem AVG: noch ein Leerzeichen, das muss in der regex natürlich auch noch berücksichtigt werden.

also so m/Avg: ([\d\.]+) /

Alles was da in () gefunden wird, geht nach $1.
also beliebig viele Ziffern und ".", die müssen abermindestens einmal vorkommen. Negative Temperaturen werden nicht erkannt.

Elektrolurch
configDB und Windows befreite Zone!

der_da

Zitat von: Elektrolurch am 20 Mai 2016, 08:40:04
Entschuldigung, aber ein bisserl Mitdenken wäre auch schon angebracht:

Tschuldigung, aber ich habe es schon versucht, habe aber irgendwie einen Knoten im Kopf  :-\ Bin kein Programmierer.

Zitat von: Elektrolurch am 20 Mai 2016, 08:40:04
also so m/Avg: ([\d\.]+) /

Alles was da in () gefunden wird, geht nach $1.
also beliebig viele Ziffern und ".", die müssen abermindestens einmal vorkommen.

Ich habe jetzt folgendes gemacht:
({ my $t = ReadingsVal("Terrasse","statTemperatureDay",'Avg:99');;
   fhem ("set du_Test1 $t");;
   $t = ~m/Avg:([\d.]+) /;;
   fhem ("set du_Test2 $t");;
   $t = $1;;
  fhem("set du_avgTemp $t");;
})

und als Ergebnis steht nun in du_Test1: Min: 8.0 Avg: 11.3 Max: 20.9
in du_Test2: 18446744073709551615
ind du_avgTemp wirft Fehler: no set value specified

Das Regex macht also nicht das, was es soll. :-\

ernst1024

wenn ich das hier so überfliege, dann sollte das modul average wie für dich gemacht sein
Gruß Ernst

der_da

Zitat von: ernst1024 am 20 Mai 2016, 11:16:24
wenn ich das hier so überfliege, dann sollte das modul average wie für dich gemacht sein
Danke!
Ja, damit geht es, denn da stehen die Werte jeweils einzeln drin. Habe es jetzt damit gelöst.
Trozdem wäre ich sehr daran interessiert, wie man mit der richtigen RegEx den Mittelwert aus dem anderen Reading "herauspolken" kann.
Auf der Seite regex101.com habe ich das Regex "Avg: ([\d.]+)" erfolgreich auf meinen String "Min: 8.0 Avg: 11.3 Max: 20.9" losgelassen und es wird genau der Wert "11.3" extrahiert. Nur im FHEM wird daraus irgendwie nix (siehe mein vorheriger Beitrag).  :-\

Hans Franz

Hab's jetzt nicht nachgestellt, aber:
$t = ~m/Avg:([\d.]+) /;
sollte so ausshehen:
$t =~ m/Avg:([\d.]+) /;

Gruß
Hans
Raspi
CUL, Nano-CUL
FHT8V, FHT80B, S300TH
WM1000WZ, ELRO
LW12, LD382,DS18B20

igami

DOIF kann das mit einfacher Syntax

define regex_DOIF DOIF ([Terrasse:statTemperatureDay])(set du_avgTemp [Terrasse:statTemperatureDay:"Avg: ([-\d\.]+)":$1])


Grüße
igami
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

der_da

Zitat von: Hans Franz am 20 Mai 2016, 12:53:52
Hab's jetzt nicht nachgestellt, aber:
$t = ~m/Avg:([\d.]+) /;
sollte so ausshehen:
$t =~ m/Avg:([\d.]+) /;
Bei mir klappt das beides nicht. Der Unterschied ist auch nur das Leerzeichen vor der ~
Trotzdem Danke Hans!  ;)

Zitat von: igami am 20 Mai 2016, 12:56:18
DOIF kann das mit einfacher Syntax

define regex_DOIF DOIF ([Terrasse:statTemperatureDay])(set du_avgTemp [Terrasse:statTemperatureDay:"Avg: ([-\d\.]+)":$1])


Grüße
igami
Danke! Das klappt jetzt auch.

Hans Franz

In
$t =~ m/Avg:([\d.]+) /;
fehlt noch ein Leerzeichen.
$t =~ m/Avg: ([\d.]+) /;
Jetzt sollte in $1 der richtige Wert stehen.

Gruß
Hans
Raspi
CUL, Nano-CUL
FHT8V, FHT80B, S300TH
WM1000WZ, ELRO
LW12, LD382,DS18B20