PRTG JSON-Sensor

Neben XML hat sich das JSON-Format als strukturierte Datenspeicherung etabliert. Da mittlerweile auch diverse IoT-Geräte per REST-API über http abfragbar sind und dabei eine JSON-Antwort liefern, konnte ich Am Beispiel eines Kostal 15 meine ersten Erfahrungen mit der JSON-Verarbeitung von PRTG machen.

REST oder JSON ?

Wenn Sie unter PRTG einen neuen Sensor für JSON addieren, dann liefert ihnen der Assistent gleich mehrere Sensoren. Das kann schon verwirrend sein aber lässt sich einfach erklären. Die meisten Sensoren, die eine XML-Antwort akzeptieren können auch mit einer JSON-Antwort umgehen.

Für mich interessant ist aber der rot umrandete "REST Custom BETA"-Sensor, da die anderen schon ein für PRTG geeignetes Format liefern oder nur einen Wert extrahieren. Der neue Sensor aber kann mit einem Template arbeiten, bei dem sie über JSONPATH-Statements aus einer JSON-Datei mehrere Werte einsammeln und dann in eine anderen JSON-Ausgabe umwandeln können. Zudem kann ich bei jedem Kanal auch weitere Einstellungen direkt mitgeben, z.B. die Einheit, Float/Integer oder Absolut/Difference.

Daten per PowerShell

Zuerst habe ich mal geschaut, was die Quelle so liefert. Hier war es ein Kostal Pico 15-Wechselrichter, von dem ich eine Auswahl an Werten auslesen wollte:

(Invoke-Webrequest `
   -URI "http://192.168.8.1/api/dxs.json?dxsEntries=251658753&dxsEntries=33555203&dxsEntries=33555459&dxsEntries=33555715&dxsEntries=251658496" `
   -UseBasicParsing).content

{"dxsEntries":[{"dxsId":251658753,"value":38.109718},{"dxsId":251658496,"value":13}],"session":{"sessionId":0,"roleId":0},"status":{"code":0}}

Im Content steht die JSON-Struktur, die ich nun mal auffächere, damit sie die Query-Strings für PRTG besser sehen:

{"dxsEntries":
   [
      {"dxsId":251658753,"value":38.109718},
      {"dxsId":33555203,"value":0.000000},
      {"dxsId":33555459,"value":0.000000},
      {"dxsId":33555715,"value":0.000000},
      {"dxsId":251658496,"value":13}
   ],
   "session":{"sessionId":0,"roleId":0},
   "status":{"code":0}
}

Die Daten sind so schon mal ganz gut zu verwenden, auch wenn die Auflistung eines Array mit zwei Werten eher ungewöhnlich ist. Mir hätte folgendes Format besser gefallen:

{
   "251658753":38.109718,
   "33555203":0.000000,
   "33555459":0.000000,
   "33555715":0.000000,
   "251658496":13,
   "session":{"sessionId":0,"roleId":0},
   "status":{"code":0}
}

Beim Array habe ich noch keinen Weg gefunden, das Feld anhand des Namens zu selektieren und gehe mal davon aus, dass die Rückgabe immer in der gleichen Reihenfolge ist.

Teamplate erstellen

Damit der REST-Sensor arbeiten kann muss ich bei der Einrichtung aber ein Template erstellen, damit PRTG die Quelle parsen kann. Dazu bedient sich PRTG einer Text-Datei, die im Ordner "\Custom Sensors\rest" im Programmverzeichnis von PRTG abgelegt wird und die Endung ".Template" haben muss.

Wenn Sie mit JSONPatch nicht täglich arbeiten, dann ist ein Parser zum Testen und Spielen eine gute Hilfe. Eine große Hilfe beim Erstellen der Templates ist z.B. https://jsonpath.com/.

Links gebe ich die JSON-Antwort des Wechselrichters ein und rechts kann ich mit den Pfaden hantieren, bis das Ergebnis stimmt. Es gibt vermutlich auch noch eine Syntax, mit der ich auf den Wert von dxsId filtern kann, aber ich nutze einfach mal die Aufzählung und erstelle damit folgendes Template:

{
   "prtg": {
      "result": [
         {
            "Channel": "Gesamteinspeisung",
            "CustomUnit": "kWh",
            "Float": 1,
            "Mode": "Difference",
            "Value": $.dxsEntries[0:1].value
         },
         {
           "Channel": "String1",
            "CustomUnit": "Wh",
            "Float": 1,
            "Mode": "Absolute",
            "Value": $.dxsEntries[1:2].value
         },
         {
            "Channel": "String2",
            "CustomUnit": "Wh",
            "Float": 1,
            "Mode": "Absolute",
            "Value": $.dxsEntries[2:3].value
         },
         {
            "Channel": "String3",
            "CustomUnit": "Wh",
            "Float": 1,
            "Mode": "Absolute",
            "Value": $.dxsEntries[3:4].value
         },
         {
            "Channel": "Betriebsstunden",
            "CustomUnit": "h",
            "Float": 0,
            "Mode": "Absolute",
            "Value": $.dxsEntries[4:5].value
         },
      ]
   }
}

In dem Verzeichnis finden Sie schon einige Templates.

Die Templates finden Sie später auch bei der Anlage des Sensors.

Ein bisschen verrät Paessler damit natürlich wohl auch, welche Systeme Sie damit abfragen. Ich bin aber sicher, dass hier weitere Templates dazu kommen oder von der Community beigesteuert werden.

Sensor einrichten

Nachdem das Template auf dem PRTG-Probe-Server hinterlegt wurde. kann ich einen neuen Sensor from Type "Rest Custom Beta" anlegen:

Die IP-Adresse des Wechselrichters wird von dem übergeordneten Device bezogen, so dass ich nur noch den REST-Query und das Template anzugeben habe.

Im Feld "Rest-Query" gebe ich dann einfach nur den Pfad ein, denn der Server wird vom Device vererbt:

/api/dxs.json?dxsEntries=251658753&dxsEntries=33555203&dxsEntries=33555459&dxsEntries=33555715&dxsEntries=251658496

Werte kontrollieren

Und nach dem nächsten Aufruf sehen wir die ersten Werte:

Leider habe ich noch nicht genau heraus gefunden, warum die Werte alle eine "0" angehängt bekommen. Bitte nicht in der WebUI umbenennen, da dann die Kanäle wieder neu angelegt werden.

Da man das Feld "Betriebsstunden" nicht sinnvoll alle 5 Minuten abfragen kann, habe ich es auf "Absolute" gestellt. Also primären Kanal habe ich per Konfiguration dann von "Response Time" auf "Gesamteinspeisung umgestellt.

Entsprechend könnte ich pro Kostal nun ein Device mit zwei Sensoren vom Typ "HTTP XML/REST Value Sensor" anlegen. Allerdings gibt es hier das Problem, dass man nicht die Funktion "Difference" angeben kann. PRT liest den Wert oder die Anzahl der Knoten aus und übernimmt diesen. Als Ergebnis hätte ich einfach eine aufsteigende Line aber nie die zwischen den Messungen eingespeiste Energie.

Weitere Links