Vorhandenes Reading in zwei Userreadings aufteilen

Begonnen von ThomasMagnum, 16 Januar 2018, 12:15:09

Vorheriges Thema - Nächstes Thema

ThomasMagnum

Hallo,

ich habe mal wieder Verständnissprobleme beim Thema regex.
Ich möchte ein vorhandenes Reading in welchem zwei Werte durch ein Komma getrennt stehen auf zwei verschiedene Userreadings aufteilen. Ich habe getestet und kann die beiden Teile per (.*),(*.) auch trennen, jedoch weiß ich nicht wie ich die einzelnen Teile benenne um sie dann in das jeweilige userreading schreiben zu können.

Hier ein Beispiel:
location 50.1468988,8.4486689

Das Reading location soll aufgeteilt werden auf deinmal das reading "lat" und einmal auf das reading "lon". Mir geht es hier nicht darum zu verstehen wie Userreadings erstellt und gesetzt werden, nur darum wie ich das vorhandene Reading trenne und auf die userreadings aufteile.


Es wäre nett wenn mir hier jemand einen Einstieg geben könnte. Die Beispiele per Suche habe ich mir durchgelesen, verstehe aber meistens nur "Bahnhof".

Vielen Dank schon mal für eure Hilfe.

Gruß, Thomas

Otto123

Hallo Thomas,

ich habe durch Zufall eine ganz gute Erklärung gefunden
https://perlmaven.com/perl-split

Hilft Dir das?

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

ThomasMagnum

Hallo Otto,

das schau ich mir heute Abend mal an.
Vielen Dank schonmal.

Gruß, Thomas

ThomasMagnum

So, ich hab mir die Seite mal angesehen und noch einige andere Hinweise gelesen. Ich bekomme es aber nicht hin. Irgendwo habe ich noch ein Verständnisproblem.
Was hab ich gemacht. Ich will die beiden Userreadings "lat" und lon" ertsellen. Dazu habe ich nun das folgende entwickelt:

{my $str = fhem("livetracking location"); my $l = split(.*),(.*) $str; fhem("setreading livetracking lat $l[0] ; setreading livetracking lon $l[1]");}

Der Theorie:
{my $str = fhem("livetracking location") soll das zu Teilende Reading sein, mit my $l = split(.*),(.*) $str soll das Reading aufgeteilt werden. Und zu guter letzt sollen per fhem("setreading livetracking lat $l[0] ; setreading livetracking lon $l[1]") die beiden userreadings "lat" und "lon" erstellt werden.

Leider passiert aber nichts, habt ihr noch ein, zwei Hinweise für mich?

livetracking ist das Device und location das Reading.

Gruß, Thomas

KernSani

Wie rufst du o.g. Code denn auf? Im userreading Attribut? Gibt es irgendwelche logeinträge? Vielleicht würde es auch Sinn machen, das Ganze in myUtils auszulagern und ein paar Logmeldungen rausschreiben. Im Übrigen mag es FHEM nicht so gerne wenn im userreading set Befehle auf sich selbst aufgerufen werden (setreading sollte da eigentlich unkritisch sein, bin mir aber nicht sicher)
RasPi: RFXTRX, HM, zigbee2mqtt, mySensors, JeeLink, miLight, squeezbox, Alexa, Siri, ...

ThomasMagnum

Ja, genau. Ich rufe das per Attribut "userReadings" auf. Der Code steht im entsprechenden Feld.

Logeinträge habe ich keine, ebenso werden keinerlei Events generiert.

Ich werde mal versuchen das Ganze in die myUtils auszulagern und den Code über ein Notify aufzurufen.

Da ich leinerlei Programierbackground habe bin ich mir halt unsicher ob der Code als soches stimmt  :-\

KernSani

ein "list" eines devices heisst,
list meinDevice
in die Kommandozeile eingeben und dann den (kompletten) Output posten (in code tags - das # oben im Editor).

das userReadings Attribut ist falsch. Syntax ist laut CommandRef:
<reading>[:<trigger>] [<modifier>] { <perl code> }
bei dir fehlt zumindest das reading. Da du aber eigentlich kein einzelnes Reading willst, wäre es besser, das Ganze über notify zu lösen. Zum testen kannst du deinen Code (inkl. der geschweiften Klammern) aber auch einfach oben in die Kommandozeile eingeben.

{my $str = fhem("livetracking location")
macht auch keinen Sinn, du meinst wahrscheinlich sowas wie:
{my $str = ReadingsVal("livetracking","location", undef)
das würde dir den Wert des Attributs "location" des Device "livetracking" zurückgeben.


RasPi: RFXTRX, HM, zigbee2mqtt, mySensors, JeeLink, miLight, squeezbox, Alexa, Siri, ...

Braakhekke

Hallo Thomas,

ich habe bei mir ein Userreading angelegt mit folgendem Inhalt

lat:location.* {(split(",",ReadingsVal($NAME,"location","")))[0]},lon:location.* {(split(",",ReadingsVal($NAME,"location","")))[1]},GoogleMapsCenter {ReadingsVal("livetrackingdata","location","")}

vielleicht hilft Dir das.

Grüße Ben
1 x NUC mit PROXMOX (ct FHEM mit Tablet UI, ct Zoneminder v1.30.4, ct habridge) 2 x Raspberry Pi Modell 3, WLAN, HMLAN, V 1.67 nanoCUL868, nodemcu esp8266, viele HM-Komponenten, KS300, HUEDevice

Christoph Morrison

Zitat von: ThomasMagnum am 16 Januar 2018, 19:49:19
So, ich hab mir die Seite mal angesehen und noch einige andere Hinweise gelesen. Ich bekomme es aber nicht hin. Irgendwo habe ich noch ein Verständnisproblem.
Was hab ich gemacht. Ich will die beiden Userreadings "lat" und lon" ertsellen. Dazu habe ich nun das folgende entwickelt:

{my $str = fhem("livetracking location"); my $l = split(.*),(.*) $str; fhem("setreading livetracking lat $l[0] ; setreading livetracking lon $l[1]");}

Der Theorie:
{my $str = fhem("livetracking location") soll das zu Teilende Reading sein, mit my $l = split(.*),(.*) $str soll das Reading aufgeteilt werden. Und zu guter letzt sollen per fhem("setreading livetracking lat $l[0] ; setreading livetracking lon $l[1]") die beiden userreadings "lat" und "lon" erstellt werden.

Ich zitiere mal perldoc zum Thema Pattern bei split:
ZitatAnything in EXPR that matches PATTERN is taken to be a separator that separates the EXPR into substrings (called "fields") that do not include the separator. Note that a separator may be longer than one character or even have no characters at all (the empty string, which is a zero-width match).

Dein PATTERN lautet (.*),(.*) und das ist zwar ein reguläres PATTERN, matcht aber auf den gesamten String, ergo ist dein Ergebnis eine leere Liste. Du kannst einfach mit /,/ splitten und wirst eine Liste mit zwei Elementen erhalten.

Zusätzlich rufst du split im Skalar-Kontext ($l = split) auf, was bedeutet, dass $l später nur die Anzahl der erhaltenen Elemente (beim richtigen Pattern und deinem Beispiel also 2) enthalten wird. perldoc:
Zitat
Splits the string EXPR into a list of strings and returns the list in list context, or the size of the list in scalar context.

Noch ein kleiner Hinweis: $l ist kein besonders guter Bezeichner. In deinem Falle könnte jemand anderes nämlich $l für $length halten, da du ja split im skalaren Kontext aufrufst, obwohl du vermutlich $location meinst. Zusätzlich kann man je nach verwendetem Font nicht trivial unterscheiden, ob l (kleines L) oder 1 (arabisch 1) gemeint ist.