Making-of: Grafana-Dashboard für die Photovoltaik-Anlage

Seit einiger Zeit nenne ich eine Photovoltaik- oder auch PV-Anlage mein Eigen. In diesem Artikel möchte ich ein wenig über die Entwicklung eines Grafana-Dashboards für eben diese Photovoltaik-Anlage berichten, es handelt sich somit um eine Art “Making-of”. Wer eher an harten Fakten und Anleitungen zum Ausprobieren interessiert ist, findet diese einerseits bei GitHub, andererseits in deutscher Sprache zusammengestellt auf der Seite Grafana Photovoltaik Dashboard.

Warum noch ein Dashboard?

Der Wechselrichter, ein Kostal Plenticore Plus 10, stellt dabei eine Admin- bzw. Anlagenbetreiber-UI zur Verfügung, die einerseits eine Live-Ansicht der aktuellen Daten (wie Stromverbrauch, Stromerzeugung, Einspeisung etc.) bietet, andererseits Statistiken für den jeweiligen Tag, den aktuellen Monat, das Jahr, sowie insgesamt über alle Zeiträume hinweg anzeigt. Zusätzlich existiert ein Web-Portal von Kostal, in dem sich die wichtigsten Angaben im Zeitverlauf betrachten lassen. Dabei werden die Daten alle zehn Minuten an das Portal übertragen, was dazu führt, dass die Auflösung recht grob ist und kleinere Zeiträume überhaupt nicht betrachtet werden können bzw. unberücksichtigt bleiben. Da mir dies nicht genug war, habe ich nach einem Weg gesucht, der es mir erlaubte, die vom Wechselrichter bereitgestellten Werte letztlich in ein Grafana-Dashboard einfließen zu lassen. Die Idee lag auch daher nahe, da Grafana in Zusammenarbeit mit Prometheus bereits dafür genutzt wird, um diverse Statistiken von Servern bzw. diversen Diensten übersichtlich darzustellen.

Kostal-Wechselrichter: Tools und APIs

Also begab ich mich auf die Suche nach entsprechenden Tools, aber fand tatsächlich erstaunlich wenig. Mit dem FHEM-Home-Server wollte ich keine nähere Beziehung eingehen, auch die Einbindung in OpenHAB stieß bei mir auf eher wenig Begeisterung. Der erste Schritt bestand somit, herauszufinden, ob und wenn ja, welche Möglichkeiten es gab, an die erwünschten Daten überhaupt heran zu kommen. Mit Modbus wollte ich mich irgendwie auch nicht herum schlagen, aber nach kurzer Suche fanden sich Hinweise, dass der Kostal Wechselrichter auch eine – zwar inoffizielle – REST-API besitzt, die dank Swagger UI auch eine Art Dokumentation besitzt. Deren URL findet sich unter der IP des Wechselrichters im Pfad “/api/v1/“, neben dem Auslesen von Werten können dabei auch diverse Einstellungen verändert werden. Nun gab es mit “pykoplenti” eine Python-Library für die Kostal Plenticore Wechselrichter, ein weiteres Projekt, ebenfalls in Python geschrieben, ist “kostal-RESTAPI“. Nach kurzem Ausprobieren ließ sich feststellen, dass diese Projekte auch prima funktionierten, nur hätte ich dann wieder von meiner aktuell bevorzugten Programmiersprache, Go, abrücken müssen.

Das Schöne an Go ist, dass sich damit wunderschöne, kleine Binaries erzeugen lassen, die beim Einsatz von Docker zu ebenfalls wunderschönen, kleinen Images führen. Somit war schnell der Entschluss gefasst, eine Client-Library für die REST-API des Wechselrichters in Go zu implementieren, was auch dazu diente, um nach den ersten Gehversuchen, die inzwischen auch schon eine Weile zurück lagen, die Sprache wieder etwas besser kennenzulernen.

Erst die Library, dann das Vergnügen

Dabei möchte ich mich insbesondere bei den Autoren von kostal-RESTAPI und der Anbindung des Inverters bei OpenHAB bedanken, denn dank dieser Quelltexte konnte ich die bis auf den Swagger-Output undokumentierte dreischrittige Authentifizierung in Go nachimplementieren, ohne die sich fast keine Daten auslesen lassen, abgesehen von ein paar Versionsinformationen der API selbst. Das Ergebnis nannte ich golrackpi – Go (Golang) Library Rest Api Client (for) Kostal Plenticore Inverters (with CLI). Neben der eigentlichen Library ist darin eine CLI enthalten, die zur Anzeige von “settings“, “processdata“, “events” und “modules” dient, was angesichts der hervorragenden Cobra-CLI-Library schnell hinzugefügt werden konnte bzw. letztlich daraus entstand, dass ich die Daten irgendwie zwecks Test darstellen wollte und sich somit der Aufwand, dabei gleich eine vollwertige CLI zu bauen, in sehr engen Grenzen hielt.

Dabei muss ich erwähnen, dass ich mich absichtlich auf das Auslesen der Daten konzentriert habe. Zwar ließen sich auf dieselbe Weise auch diverse Parameter des Wechselrichters ändern, doch möchte ich diese Aufgabe lieber den Experten mit erweiterten elektrotechnischen Kenntnissen überlassen. Einer möglichen Ergänzung steht natürlich nichts im Wege, wer also Lust und Zeit hat, sich dieser Aufgabe anzunehmen, kann sich jederzeit gerne daran beteiligen.

Vom Wechselrichter zu Prometheus, zweiter Akt

Nun konnten die Daten aus dem Wechselrichter also ausgelesen werden und mussten nur noch irgendwie zu Prometheus gelangen. Um das Pferd mal von hinten aufzuzäumen – mit der Go-Client-Library für Prometheus hatte ich bereits in einem früheren Projekt Erfahrungen gesammelt. Letztlich muss dafür nur der Code für einen Web-Server geschrieben werden, wofür beispielsweise die Go-Standard-Libraries verwendet werden können. Jedoch nutzte ich hier auch wieder das HTTP-Web-Framework Gin, abermals aufgrund guter Erfahrungen – und weil das Codefragment dafür mehr oder minder bereits zur Verfügung stand. Somit mussten die Daten letztlich aus irgendeiner Quelle ausgelesen und so aufbereitet werden, dass sie in einem für Prometheus bzw. der Prometheus Client-Library passenden Format inkl. sinnvoller Beschreibungen zur Verfügung stehen. Für die Konvertierung der Datenstrukturen unternahm ich hier einen ersten Ausflug in das Reflection-Paket von Go, was sich durchaus gelohnt und in Konsequenz einigen Code erspart hat.

Das Ergebnis findet sich in einem Tool, das nun invaps heißt, was für “inverter value Prometheus service” steht. Der damit entstandene Service stellt die Processdata-Werte des Wechselrichters unter dem Pfad “/metrics/” zur Abfrage von Prometheus zur Verfügung. Doch woher kommen die Daten? Im Gegensatz zur sicherlich auf den ersten Blick intuitiven und auch auf den zweiten Blick leicht zu realisierenden Lösung der direkten Nutzung der golrackpi-Library habe ich mich hier für einen Zwischenschritt, oder vielmehr das Zwischenspeichern in einer Datenbank entschieden. Dies geschah aus mehreren Gründen.

Einerseits ist mit zwei Tools – eines zuständig für das Auslesen der Daten aus dem Wechselrichter, das andere zuständig für die Bereitstellung für Prometheus, eine Trennung der Aufgabenbereiche vorhanden, getreu dem Motto, ein Tool für eine Aufgabe. Zudem lassen sich bei der Nutzung einer Datenbank relativ leicht Berechnungen ausführen, etwa zur Ermittlung der durchschnittlichen Werte über die letzten 30 Sekunden, was ansonsten innerhalb des Programmes selbst hätte implementiert werden müssen. Darüber hinaus wäre es auch möglich, die Werte zur Weiterverarbeitung durch andere Prozesse zur Verfügung zu stellen oder dauerhaft zu archivieren, falls einem Prometheus dafür nicht genügen sollte. Zwar werden aktuell alle Einträge, die älter sind als zwei Tage, aus der Datenbank entfernt, doch wäre eine entsprechende Erweiterung leicht hinzuzufügen. Und falls diese durchaus rationalen Argumente nicht ausreichen sollten – zu guter Letzt wollte ich auch einmal die JSON-Funktionen von MariaDB nutzen, denn tatsächlich besteht die Datenbank-Definition nur aus einer Tabelle, in der die vom Wechselrichter im JSON-Format zur Verfügung gestellten Daten vollständig in einem JSON-Feld gespeichert werden.

Vom Wechselrichter zu Prometheus, erster Akt

Das zweite, oder vielmehr in der Reihenfolge erste Tool, welches ich dank viel zu wenig Phantasie in der Namensfindung einfach invafetch genannt habe (“inverter value fetcher“), macht nun nichts Anderes, als per golrackpi-Library die gewünschten Processdata-Werte vom Wechselrichter zu holen und diese umgehend in die MariaDB-Datenbank wegzuschreiben. Dabei können aktuell die Abstände der Requests sowie die Zeitspanne, nach der sich das Tool eine neue Session holen, sich somit neu einloggen soll, konfiguriert werden.

Damit nun nicht jeder Nutzer sein eigenes Dashboard mittels Grafana basteln muss, stelle ich die von mir in einigen Iterationsschritten entwickelte Dashboard-Definition natürlich ebenfalls zur Verfügung. Da dies jedoch das mein erstes Grafana-Dashboard ist, das ich von Grund auf neu erstellt habe, gibt es dabei natürlich noch einiges Verbesserungspotenzial. Während ich mit der Anzeige der Panels der aktuellen Werte durchaus zufrieden bin, sind die Statistik-Panels noch – naja, sagen wir mal, optimierungsfähig. Auch hier würde ich mich sehr über Ideen, Vorschläge und Inspirationen, oder schlicht und einfach Mitarbeit freuen, um die jetzigen Ergebnisse ein wenig reizvoller darstellen zu können.

Und endlich zum Grafana-Dashboard

Alle Tools, d.h. sowohl invafetch als auch invaps habe ich während der Entwicklung bereits produktiv in der jeweils aktuellen Version zur Erstellung des Dashboards genutzt, insgesamt laufen sie seit einigen Monaten stabil in einer Docker-Umgebung in einer meiner VMs. Um den Einstieg zu erleichtern, ist in einem dritten Repository auf GitHub alles vereint, was zum Start mittels Docker notwendig ist, das betrifft sowohl die Beschreibung der Konfigurationsoptionen, als auch ein Docker-Compose-File, Processdata-Definition, Tabellendefinition sowie natürlich die Dashboard-Definitionsdatei, die einfach in Grafana importiert werden kann.

Da das Kreativitätslevel bei der Namensfindung inzwischen auf der Ebene der Moskauer Metro angelangt war, heißt dieses Repository sinngemäß grkopv-dashboard (“Grafana Kostal Photovoltaic Dashboard“).

Das Ergebnis zeigt sich wie folgt, wobei die Benutzung und insbesondere Interaktivität von Grafana hier im Screenshot naturgemäß nicht dargestellt werden kann:

Grafana Dashboard der heimischen Photovoltaik-Anlage

Auf der Seite Grafana Photovoltaik Dashboard sind die READMEs der drei oben genannten GitHub-Repositories in deutscher Sprache zu finden. Diese sind eher als Archiv zu verstehen, da etwaige Updates und Änderungen zunächst in die englischsprachigen Fassungen auf GitHub einfließen werden.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.

Tags: