[gelöst] Reading splitten, aber wie genau ?

Begonnen von Ma_Bo, 26 Juni 2016, 16:38:15

Vorheriges Thema - Nächstes Thema

Ma_Bo

Hallo, ich habe folgendes Reading und möchte es mittels userReadings splitten, aber wie genau stelle ich das an ?

Reading2 : {"battery":"100.0","ip":"109.44.3.170"}

Ich kann mittels split folgendes Reading teilen:

Reading1 : ID 3057673 Hoehe 117.53236489191546

dafür lege ich ein userReadings an mit
attr Testdevice userReadings ID:Reading1.* {(split(' ', ReadingsVal("$name","Reading1",""), 3))[1]},Hoehe:Reading1.* {(split(' ', ReadingsVal("$name","Reading1",""), 5))[3]}

und erhalte 2 neue Readings mit den dazugehörigen Werten.

Wie aber bekomme ich das oben gennante Reading gesplittet ?

Grüße Marcel
NUC mit FHEM, HM Heizungsthermostate, HM Wandthermostate, Intertechno Funksteckdosen, 10" Tablet als Wanddisplay, KeyMatic, Fensterkontakte, Fensterkontakte umgebaut als Wassermelder und Briefkastenmelder, Aussenthermostat, Anwesenheitssteuerung über Fritz Box, Google Home usw. usw.

Ellert


Ma_Bo

#2
Ich möchte Reading 2 splitten und dann ein Reading

battery 100.0

und ein Reading

ip 109.44.3.170

haben.

Es sollen also 2 neue Readings enstehen und die " und die : sollen raus und am Anfang die eckige Klammer und am Ende die eckige Klammer müssen weg bzw. auch das Komma in der Mitte.
NUC mit FHEM, HM Heizungsthermostate, HM Wandthermostate, Intertechno Funksteckdosen, 10" Tablet als Wanddisplay, KeyMatic, Fensterkontakte, Fensterkontakte umgebaut als Wassermelder und Briefkastenmelder, Aussenthermostat, Anwesenheitssteuerung über Fritz Box, Google Home usw. usw.

viegener

Ich würde so etwas mit regular expressions machen, da kannst Du am gezieltesten die einzelnen Teile herausholen und musst keine grossen Funktionskonstrukte bauen.

Ohne es jetzt ausprobiert zu haben könntest Du so etwas machen um den Wert von Battery herauszulesen, der Wert in der () wird dann in ein Reading battery gepackt

attr Testdevice userReadings battery { ReadingsVal("$name","Reading2","") =~ /battery\":\"([^\"]*)\"/; return $1 }
Kein Support über PM - Anfragen gerne im Forum - Damit auch andere profitieren und helfen können

Ma_Bo

ZitatIch würde so etwas mit regular expressions machen, da kannst Du am gezieltesten die einzelnen Teile herausholen und musst keine grossen Funktionskonstrukte bauen.

Ohne es jetzt ausprobiert zu haben könntest Du so etwas machen um den Wert von Battery herauszulesen, der Wert in der () wird dann in ein Reading battery gepackt


attr Testdevice userReadings battery { ReadingsVal("$name","Reading2","") =~ /battery\":\"([^\"]*)\"/; return $1 }

Vielen Dank, das funktioniert !
NUC mit FHEM, HM Heizungsthermostate, HM Wandthermostate, Intertechno Funksteckdosen, 10" Tablet als Wanddisplay, KeyMatic, Fensterkontakte, Fensterkontakte umgebaut als Wassermelder und Briefkastenmelder, Aussenthermostat, Anwesenheitssteuerung über Fritz Box, Google Home usw. usw.

justme1968

#5
das schaut nach json aus. das sollte man eigentlich auch als json parsen statt auf zu splitten oder mit einer regex zu arbeiten. da ganze ist auch besser in einem notify aufgehoben statt in einem user reading weil für jedes reading immer wieder gesplittet würde. dort würde so etwas etwa so aussehen:sub
json2readings($$)
{
  my ($name,$reading) = @_;

  my $hash = $defs{$name};
  return if( !$hash );

  if( my $decoded = eval { decode_json($reading) } ) {
    readingsBeginUpdate($hash);
    foreach my $reading (keys $decoded) {
      readingsBulkUpdate($hash, $reading, $decoded{$reading});
    }
    readingsEndUpdate($hash,1);

  } else {
    Log3 $name, 3, "empty or invalid json received";

  }
}
übergeben wird der device name in den die readings sollen und der json string.


wo kommen denn diese readings her? im httpmod modul gibt es extra die möglichkeit json zu dekodieren. und es gibt hier im forum ein JSONREADINGS modul.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

dev0

Müßte es nicht statt "foreach my $reading (keys $decoded) {"

foreach my $key (keys $decoded) {

lauten?

justme1968

hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

Ma_Bo

Also, die Readings lasse ich mir durch ein php script aus einer SQL Datenbank in einen Dummy schreiben.
Ich bekomme aber alle Werte als ein Reading, so dass ich dieses splitten muss.

Evtl. hat ja jemand Lust und Zeit um sich das mal anzuschauen, ich wusste mir weiter nicht zu helfen und meine Methode funktioniert wunderbar seit ca. 1/2 Jahr.

Es geht sich um eine Software mit der ich 2 Handy´s tracke, die APP für die Handy´s schreibt alle 10 Sekunden ihre Daten in die Datenbank und mit der Software, welche über die WEBUI erreichbar ist, zeigt mir dann einige Werte, Position, Geschwindigkeit usw. an.

Die Software bietet auch eine API aber wie gesagt, ich kam "damals" damit nicht weiter und habe den Umweg dann hergestellt.

Unter folgendem Link ist die Funktion usw erklärt, das ganze ist Open Source : https://www.traccar.org

Eine geänderte WEBUI, die ich nutze und die auch die API bereitstellt : http://traccar.litvak.su/features/

Falls jemand Lust hat, kann er sich das ja mal anschauen.

Grüße Marcel
NUC mit FHEM, HM Heizungsthermostate, HM Wandthermostate, Intertechno Funksteckdosen, 10" Tablet als Wanddisplay, KeyMatic, Fensterkontakte, Fensterkontakte umgebaut als Wassermelder und Briefkastenmelder, Aussenthermostat, Anwesenheitssteuerung über Fritz Box, Google Home usw. usw.

tschimi

Hi, ich hab ein ähnliches Problem und bin am Verzweifeln. Mein String sieht so aus:

{"Time":"2019-04-19T16:24:45","ANALOG":{"A0":1},"TX20":{"Speed":0.00,"SpeedAvg":0.00,"SpeedMax":0.00,"Direction":"NE"}}

Nun möchte ich Speed, SpeedAvg und SpeedMax auf eigene Userreadings verteilen.

Versucht hab ich glaube ich fast alle Varianten von: SpeedMax { ReadingsVal("$name","state","") =~ /SpeedMax"\:([0-9]*)\,//; return $1 }
aber ich bekomme es nicht hin :-(

hat jemand einen Tipp?

Dankeschön, tschimi

CoolTux

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

tschimi

Nun, genau, das funktioniert für "Direction". Die anderen Werte sind aber leider NICHT in Anführungszeichen. Ich hab jetzt aber einen Workaround gemacht - nicht schön aber es geht...

   
Direction { ReadingsVal("$name","state","") =~ /Direction\":\"([^\"]*)\"/; return $1 },
SpeedMax {(split ",",((split ":",(ReadingsVal("$name","state","")))[9]))[0]},
SpeedAvg {(split ",",((split ":",(ReadingsVal("$name","state","")))[8]))[0]},
Speed {(split ",",((split ":",(ReadingsVal("$name","state","")))[7]))[0]}

Lg, Tschimi

justme1968

#12
die werte sind nicht in anführungszeichen weil es zahlen und keine strings sind. 

die routine von oben sollte auch damit klar kommen.

die wird aber nicht in userReadings gesteckt sondern in ein einzelnes notify. danach kümmert sie sich selber um alle werte und legt je ein reading für jeden wert an.

das ist deutlich effizienter da nur ein mal gesplittet wird und nicht für jedes reading immer wieder.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968