jsonread
Das vorliegende Plugin ist in der Lage aus einer Datei oder von einer URL JSON Daten zu lesen und anhand einer Abfrageanweisung einen Datenpunkt an ein Item zu übergeben.
Anforderungen
Für die Auswertung des JSON Datensatzes wird der flexible JSON Prozessor JQ verwendet.
Jede Webseite, die JSON formatierte Daten liefern kann oder jede Datei die JSON formatierte Daten enthält, kann als Datenquelle für das Plugin verwendet werden.
Konfiguration
Wichtig
Detaillierte Informationen zur Konfiguration des Plugins sind unter Plugin ‚jsonread‘ Konfiguration zu finden.
plugin.yaml
Es können beliebig viele Instanzen des Plugins erstellt werden. Für jede Datenquelle muß eine Instanz konfiguriert werden.
URL
Der Ursprung der Daten. Aktuell werden http://
, https://
und file://
Schemen unterstützt.
Bemerkung
Absolute Pfadangabe für Dateien wie in file:///absoluter/pfad/hier
enthalten 3 Schrägstriche
relative Pfadangabe für Dateien wie in file://relativer/pfad/hier
enthalten 2 Schrägstriche
Beispiele verschiedener Datenquellen
Die folgenden Beispiele nutzen openweathermap und den Beispiel API Schlüssel. Der Schlüssel sollte wirklich nur für Testzwecke verwendet werden.
http Quelle
jsonread:
plugin_name: jsonread
url: https://samples.openweathermap.org/data/2.5/weather?q=London,uk&appid=b6907d289e10d714a6e88b30761fae22
cycle: 30
Dateiquelle
jsonread:
plugin_name: jsonread
url: file:///path/to/data.json
cycle: 30
Mehrere Instanzen
jsonreadlon:
plugin_name: jsonread
url: https://samples.openweathermap.org/data/2.5/weather?q=London,uk&appid=b6907d289e10d714a6e88b30761fae22
instance: london
jsonreadcair:
plugin_name: jsonread
url: https://samples.openweathermap.org/data/2.5/weather?id=2172797&appid=b6907d289e10d714a6e88b30761fae22
instance: cairns
items.yaml
Beispiel Klimaabfrage
Die Abfrage https://samples.openweathermap.org/data/2.5/weather?q=London,uk&appid=b6907d289e10d714a6e88b30761fae22
ergibt ein Ergebnis in etwa wie folgt:
{
"coord": {
"lon": -0.13,
"lat": 51.51
},
"weather": [
{
"id": 300,
"main": "Drizzle",
"description": "light intensity drizzle",
"icon": "09d"
}
],
"base": "stations",
"main": {
"temp": 280.32,
"pressure": 1012,
"humidity": 81,
"temp_min": 279.15,
"temp_max": 281.15
},
"visibility": 10000,
"wind": {
"speed": 4.1,
"deg": 80
},
"clouds": {
"all": 90
},
"dt": 1485789600,
"sys": {
"type": 1,
"id": 5091,
"message": 0.0103,
"country": "GB",
"sunrise": 1485762037,
"sunset": 1485794875
},
"id": 2643743,
"name": "London",
"cod": 200
}
Mit der Definition
temperature:
type: num
jsonread_filter: .main.temp
windspeed:
type: num
jsonread_filter: .wind.speed
werden den entsprechenden Items die Temperatur und die Windgeschwindigkeit zugewiesen.
Wenn mehrere Instanzen für das Plugin definiert werden,
so muss das jsonread_filter
Attribut
erweitert werden mit @
und dem Instanznamen
temperature:
london:
type: num
jsonread_filter@london: .main.temp
cairns:
type: num
jsonread_filter@cairns: .main.temp
Der Attributwert für jsonread_filter
wird direkt an jq weitergegeben.
Auf diese Art und Weise ist es möglich
recht komplexe Filter zu erstellen und für die Itembefüllung zu verwenden.
Dabei muss darauf geachtet werden, dass nur ein einzelner Wert
zurückgegeben werden darf.
Für komplexe JSON Strukturen kann es recht kompliziert sein,
entsprechende Filter zu definieren, daher
könnte es einfacher sein, diese Filter auf der Kommandozeile zu entwickeln:
curl https://json.server.org/data.json | jq '.object'
Es lohnt ein Blick ins Tutorial für jq um für die Verwendung der Filter einen Eindruck zu bekommen.
Beispiel Batteriedaten
In der etc/plugin.yaml
wird das Plugin definiert als:
myreserve:
plugin_name: jsonread
url: file:///tmp/BMSData.shtml
instance: myreserve
cycle: 10
Die Datei /tmp/BMSData.shtml
wird dabei vom Prozess
receiveBLE.py
auf einem Raspi erzeugt (SolarWatt):
{
"FData": {
"IPV": 5.17,
"VBat": 170.1,
"VPV": 418.5,
"PGrid": 18,
"IBat": -9.91
},
"SData": {
"ACS": {
"U_L2": 239,
"f": 49.98
},
"SoC": 10
}
}
Um die Spannung, den aktuellen Ladestrom und die Ladeleistung zu erhalten,
werden folgende Items für
die Instanz myreserve
definiert:
battery:
u:
type: num
jsonread_filter@myreserve: .FData.VBat
i:
type: num
jsonread_filter@myreserve: .FData.IBat
power:
remark: etwas einfache Mathematik kann verwendet werden:
type: num
jsonread_filter@myreserve: (.FData.VBat * .FData.IBat * -1)
Beispiel Energiemanager
In der etc/plugin.yaml
wird das Plugin definiert als:
swem:
plugin_name: jsonread
url: http://192.168.x.y/rest/kiwigrid/wizard/devices
instance: swem
cycle: 30
Die Abfrage der URL liefert ein ziemliche großes JSON Datenpaket mit mehr als 4500 Zeilen. Ein Auszug ist im folgenden dargestellt:
{
"result": {
"items": [
{
"guid": "urn:your-inverter-guid",
"tagValues": {
"PowerACOut": {
"value": 2419,
"tagName": "PowerACOut"
}
}
}
]
}
Um die aktuelle Inverter AC Ausgangsleistung zu erhalten, wird folgendes Item mit einem komplexen Filter definiert:
inverter:
type: num
jsonread_filter@swem: (.result.items[] | select(.guid == "urn:your-inverter-guid").tagValues.PowerACOut.value)
Auswählen des Arrays .result.items
,
dann auswählen des Zweiges, bei dem das Element guid
mit dem eigenen
your-inverter-guid
übereinstimmt, und im Zweig weitergehen
und den Wert von .tagValues.PowerACOut.value
abfragen und ins Item schreiben.
Das jsonread_filter
Attribut kann mit Hilfe des
Blockstils für mehrzeilige Strings
eben auf mehrere Zeilen aufgeteilt werden.
So ist folgende komplexe Berechnung über einen Filter möglich:
grid:
type: num
jsonread_filter@swem: >
(.result.items[] |
select(.deviceModel[].deviceClass == "com.kiwigrid.devices.solarwatt.MyReservePowermeter").tagValues.PowerOut.value) -
(.result.items[] |
select(.deviceModel[].deviceClass == "com.kiwigrid.devices.solarwatt.MyReservePowermeter").tagValues.PowerIn.value)
Web Interface
Im Webinterface wird das Ergebnis der letzten Abfrage der Quelle
im Original sowie als vereinfachte .jq Abfragesyntax dargestellt.
Außerdem werden die Items mit dem entsprechenden
jsonread_filter
Attribut und dem aktuell zugewiesenen Wert angezeigt.