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
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