JSON Datensatz in FHEM zusammenstellen und in Datei schreiben?

Begonnen von TubeHead, 03 Juli 2026, 15:56:08

Vorheriges Thema - Nächstes Thema

TubeHead

Ach so! Du meintest im Link selber? Ich bin davon ausgegangen, das Du meine FHEM-Instanz meinst  :))

Und ja: Wenn ich das in Deine Instanz packe, erhalte ich selbiges Ergebnis

TomLee

Weil die Mühe die ich mir in der Demoinstallation gemacht habe morgen weg sein wird, halt ich meinen weiteren, erratenen Ansatz hier mal fest:

defmod Tele2JSON at +*00:01:00 {DevToJson("/opt/fhem/fhemdevstates.json","TMP:state","HUM:state","wetter:wind","wetter:pressure")}
sub DevToJson {
  my ($file, @specs) = @_;                        # 1. Argument = Dateiname, alle weiteren = "Device:Reading"-Angaben
  my (@out, %idx);                                # @out = spätere JSON-Liste, %idx = Merkhilfe "Device -> zugehörige Hashref"

  for (@specs) {                                  # über jede Spec-Angabe iterieren, aktueller Wert steht in $_
    my ($d,$r) = split(':',$_,2);                 # Spec am ersten Doppelpunkt trennen: $d = Device, $r = Reading (2 = max. 2 Teile)

    push @out, ($idx{$d} = {device=>$d})          # neue Hashref anlegen, in %idx merken UND (da Zuweisung die Ref zurückgibt) an @out anhängen
      if !$idx{$d};                               #   ... aber nur, wenn dieses Device noch kein Objekt hat

    $idx{$d}{$r} = ReadingsVal($d,$r,'error');         # Reading auslesen (Default: error) und im Device-Objekt unter dem Reading-Namen ablegen
  }

  my $json = toJSON(\@out);                       # Array-Referenz von FHEM serialisieren lassen -> JSON-String (quotet alles als String)
  $json =~ s/:"(-?\d+(?:\.\d+)?)"/:$1/g;          # nachträglich die Quotes um reine Zahlenwerte entfernen; führender ":" trifft nur Werte, nie Schlüssel

  FileWrite({FileName=>$file}, $json);            # JSON-String in die Datei schreiben (überschreibt den bisherigen Inhalt)
}

TubeHead

Ok, vielen Dank für Deine Mühen.
Da ich von Perl keinen blassen Schimmer habe, kann ich dass auch nicht zu einem Ende bringen.
Ich werde es jetzt mal auf einem anderen Weg versuchen und vorher in einem Dummy alles zusammenstellen, was ich für die JSON benötige und dann das ursprüngliche Skript versuchen...
Scheint also, wie anfangs erwähnt, wohl doch nicht so trivial zu sein...

TomLee

Das letzte Beispiel ist so gebaut, das man beliebig viele Devicename:Readings in der Funktion angeben kann.
Die Funktion selbst müsstest einfach nur copy+paste in der myUtils ergänzen. Keine Änderung und kein Perlwissen nötig.

Die Frage ob das Ergebnis passt oder nicht müsstest halt mal beantworten oder erklären wie deiner Anforderung nach der JSON genau aussehen soll.

TubeHead

Also dann funktioniert es nicht wie erwartet. Ich hatte das genau so kopiert, zur Sicherheit FHEM neu gestartet und in der GUI manuell "execNow" ausgelöst.
Die Datei wird geschrieben, aber außer einem eckigen Klammernpaar ist sie weiterhin leer...
Ich hatte sogar genau die defmod genommen, welche Du auch genutzt hast...

TomLee

[{"device":"TMP","state":"29"},{"device":"HUM","state":"64"},{"device":"wetter","pressure":"1024","wind":"3.9"}]
So würde passen oder nicht?

TomLee

ZitatIch hatte sogar genau die defmod genommen, welche Du auch genutzt hast...

Kann nicht sein.
Ich hab dir zum nachvollziehen alles nochmal in der Demoinstallation im Raum TubeHead "gebaut":

https://demo-fhem.cooltux.net/fhem?room=TubeHead

Wenn Du oben in der Befehlszeile {qx(cat /opt/fhem/fhemdevstates.json)} eingibst dann kommt dieses JSON Array zurück: [{"device":"TMP","state":39},{"device":"HUM","state":64},{"device":"wetter","pressure":1024,"wind":3.9}]

TubeHead

ZitatKann nicht sein.
... aber naja doch ;o) Wir "meinen" nur was anderes...

+*00:01:00 {DevToJson("/opt/fhem/fhemdevstates.json","TMP:state","HUM:state","wetter:wind","wetter:pressure")}Steht jetzt identisch zu Deiner Testinstallation auch so bei mir. DEF ist also bei Dir und mir identisch.
Das was in 99_myUtils.pm als Code steht, ist ebenfalls per C&P 1:1 identisch mit dem Code, welcher von Dir in Beitrag #16 geschrieben wurde.

{qx(cat /opt/fhem/fhemdevstates.json)}Das funktioniert bei Deiner Testinstallation, aber nicht bei mir. Ich nehme an, das ist OS-Abhängig?

Wie dem auch sei: Das Endergebnis, also der Inhalt der sehr wohl auf die Platte geschriebenen telemetry.json ist hals ein leeres "[]". Warum das bei Deiner Testinstallation funktioniert und bei mir nicht, ist mir ein Rätsel... Fehlt da bei mir irgend ein Paket unter Debian, auf welches Perl hier angewiesen ist?

TubeHead

AUA! Warte mal... ICH DOOF  :o

Ich hatte die 99_myUtils.pm als 99:myUtils_Kopie.pm weggesichert. Offensichtlich nimmt FHEM die aber dennoch als gültige Datei; habe ich absolut nicht mit gerechnet  ::)

Da habe ich jetzt mal ein .bak von gemacht und siehe da: NU GEIT DAT!!!

TubeHead

So... Die Datei wird auf jeden Fall geschrieben. Problem bleibt nur noch das (für mich) unbrauchbare Format.

Rauskommen soll da sowas wie hier:

{"TMP":25,"HUM":46,"pressure":1018,"wind":18}
Also immer Bezeichner:Wert



TomLee

Kannst Du mal erklären/zeigen wofür der Json gebraucht wird?

TubeHead

... zur Bereitstellung von Telemetriedaten  für MeshCOM (1) vie WebDesk-Server (2) ...

1: https://icssw.org

2: https://github.com/DH1FR/MeshcomWebDesk

TomLee

#27
Die Funktion in der Demoinstallation spuckt jetzt so einen Json aus wie das Ergebnis hier.

Es gibt jetzt einen dritten (edit: optionalen) Teil in der Spec eines Parameters, um den Schlüssel im JSON frei zu benennen.

TubeHead

Cool! Probiere ich aus, sobald ich für meine Holde und mich Futter fertig hab', sonst bekomme ich was an die Ohren  :o  8)

TubeHead

Perfekt!
Ich musste allerdings den Timestamp im Code auskommentieren. Der generiert eine Fehlermeldung. Ohne den klappt es aber wie RogerRabbit!

Vielen lieben Dank!