Neues Modul JSONREADINGS zur Einbindung beliebiger json-Daten per URL

Begonnen von bgewehr, 24 Juni 2015, 15:46:38

Vorheriges Thema - Nächstes Thema

bgewehr

Hallo,

mir schwebt ein Modul JSONREADINGS vor Augen, das per URL oder File aus beliebigen Quellen JSON-Daten holt und dann diese Quellen als Readings in fhem angezeigt werden.

Edit:
Hier der direkte Link zum Modul (Mitarbeit ist herzlich willkommen):

https://github.com/bgewehr/fhem/blob/master/FHEM/70_JSONREADINGS.pm

Angenommen, das json ist einfach:
{"key":"value"}

dann soll das Reading key mit dem Wert value angelegt werden.

Wenn das json etwas schwieriger wird, dann soll das entsprechend analysiert und ausgewertet werden:

{"Year":"2012","Quarter":"Q3","DataType":"Other 3","Environment":"STEVE","Amount":125}

dann sollen die Readings Year, Quarter, DataType, Environment und Amount mit den entsprechenden Werten  angelegt werden.

Wenn nun das ganze noch komplizierter wird:

[{"Year":"2012","Quarter":"Q3","DataType":"Other 3","Environment":"STEVE","Amount":125},{"Year":"2012","Quarter":"Q4","DataType":"Other 2","Environment":"MIKE","Amount":500}]

dann sollen die Readings Year_01, Year_02, Quarter_01, Quarter_02, DataType_01, DataType_02, Environment_01, Environment_02 und Amount_01, Amount_02 mit den entsprechenden Werten  angelegt werden.

Es kann aber noch komplizierter werden:
[{"Year":"2012","Quarter":"Q3","DataType":"Other 3","Environment":[{"Partner":"STEVE"},{"Location":"home"}],"Amount":125},{"Year":"2012","Quarter":"Q4","DataType":"Other 2","Environment":[{"Partner":"MIKE"},{"Location":"home"}],"Amount":500}]

dann sollen die Readings Year_01, Year_02, Quarter_01, Quarter_02, DataType_01, DataType_02, Environment_01_Partner, Environment_01_Location, Environment_02_Partner, Environment_02_Location und Amount_01, Amount_02 mit den entsprechenden Werten  angelegt werden.

Dazu müsste nach dem Abholen des json Strings ein Schleife wie folgt laufen:

Angenommen die maximale Schachtelung ist 4 (ich will die Rekursion vermeiden!)


my $data = decode_json($result);

if (%$data) { 
    for $subdata1 (%data) {
       if (%$subdata1) { 
           for $subdata2 (%subdata1) {
              if (%$subdata2) { 
                  for $subdata3 (%subdata2) {
                     if (%$subdata3) { 
                         for $subdata4 (%subdata3) {
                            mach was; #Ebene 4
                         }
                     }
                     else {
                        mach was; #Ebene 3
                     }
                  }   
              else {
                  mach was; #Ebene 2
              }
           }   
           else {
               mach was; #Ebene1
        }
     }
  else {
    da is nix drin, also mach nix;
  }   
}


Kann das jemand von Euch so richtig elegant? Ich schaffe es nicht...

Auch eine nicht auf eine Ebenenzahl begrenzte Lösung wäre natürlich noch besser...

Ich bin sicher, dafür würde es viele Verwendungen geben, Daten von außen erstmal zu holen, so als genericJSON interface.
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

justme1968

warum willst du die rekursion vermeiden? das ist doch genau eine der eleganten methoden....

eine stack basiert lösung könnte noch eine alternative sein aber nicht prinzipiell anders.

gerade wenn du keine einschränkung bezüglich ebenen und verschachtelung willst macht alles andere keinen sinn.

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

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

bgewehr

Also eine

sub json_rekursiv($object)
If (%$object) {
json_rekursiv (%$objekt);
} else {
for $key (keys(%$objekt)) {
print $key.": ".$objekt->$key
}
}


Oder so ähnlich.

Wie komme ich wenn ich am Blatt bin, wieder zurück zur Wurzel, um mir den Pfad zum Blatt als Readingsname zu bauen?

Kann bitte jemand mal einen realcode Vorschlag machen? Ich tappe noch so Pseudocode mäßig im Dunkeln...
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

Dietmar63

vielleicht kannst du in Volkszaeher abschreiben.
http://www.fhemwiki.de/wiki/Volkszaehler#JSON_f.C3.BCr_Perl
Selbst parsen ist bestimmt nicht leicht.
Deshalb  dieses Modul nutzen:
http://search.cpan.org/~makamaka/JSON-2.90/lib/JSON.pm

Dann verwandelt das Modul den json-String bestimmt in ein %Hash und das läst sich am besten rekursiv verarbeiten.
Gruß Dietmar
FB7390, CUL, 2 FHT, FS20
modules: 98_WOL.pm, 98_Heating_Control.pm,   98_WeekdayTimer.pm, 98_RandomTimer.pm, 59_Twilight.pm

Dietmar63

oder hier: 70_JSONMETER.pm
in der Methode JSONMETER_ParseJsonFile kannst du sehen was es bedeutet selbst zu parsen.
Gruß Dietmar
FB7390, CUL, 2 FHT, FS20
modules: 98_WOL.pm, 98_Heating_Control.pm,   98_WeekdayTimer.pm, 98_RandomTimer.pm, 59_Twilight.pm

Dietmar63

weitere Beispiele:
Zitat
01_FHEMWEB.pm
10_pilight_ctrl.pm
30_HUEBridge.pm
30_LIGHTIFY.pm
31_LightScene.pm
32_withings.pm
33_readingsHistory.pm
37_harmony.pm
38_JawboneUp.pm
38_netatmo.pm
70_JSONMETER.pm
70_PHTV.pm
70_Pushalot.pm
70_Pushbullet.pm
70_Pushover.pm
70_XBMC.pm
72_FB_CALLLIST.pm
73_km200.pm
93_DbLog.pm
98_HTTPMOD.pm
98_JsonList2.pm
98_JsonList.pm
98_UbiquitiMP.pm

wobei 10_pilight_ctrl.pm ein gutes Beispiel für das JSON-Modul ist:


...
    my $json = JSON->new;
    my $jsondata = $json->decode($rcv);
Gruß Dietmar
FB7390, CUL, 2 FHT, FS20
modules: 98_WOL.pm, 98_Heating_Control.pm,   98_WeekdayTimer.pm, 98_RandomTimer.pm, 59_Twilight.pm

bgewehr

Das use JSON; ist nicht das Problem, damit kann man einfach umgehen.

Ich habe jetzt diesen Code gefunden:
http://stackoverflow.com/questions/13403397/perl-hash-of-hashes-of-hashes-of-hashes-is-there-an-easy-way-to-get-an-elem


sub traverse (&$@) {
    my ($do_it, $data, @path) = @_;

    # iterate
    foreach my $key (sort keys %$data) {

        # handle sub-tree
        if (ref($data->{$key}) eq 'HASH') {
            traverse($do_it, $data->{$key}, @path, $key);
            next;
        }

        # handle leave
        $do_it->($data->{$key}, @path, $key);
    }
}


also eine rekursive Abwicklung auf flache Pfade und den Werten am Ende der Zweige als Werte - perfekt.

Wer mag mir helfen, das in ein fhem Perl-Modul zu packen?

Ich habe fhem in den letzte Stunden schon zig mal neu starten müssen, weil es leider bei diesen Versuchen dauernd abstürzt... komme dennoch nicht recht voran.
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

justme1968

du musst zwei dinge unterscheiden:
- das parsen von json in eine perl datenstruktur. das würde ich nicht selber machen. die json lib ist wunderbar dafür
- das erzeugen der readings aus den geparsed würde ich rekursiv in etwa so machen:

use strict;                                                                     
use warnings;                                                                   
                                                                               
use JSON;                                                                       
                                                                               
sub toReadings($;$$);                                                           
sub                                                                             
toReadings($;$$)                                                               
{                                                                               
  my ($ref,$prefix,$suffix) = @_;                                               
  $prefix = "" if( !$prefix );                                                 
  $suffix = "" if( !$suffix );                                                 
  $suffix = "_$suffix" if( $suffix );                                           
                                                                               
  if(  ref($ref) eq "ARRAY" ) {                                                 
    while( my ($key,$value) = each $ref) {                                     
      toReadings($value,$prefix,sprintf("%02i",$key+1));                       
    }                                                                           
  } elsif( ref($ref) eq "HASH" ) {                                             
    while( my ($key,$value) = each $ref) {                                     
      if( ref($value) ) {                                                       
        toReadings($value,$prefix.$key.$suffix."_");                           
      } else {                                                                 
        printf "readingsSingleUpdate(\$hash, '$prefix$key$suffix', '$value', 1);\n";
      }                                                                         
    }                                                                           
  }                                                                             
}                                                                               
                                                                               
                                                                               
my $json = '{"key":"value"}';                                                   
                                                                               
$json = '{"Year":"2012","Quarter":"Q3","DataType":"Other 3","Environment":"STEVE","Amount":125}';
                                                                               
$json = '[{"Year":"2012","Quarter":"Q3","DataType":"Other 3","Environment":"STEVE","Amount":125},{"Year":"2012","Quarter":"Q4","DataType":"Other 2","Environment":"MIKE","Amount":500}]';
                                                                               
$json = '[{"Year":"2012","Quarter":"Q3","DataType":"Other 3","Environment":[{"Partner":"STEVE"},{"Location":"home"}],"Amount":125},{"Year":"2012","Quarter":"Q4","DataType":"Other 2","Environment":[{"Partner":"MIKE"},{"Location":"home"}],"Amount":500}]';
                                                                               
                                                                               
my $decoded = decode_json( $json );                                             
toReadings($decoded);


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

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

bgewehr

#8
@Andre, das ist nah dran:

Aus


{
  "response": {
  "version":"0.1",
  "termsofService":"http://www.wunderground.com/weather/api/d/terms.html",
  "features": {
  "forecast": 1
  }
}
,
"forecast":{
"txt_forecast": {
"date":"8:41 PM CEST",
"forecastday": [
{
"period":0,
"icon":"cloudy",
"icon_url":"http://icons.wxug.com/i/c/k/cloudy.gif",
"title":"Tuesday",
"fcttext":"Cloudy. Lows overnight in the low 50s.",
"fcttext_metric":"Mostly cloudy. Low 10C.",
"pop":"10"
}
,
{
"period":1,
"icon":"nt_cloudy",
"icon_url":"http://icons.wxug.com/i/c/k/nt_cloudy.gif",
"title":"Tuesday Night",
"fcttext":"Cloudy. Low near 50F. Winds WNW at 5 to 10 mph.",
"fcttext_metric":"Cloudy. Low around 10C. Winds WNW at 10 to 15 km/h.",
"pop":"10"
}
,
{
"period":2,
"icon":"cloudy",
"icon_url":"http://icons.wxug.com/i/c/k/cloudy.gif",
"title":"Wednesday",
"fcttext":"Cloudy skies. High 66F. Winds WSW at 5 to 10 mph.",
"fcttext_metric":"Overcast. High 19C. Winds WSW at 10 to 15 km/h.",
"pop":"10"
}
,
{
"period":3,
"icon":"nt_partlycloudy",
"icon_url":"http://icons.wxug.com/i/c/k/nt_partlycloudy.gif",
"title":"Wednesday Night",
"fcttext":"Cloudy skies early, then partly cloudy after midnight. Low 54F. Winds light and variable.",
"fcttext_metric":"Partly cloudy skies. Low 12C. Winds light and variable.",
"pop":"0"
}
,
{
"period":4,
"icon":"partlycloudy",
"icon_url":"http://icons.wxug.com/i/c/k/partlycloudy.gif",
"title":"Thursday",
"fcttext":"Mostly cloudy skies early, then partly cloudy in the afternoon. High 73F. Winds SW at 5 to 10 mph.",
"fcttext_metric":"Considerable clouds early. Some decrease in clouds later in the day. High 23C. Winds SW at 10 to 15 km/h.",
"pop":"20"
}
,
{
"period":5,
"icon":"nt_partlycloudy",
"icon_url":"http://icons.wxug.com/i/c/k/nt_partlycloudy.gif",
"title":"Thursday Night",
"fcttext":"A few clouds. Low 57F. Winds light and variable.",
"fcttext_metric":"Partly cloudy. Low 14C. Winds light and variable.",
"pop":"10"
}
,
{
"period":6,
"icon":"partlycloudy",
"icon_url":"http://icons.wxug.com/i/c/k/partlycloudy.gif",
"title":"Friday",
"fcttext":"Intervals of clouds and sunshine. High 78F. Winds SSW at 5 to 10 mph.",
"fcttext_metric":"Cloudy early with partial sunshine expected late. High 26C. Winds SSW at 10 to 15 km/h.",
"pop":"10"
}
,
{
"period":7,
"icon":"nt_rain",
"icon_url":"http://icons.wxug.com/i/c/k/nt_rain.gif",
"title":"Friday Night",
"fcttext":"Showers early, becoming a steady rain late. Low around 60F. Winds SSW at 5 to 10 mph. Chance of rain 70%.",
"fcttext_metric":"Showers early, becoming a steady rain late. Low 16C. Winds SSW at 10 to 15 km/h. Chance of rain 70%.",
"pop":"70"
}
]
},
"simpleforecast": {
"forecastday": [
{"date":{
"epoch":"1435078800",
"pretty":"7:00 PM CEST on June 23, 2015",
"day":23,
"month":6,
"year":2015,
"yday":173,
"hour":19,
"min":"00",
"sec":0,
"isdst":"1",
"monthname":"June",
"monthname_short":"Jun",
"weekday_short":"Tue",
"weekday":"Tuesday",
"ampm":"PM",
"tz_short":"CEST",
"tz_long":"Europe/Berlin"
},
"period":1,
"high": {
"fahrenheit":"58",
"celsius":"14"
},
"low": {
"fahrenheit":"50",
"celsius":"10"
},
"conditions":"Overcast",
"icon":"cloudy",
"icon_url":"http://icons.wxug.com/i/c/k/cloudy.gif",
"skyicon":"",
"pop":10,
"qpf_allday": {
"in": 0.00,
"mm": 0
},
"qpf_day": {
"in": null,
"mm": null
},
"qpf_night": {
"in": 0.00,
"mm": 0
},
"snow_allday": {
"in": 0.0,
"cm": 0.0
},
"snow_day": {
"in": null,
"cm": null
},
"snow_night": {
"in": 0.0,
"cm": 0.0
},
"maxwind": {
"mph": 18,
"kph": 29,
"dir": "",
"degrees": 0
},
"avewind": {
"mph": 4,
"kph": 7,
"dir": "WNW",
"degrees": 298
},
"avehumidity": 87,
"maxhumidity": 0,
"minhumidity": 0
}
,
{"date":{
"epoch":"1435165200",
"pretty":"7:00 PM CEST on June 24, 2015",
"day":24,
"month":6,
"year":2015,
"yday":174,
"hour":19,
"min":"00",
"sec":0,
"isdst":"1",
"monthname":"June",
"monthname_short":"Jun",
"weekday_short":"Wed",
"weekday":"Wednesday",
"ampm":"PM",
"tz_short":"CEST",
"tz_long":"Europe/Berlin"
},
"period":2,
"high": {
"fahrenheit":"66",
"celsius":"19"
},
"low": {
"fahrenheit":"54",
"celsius":"12"
},
"conditions":"Overcast",
"icon":"cloudy",
"icon_url":"http://icons.wxug.com/i/c/k/cloudy.gif",
"skyicon":"",
"pop":10,
"qpf_allday": {
"in": 0.00,
"mm": 0
},
"qpf_day": {
"in": 0.00,
"mm": 0
},
"qpf_night": {
"in": 0.00,
"mm": 0
},
"snow_allday": {
"in": 0.0,
"cm": 0.0
},
"snow_day": {
"in": 0.0,
"cm": 0.0
},
"snow_night": {
"in": 0.0,
"cm": 0.0
},
"maxwind": {
"mph": 10,
"kph": 16,
"dir": "WSW",
"degrees": 247
},
"avewind": {
"mph": 6,
"kph": 10,
"dir": "WSW",
"degrees": 247
},
"avehumidity": 69,
"maxhumidity": 0,
"minhumidity": 0
}
,
{"date":{
"epoch":"1435251600",
"pretty":"7:00 PM CEST on June 25, 2015",
"day":25,
"month":6,
"year":2015,
"yday":175,
"hour":19,
"min":"00",
"sec":0,
"isdst":"1",
"monthname":"June",
"monthname_short":"Jun",
"weekday_short":"Thu",
"weekday":"Thursday",
"ampm":"PM",
"tz_short":"CEST",
"tz_long":"Europe/Berlin"
},
"period":3,
"high": {
"fahrenheit":"73",
"celsius":"23"
},
"low": {
"fahrenheit":"57",
"celsius":"14"
},
"conditions":"Partly Cloudy",
"icon":"partlycloudy",
"icon_url":"http://icons.wxug.com/i/c/k/partlycloudy.gif",
"skyicon":"",
"pop":20,
"qpf_allday": {
"in": 0.00,
"mm": 0
},
"qpf_day": {
"in": 0.00,
"mm": 0
},
"qpf_night": {
"in": 0.00,
"mm": 0
},
"snow_allday": {
"in": 0.0,
"cm": 0.0
},
"snow_day": {
"in": 0.0,
"cm": 0.0
},
"snow_night": {
"in": 0.0,
"cm": 0.0
},
"maxwind": {
"mph": 10,
"kph": 16,
"dir": "SW",
"degrees": 219
},
"avewind": {
"mph": 6,
"kph": 10,
"dir": "SW",
"degrees": 219
},
"avehumidity": 57,
"maxhumidity": 0,
"minhumidity": 0
}
,
{"date":{
"epoch":"1435338000",
"pretty":"7:00 PM CEST on June 26, 2015",
"day":26,
"month":6,
"year":2015,
"yday":176,
"hour":19,
"min":"00",
"sec":0,
"isdst":"1",
"monthname":"June",
"monthname_short":"Jun",
"weekday_short":"Fri",
"weekday":"Friday",
"ampm":"PM",
"tz_short":"CEST",
"tz_long":"Europe/Berlin"
},
"period":4,
"high": {
"fahrenheit":"78",
"celsius":"26"
},
"low": {
"fahrenheit":"60",
"celsius":"16"
},
"conditions":"Partly Cloudy",
"icon":"partlycloudy",
"icon_url":"http://icons.wxug.com/i/c/k/partlycloudy.gif",
"skyicon":"",
"pop":10,
"qpf_allday": {
"in": 0.18,
"mm": 5
},
"qpf_day": {
"in": 0.00,
"mm": 0
},
"qpf_night": {
"in": 0.18,
"mm": 5
},
"snow_allday": {
"in": 0.0,
"cm": 0.0
},
"snow_day": {
"in": 0.0,
"cm": 0.0
},
"snow_night": {
"in": 0.0,
"cm": 0.0
},
"maxwind": {
"mph": 10,
"kph": 16,
"dir": "SSW",
"degrees": 209
},
"avewind": {
"mph": 8,
"kph": 13,
"dir": "SSW",
"degrees": 209
},
"avehumidity": 57,
"maxhumidity": 0,
"minhumidity": 0
}
]
}
}
}


wird nun


HASH(0x3f52320)response_features_forecast: 1
HASH(0x3f52320)response_termsofService: http://www.wunderground.com/weather/api/d/terms.html
HASH(0x3f52320)response_version: 0.1
HASH(0x3f52320)forecast_simpleforecast_forecastday_qpf_allday_01_mm: 0
HASH(0x3f52320)forecast_simpleforecast_forecastday_qpf_allday_01_in: 0
HASH(0x3f52320)forecast_simpleforecast_forecastday_avewind_01_mph: 4
HASH(0x3f52320)forecast_simpleforecast_forecastday_avewind_01_dir: WSW
HASH(0x3f52320)forecast_simpleforecast_forecastday_avewind_01_degrees: 255
HASH(0x3f52320)forecast_simpleforecast_forecastday_avewind_01_kph: 6
ASH(0x3f52320)forecast_simpleforecast_forecastday_snow_night_01_in: 0
HASH(0x3f52320)forecast_simpleforecast_forecastday_snow_night_01_cm: 0
HASH(0x3f52320)forecast_simpleforecast_forecastday_maxwind_01_kph: 22
HASH(0x3f52320)forecast_simpleforecast_forecastday_maxwind_01_degrees: 0
HASH(0x3f52320)forecast_simpleforecast_forecastday_maxwind_01_dir:
HASH(0x3f52320)forecast_simpleforecast_forecastday_maxwind_01_mph: 14
HASH(0x3f52320)forecast_simpleforecast_forecastday_skyicon_01:
HASH(0x3f52320)forecast_simpleforecast_forecastday_high_01_fahrenheit: 68
HASH(0x3f52320)forecast_simpleforecast_forecastday_high_01_celsius: 20
HASH(0x3f52320)forecast_simpleforecast_forecastday_period_01: 1
HASH(0x3f52320)forecast_simpleforecast_forecastday_conditions_01: Partly Cloudy
HASH(0x3f52320)forecast_simpleforecast_forecastday_icon_url_01: http://icons.wxug.com/i/c/k/partlycloudy.gif
HASH(0x3f52320)forecast_simpleforecast_forecastday_maxhumidity_01: 0
HASH(0x3f52320)forecast_simpleforecast_forecastday_qpf_night_01_in: 0
HASH(0x3f52320)forecast_simpleforecast_forecastday_qpf_night_01_mm: 0
HASH(0x3f52320)forecast_simpleforecast_forecastday_date_01_ampm: PM
HASH(0x3f52320)forecast_simpleforecast_forecastday_date_01_tz_long: Europe/Berlin
usw.
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

justme1968

wo genau ist deine ausgabe her?

wenn du das ganze in fhem einbaust funktioniert vermutlich print nicht. nimm zum testen Log 3, ...

aber eigentlich kannst du auch gleich die readings erzeugen:
mach aus der print zeile direkt eine zeile mit readingsBulkUpdate. dazu musst du noch den $hash mit durchreichen und vor dem aufruf von toReadings muss das readingsBeginUpdate und danach das readingsEndUpdate.

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

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

bgewehr

Bin dran, aber $hash durchreichen brauche ich Hilfe...
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

bgewehr

das funktioniert nicht:


...
  my $decoded = decode_json( $response->content );
 
  readingsBeginUpdate($hash);
 
  toReadings($decoded, $hash);
 
  readingsEndUpdate($hash,1);
 
  DoTrigger($name, undef) if($init_done);
}

sub toReadings($;$$)                                                               
{                                                                               
  my ($ref,$hash,$prefix,$suffix) = @_;                                               
  $prefix = "" if( !$prefix );                                                 
  $suffix = "" if( !$suffix );                                                 
  $suffix = "_$suffix" if( $suffix );                                           
                                                                               
  if(  ref($ref) eq "ARRAY" ) {                                                 
    while( my ($key,$value) = each $ref) {                                     
      toReadings($value,$hash,$prefix,sprintf("%02i",$key+1));                       
    }                                                                           
  } elsif( ref($ref) eq "HASH" ) {                                             
    while( my ($key,$value) = each $ref) {                                     
      if( ref($value) ) {                                                       
        toReadings($value,$hash,$prefix.$key.$suffix."_");                           
      } else {
        print $prefix.$key.$suffix.": ".$value;                 
          #readingsBulkUpdate($hash, $prefix.$key.$suffix, $value);
      }                                                                         
    }                                                                           
  }                                                                             
}                                                         


Too many arguments for main::toReadings at ./FHEM/70_JSONREADINGS.pm line 123, near "))"
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

justme1968

sub toReadings($$;$$)
{
   my ($hash,$ref,$prefix,$suffix) = @_;
...
}


und überall beim aufruf von toReadings als erstes noch den $hash mit übergeben.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

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

herrmannj

poste mal was Du hast, bitte.

btw: der json muss nicht nach key/value aufgebaut sein. Ein (Namensloses) array ist ebenfalls gültig. Greift das mapping auf readings dann ?

vg
joerg

justme1968

das schaut doch gut aus.

wegen namenlosem hash oder array: das kann man über passende default werte und zähler lösen wenn es relevant ist. ansonsten ist der vorschlag auch nur ein erster ohne anspruch auf vollständigkeit. :)

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

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