JsonPath Transformation Service

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

JFKOGLER
Beiträge: 14
Registriert: 31. Jul 2020 09:51
Answers: 0

JsonPath Transformation Service

Beitrag von JFKOGLER »

Hallo zusammen,

hab mal wieder eine Frage,

diesmal gehts um json, mein VoltoPLus Regler liefert über eine api json-ähnliche werte

ich hab den output truncated, nur als beispiel, anfang und ende stimmen

Code: Alles auswählen

{"json_values":[{"id":"U1","value":"23446"},{"id":"U2","value":"23519"},{"id":"U3","value":"23438"}]}
jetzt wollte ich in einer rule mit die jeweiligen values herausholen

item:

Code: Alles auswählen

String VoltoPlus_JSON_String       "Data"    { http="<[http://192.168.178.45/api/v1/values:60000:REGEX((.*))]" }
rule:

Code: Alles auswählen

rule "Voltoplus JSON String changed"
	when
		Item VoltoPlus_JSON_String changed 
	then
		var String data = VoltoPlus_JSON_String.state.toString
                var String value = transform("JSONPATH", "$.id:U1.value", data)
                logInfo("Voltoplus", "value changed -->  U1 geändert " + value.toString)
                VoltoPlus_U1.postUpdate(value)
end
aber mein JSONPATH dürfte nicht passen, ich bekomm immer den gesamten string zurück (hab in doku gelesen das bei fehler der ganze string zurück gegeben wird)

mit jsonpath.com komm ich nicht weiter da der transformation service ja nicht genau jsonpath ist

kann mir jemand dabei helfen?

ich möchte nicht ~20 werte einzeln mit http auslesen + regex, das würde das system ja ziemlich belasten..

danke & lg

Benutzeravatar
peter-pan
Beiträge: 2768
Registriert: 28. Nov 2018 12:03
Answers: 30
Wohnort: Schwäbisch Gmünd

Re: JsonPath Transformation Service

Beitrag von peter-pan »

Hast du es schon mal mit dem HTTP-Binding versucht. Da kannst du den ganzen String einlesen und dann die einzelnen Labels extrahieren.

Der "truncated" String scheint aber ein richtiger JSON-String zu sein. Hast du auch mal versucht den String ohne "REGEX" einzulesen ?

Alternativ, wenn du einen JSON-String von einem Device in deinem Netzwerk auslesen willst, könnte das evtl. auch so aussehen:

Code: Alles auswählen

String esp_mini_02_Version "ESP8266_Mini-2 Version [%s]"  <sonoff_pow> (gSonoffs,gVer)  { http="<[http://192.168.178.abc/json:3600000:JSONPATH($.System.Build)]" }            
Hier lese ich aus einem mit ESP-Easy-geflashten Wemos die Version heraus.
Pi5/8GB(PiOS Lite 64-bit(bookworm)/SSD 120GB - OH4.3.5 openhabian

Benutzeravatar
udo1toni
Beiträge: 15265
Registriert: 11. Apr 2018 18:05
Answers: 245
Wohnort: Darmstadt

Re: JsonPath Transformation Service

Beitrag von udo1toni »

Was Du suchst, ist ein indirekter Verweis.

Schritt 1: Lege in der http.cfg einen http Cache an:

Code: Alles auswählen

voltoPlus.url=http://192.168.178.45/api/v1/values
voltoPlus.updateInterval=60000
Nun steht das JSON Objekt als Cache zur Verfügung. Weiterhin brauchst Du drei Items für die drei Werte.

Code: Alles auswählen

Number VoltoPlus_U1 "U1 [%.1f V]" {http="<[voltoPlus:60000:JSONPATH($.[?(@.id=="U1")].value)]"}
Number VoltoPlus_U2 "U2 [%.1f V]" {http="<[voltoPlus:60000:JSONPATH($.[?(@.id=="U2")].value)]"}
Number VoltoPlus_U3 "U3 [%.1f V]" {http="<[voltoPlus:60000:JSONPATH($.[?(@.id=="U3")].value)]"}
Der JSONPATH Ausdruck $.[?(@.id=="U1")].value sucht in den Objekten der Ebene 1 diejenigen Objekte heraus, bei denen der Parameter id dem Wert U1 entspricht und übergibt den Wert des Parameters value.

Dafür braucht es keinerlei Rule :)
openHAB4.3.5 stable in einem Debian-Container (bookworm) (Proxmox 8.4.1, LXC), mit openHABian eingerichtet

JFKOGLER
Beiträge: 14
Registriert: 31. Jul 2020 09:51
Answers: 0

Re: JsonPath Transformation Service

Beitrag von JFKOGLER »

danke udo, habs hinbekommen

VS hat sich nur mokiert wegen escape zeichen

U1 expecting }.....

Code: Alles auswählen

http="<[voltoPlus:10000:JSONPATH(.[?(@.id==\"U1\")].value)]"
damits läufts..

JFKOGLER
Beiträge: 14
Registriert: 31. Jul 2020 09:51
Answers: 0

Re: JsonPath Transformation Service

Beitrag von JFKOGLER »

hab noch eine frage: gibts eine einfache möglichkeit das item Number VoltoPlus_U1 zu formatieren?

value ist zb: 23315 --> sollte dann 233,15 ergeben

gibs einen operator der das inline erledigt? oder muss ich über transform:js das bearbeiten?

lg

Benutzeravatar
udo1toni
Beiträge: 15265
Registriert: 11. Apr 2018 18:05
Answers: 245
Wohnort: Darmstadt

Re: JsonPath Transformation Service

Beitrag von udo1toni »

Ah, genau... Du hättest auch ' als Begrenzung des Strings verwenden können, also

Code: Alles auswählen

http="<[voltoPlus:10000:JSONPATH(.[?(@.id=='U1')].value)]"
, aber mit Escaping geht es natürlich genausogut.
Das Verschieben des Kommas ist allerdings leider nicht so einfach möglich, letztlich musst Du dazu den JS Transformation Service verwenden und ein Javascript nutzen.
Ungetestet, eine Datei pro Wert, exemplarisch hier für U1 (Dateiname voltusu1.js):

Code: Alles auswählen

(function(dataString) {
    var data = JSON.parse(dataString);
    var value = 'UNDEF';
    for (var i = 0; i < data.length; i++) {
        if (data[i].id == 'U1') {
            value = data[i].value;
            break;
        }
    }
    if (value != 'UNDEF') {
        value = value / 100;
    }
    return value;
})(input)
Das baust Du dann im Item so ein:

Code: Alles auswählen

Number VoltoPlus_U1 "U1 [%.1f V]" {http="<[voltoPlus:60000:JS(voltusu1.js)]"}
Es kann sein, dass da noch ein Fehler drin ist :) aber das Prinzip sollte so passen.
openHAB4.3.5 stable in einem Debian-Container (bookworm) (Proxmox 8.4.1, LXC), mit openHABian eingerichtet

JFKOGLER
Beiträge: 14
Registriert: 31. Jul 2020 09:51
Answers: 0

Re: JsonPath Transformation Service

Beitrag von JFKOGLER »

habs mir gedacht

kann ich JS

Code: Alles auswählen

JS(voltusu1.js)
mit JSONPATH

Code: Alles auswählen

Number VoltoPlus_U1 "U1 [%.1f V]" {http="<[voltoPlus:60000:JSONPATH($.[?(@.id=="U1")].value)]"}
bzw

Code: Alles auswählen

http="<[voltoPlus:10000:JSONPATH(.[?(@.id=='U1')].value)]"
in einer Zeile kombinieren oder muss ich über helper-items?

ich habs mal so getestet

Code: Alles auswählen

Number:Power VoltoPlus_U2 "U2 [JS(divide100.js):%s V]" <energy> (BM_Working_SolarRegulator) { http="<[voltoPlus:10000:JSONPATH(.[?(@.id==\"U2\")].value)]" }
nur zeigt mir basic ui dann das V (Volt) nicht an, nur

233.15

hmmm..

Benutzeravatar
udo1toni
Beiträge: 15265
Registriert: 11. Apr 2018 18:05
Answers: 245
Wohnort: Darmstadt

Re: JsonPath Transformation Service

Beitrag von udo1toni »

Ja, Du kannst natürlich auch die JS Transformation im Label nutzen, musst Dir aber darüber im Klaren sein, dass der Wert im Item weiterhin um den Faktor 100 zu groß ist, die Transformation im Labelwirkt sich ausschließlich auf die Darstellung aus.
Das http Binding kann nicht mit UoM umgehen, Du musst das Item als Number definieren, Number:Power ist nicht erlaubt. Außerdem ist Volt nicht Number:Power sondern Number:ElectricPotential (siehe https://www.openhab.org/docs/concepts/u ... t-of-units), was dann auch direkt erklärt, warum die Einheit V gar nicht zur Verfügung seht.

Aber wie gesagt, UoM ist hier verboten. Du könntest lediglich die einheitenlose Zahl per Rule in ein UoM Item schreiben, das ist aber nur sinnvoll, wenn Du anschließend UoM auch nutzt.
openHAB4.3.5 stable in einem Debian-Container (bookworm) (Proxmox 8.4.1, LXC), mit openHABian eingerichtet

JFKOGLER
Beiträge: 14
Registriert: 31. Jul 2020 09:51
Answers: 0

Re: JsonPath Transformation Service

Beitrag von JFKOGLER »

ok soweit klar,

aber wie kombiniere ich dann JS UND JSONPATH im http-binding?

geht das überhaupt?

irgendwie find ich nur beispiele entweder / oder..

JFKOGLER
Beiträge: 14
Registriert: 31. Jul 2020 09:51
Answers: 0

Re: JsonPath Transformation Service

Beitrag von JFKOGLER »

ah jetzt hab ichs verstanden, sry ned genau gelesen

json im js script, werden halt dann ein paar scripte für verschiedene id's

ich probiers später aus

lg

Antworten