Seite 1 von 2

JsonPath Transformation Service

Verfasst: 2. Sep 2020 23:07
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

Re: JsonPath Transformation Service

Verfasst: 2. Sep 2020 23:33
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.

Re: JsonPath Transformation Service

Verfasst: 3. Sep 2020 01:28
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 :)

Re: JsonPath Transformation Service

Verfasst: 3. Sep 2020 11:32
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..

Re: JsonPath Transformation Service

Verfasst: 3. Sep 2020 12:59
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

Re: JsonPath Transformation Service

Verfasst: 3. Sep 2020 14:10
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.

Re: JsonPath Transformation Service

Verfasst: 3. Sep 2020 14:59
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..

Re: JsonPath Transformation Service

Verfasst: 3. Sep 2020 15:08
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.

Re: JsonPath Transformation Service

Verfasst: 3. Sep 2020 15:54
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..

Re: JsonPath Transformation Service

Verfasst: 3. Sep 2020 16:07
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