Installationsanleitung

Vorüberlegungen

Ich hatte das Ziel alles Notwendige über NodeRed, Influx und Grafana zu lernen um die wesentlichen Daten der Photovoltaikanlage zu visualisieren. während der Umsetzung bin ich über viele Stolpersteine gefallen und möchte die Lösungen über diese Anleitung Teilen. Gerne können wir hier oder im zugehörigen Thread im Forum über aufkommende Fragen diskutieren. Die Wahl viel bei mir auf NodeRed, da in naher Zukunft noch die gesamte Haustechnik (Wärmepumpe, KNX und Co.) dazu kommen wird.

Der hier verwendete Wechselrichter ist ein: Symo 6.0-3-M


Eine fertige, und sehr coole Alternative zu dem hier beschriebenen Weg wäre das Projekt Solaranzeige. Das solltet ihr euch in jedem Fall ansehen bevor ihr eine eigene Lösung aufsetzt.

Teil 1: Aufsetzen des Raspberry Pi`s

In diesem Abschnitt geht es um das Aufsetzen des Raspberrys mit Raspbian. Da dieses Thema im Internet an sehr vielen Stellen schon beschrieben ist möchte ich hier nicht ins Detail gehen sondern nur gute Howtos verlinken und Hinweise geben die hier im speziellen interessant sind.

Ich habe mich im wesentlichen an folgendes Howto gehalten: https://www.raspifun.de/viewtopic.php?t=4

Es folgen ein paar Infos zu den Schritten die ich durchgeführt habe:

Auswahl der Hardware:

Derzeit läuft mein system auf einem Raspberry Pi 3 Model B Rev 1.2 mit einer 32GB SD karte. In punkto Leistung scheint das völlig ausreichend zu sein.

Installation Raspberry Pi OS (früher Raspbian):

Ich habe mich für das Raspberry Pi OS in der Lite Version entschieden.
Den aktuellen Download findet ihr hier: https://www.raspberrypi.org/downloads/raspberry-pi-os/


Für die Instalation auf der SD-Karte habe ich Win32 DiskImager verwendet

Vor dem ersten Start "SSH Datei" auf dem /boot/ Laufwerk erzeugen um später eine Verbindung per SSH aufbauen zu können

SD-Karte in den Raspberry PI stecken und das System das erste mal booten lassen

SSH Verbindung per Putty herstellen

Root Zugriff über SSH verbieten

Installation von mc

Installation von vim

Update der Paketliste und installation der Updates

Bash
sudo apt-get update && sudo apt-get upgrade
sudo apt-get dist-upgrade


Grundkonfiguration über raspi-config

Bash
sudo raspi-config


- Change User Password -> Passwort des Nutzers pi ändern. Dies als Standard zu lassen ist eher keine gute Idee

- Networking Options / Hostename -> gebt eurem System einen sinnvollen Namen

- Localisation Options / Change Locale -> anpassen auf de_DE.UTF-8 UTF-8

- Localisation Options / Timezone -> Berlin

- Advanced Options / Memory Split -> 16Mb

- Raspi Konfig beenden


Reboot des Systems

- Neustart des Systems mit:

Code
sudo reboot



Nun solltet ihr ein funktionsfähiges Raspbian System haben :thumbup:



Teil 2: Installation Node-Red

Im zweiten Abschnitt geht es um die Installation und Grundkonfiguration von Node-Red.


Auch hier ist schon alles im Internet beschrieben:


Installation Node-Red: https://nodered.org/docs/getting-started/raspberrypi

Absicherung: https://nodered.org/docs/user-…runtime/securing-node-red

Installation Node-Red Admin Tool: https://nodered.org/docs/user-guide/node-red-admin

Hier aber noch einmal die wesentlichen Schritte:

Installation Node-Red

Code
sudo apt-get install build-essential


Code
bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)

Absichern von Node-Red

- Node-Red Admin installieren (bei mir waren hier einige Fehlermeldungen zu sehen, scheint aber normal zu sein?)

Code
sudo npm install -g node-red-admin


- Passwort hash erzeugen:

Code
node-red-admin hash-pw


adminAuth einkommentieren und Passwort hash einfügen (nähere Infos siehe obigen Link)

Code
nano .node-red/settings.js


Autostart beim Systemstart

Code
sudo systemctl enable nodered.service


Starten von Node-Red

Code
node-red-start


Nun solltet ihr euch mit dem Benutzernamen und Passwort in den Node-Red Editor einloggen können :thumbup:


IP:1880 oder HOSTNAME:1880



Teil 3: Installation der InlufxDB

Im dritten Abschnit geht es um die Installation und Grundkonfiguration der InfluxDB.


Auch hier gibt es natürlich wieder gute Anleitungen: https://docs.influxdata.com/in…cation_and_authorization/

Influx DB installieren:

Code
curl -sL https://repos.influxdata.com/influxdb.key | sudo apt-key add -
Code
echo "deb https://repos.influxdata.com/debian buster stable" | sudo tee /etc/apt/sources.list.d/influxdb.list
Code
sudo apt update
Code
sudo apt install influxdb


Influx bei Systemstart aktivieren:

Code
sudo systemctl enable influxdb


Influx starten:

Code
sudo systemctl start influxdb


Influx Console starten um User und Datenbanken anzulegen:

Code
influx


Admin User mit allen Rechten anlegen:

Code
CREATE USER admin WITH PASSWORD 'HIERPASSWORTEINTRAGEN' WITH ALL PRIVILEGES



Datenbank und Datenbank Nutzer anlegen (ich habe hier für beides den Namen fronius verwendet)

Code
CREATE DATABASE fronius
Code
CREATE USER fronius WITH PASSWORD 'HIERPASSWORTEINTRAGEN'
Code
GRANT ALL ON "fronius" TO "fronius"
Code
exit


HTTP Authentifizierung aktivieren

Code
sudo nano /etc/influxdb/influxdb.conf


Hier müssen im Abschnitt [http] die folgende Zeilen überprüft und gegebenenfalls muss die Raute # entfernt werden werden.

enabled = true

bind-address = „:8086“

auth-enabled = true


Influx Neustarten:

Code
sudo systemctl restart influxdb



Nun solltet ihr eine laufende InfluxDB haben. In den folgenden Abschnitten werden hier die Daten gespeichert :thumbup:



Teil 4: Installation oder Upgrade von Grafana

In diesem Abschnitt geht es um die Installation von Grafana. Bitte checkt vor der Installation ob die Version im Link (der mit dem Datum) die aktuelle ist.

Die aktuelle Version findet ihr hier: https://grafana.com/grafana/download?platform=arm

Ein Update könnt ihr im übrigen genauso durchführen. Den ersten Schritt benötigt ihr dann nicht mehr.

Installation:

Code
sudo apt-get install -y adduser libfontconfig1
Code
wget https://dl.grafana.com/oss/release/grafana-rpi_7.0.3_armhf.deb (Stand 16.06.2020)
Code
sudo dpkg -i grafana-rpi_7.0.3_armhf.deb


Starten bei Systemstart

Code
sudo systemctl enable grafana-server

Starten

Code
sudo systemctl start grafana-server


Nun solltet ihr Grafana über den Browser erreichen können: http://IP-Adresse:3000/login oder http://Hostname:3000/login :thumbup:


Teil 5: Konfiguration NodeRed (Modbus TCP)

In diesen Blog Eintrag geht um das Auslesen der Daten per Modbus TCP mit NodeRed. Grundsätzlich fuktioniert das schon. In einem nächsten Schritt werde ich die ausgelesenen Daten noch verifizieren. An der ein oder anderen Stelle bin ich mir noch unsicher ob die Werte plausibel sind.

Grundlagen

Die Fronius Wechselrichter stellen mehrere Schnittstellen zur Abfrage der Systemdaten zur Verfügung:

  • Fronius Push Service
  • Fronius Solar API (JSON) (hierzu gibt es auch eine kurze Anleitung die aber nicht weiter gepflegt wird)
  • Modbus RTU
  • Modbus TCP (hier verwendet)

Auf dieser Internetseite findet ihr die Dokumentation der Schnittstellen: https://www.fronius.com/de/sol…schnittstellen/modbus-tcp


Unter diesem Link findet ihr eine .zip Datei mit Tabellen der Modbus Register: www.fronius.com/QR-link/0006


In den folgenden Tabellen hatte ich mir damals alle relevanten Informationen aus der Schnittstellen Spezifikation rausgesucht:

Meter_Register_Map_Float_v1.0.pdf
Inverter_Register_Map_Float_v1.0_with_SYMOHYBRID_MODEL_124.pdf

  • gelb markierte Zeilen habe ich nicht verwendet
  • grün markierte Zeilen werden verwendet
  • da ich mehrere Register gleichzeitig abfrage sind in der Spalte C und D der Offset vom Startregister eingetragen um die abgefragten Register aus dem Rückgabewert wieder auseinander sortieren zu können

Modbus Schnittstelle aktivieren

  • geht mit einen Browser über die IP-Adresse auf die Seite eures Wechselrichters
  • Rechts unten auf Einstellungen
  • Login als admin. Das Passwort solltet ihr von eurem Installateur bekommen haben
  • Menüpunkt Modbus auswählen
  • folgende Einstellungen wählen:

NodeRed aufrufen und konfigurieren

  • Ruft über euren Browser NodeRed auf: IP:1880 oder HOSTNAME:1880 -> Login mit den von euch definierten Benutzerdaten
  • Installation der Erweitungen über Palette verwalten / installeren:
    • node-red-contrib-influxdb
    • node-red-contrib-modbus
    • node-red-contrib-throttle
    • node-red-contrib-cron-plus

Aufbau des Flows

Import des Flows


Ihr könnt folgenden Flow importieren, jedoch müsst ihr diese Punkte Anpassen:


  • IP-Adresse des Wechselrichters der modbus-read Nodes
  • Datenbank, Benutzername und Passwort der influxdb out Nodes


Code
[{"id":"a9827259.c41c","type":"function","z":"56001560.ab571c","name":"Smart_Meter_10s","func":"var msg1 = {};\n\nmsg1.payload = \n{\n Current_AC : parseFloat(msg.payload.buffer.readFloatBE(0,1,2,3).toFixed(2)),\n Current_AC_Phase_1 : parseFloat(msg.payload.buffer.readFloatBE(4,5,6,7).toFixed(2)),\n Current_AC_Phase_2 : parseFloat(msg.payload.buffer.readFloatBE(8,9,10,11).toFixed(2)),\n Current_AC_Phase_3 : parseFloat(msg.payload.buffer.readFloatBE(12,13,14,15).toFixed(2)),\n\n Voltage_AC_Phase_1 : parseFloat(msg.payload.buffer.readFloatBE(20,21,22,23).toFixed(2)),\n Voltage_AC_Phase_2 : parseFloat(msg.payload.buffer.readFloatBE(24,25,26,27).toFixed(2)),\n Voltage_AC_Phase_3 : parseFloat(msg.payload.buffer.readFloatBE(28,29,30,31).toFixed(2)),\n \n Voltage_AC_PhaseToPhase_12 : parseFloat(msg.payload.buffer.readFloatBE(36,37,38,39).toFixed(2)),\n Voltage_AC_PhaseToPhase_23 : parseFloat(msg.payload.buffer.readFloatBE(40,41,42,43).toFixed(2)),\n Voltage_AC_PhaseToPhase_31 : parseFloat(msg.payload.buffer.readFloatBE(44,45,46,47).toFixed(2)),\n \n Frequency_AC : parseFloat(msg.payload.buffer.readFloatBE(48,49,50,51).toFixed(2)),\n \n PowerReal_AC_Grid : parseFloat(msg.payload.buffer.readFloatBE(52,53,54,55).toFixed(2)),\n \n // Berechnen der Last über Flow Variable P_PV_AC vom Inverter\n PowerReal_AC_Load : flow.get('P_PV_AC') + parseFloat(msg.payload.buffer.readFloatBE(52,53,54,55).toFixed(2)),\n\n PowerReal_AC_Phase_1 : parseFloat(msg.payload.buffer.readFloatBE(56,57,58,59).toFixed(2)),\n PowerReal_AC_Phase_2 : parseFloat(msg.payload.buffer.readFloatBE(60,61,62,63).toFixed(2)),\n PowerReal_AC_Phase_3 : parseFloat(msg.payload.buffer.readFloatBE(64,65,66,67).toFixed(2)),\n}\n\nreturn msg1;","outputs":1,"noerr":0,"x":650,"y":260,"wires":[["e89b20a7.19f768"]]},{"id":"a246ecac.33e978","type":"modbus-read","z":"56001560.ab571c","name":"Smart-Meter [40072 bis 40193] [10s]","topic":"","showStatusActivities":false,"logIOActivities":false,"showErrors":false,"unitid":"240","dataType":"HoldingRegister","adr":"40071","quantity":"122","rate":"10","rateUnit":"s","delayOnStart":false,"startDelayTime":"","server":"3a2f0c99.2d367c","useIOFile":false,"ioFile":"","useIOForPayload":false,"x":270,"y":260,"wires":[[],["a9827259.c41c","4707e368.34068c"]]},{"id":"4707e368.34068c","type":"function","z":"56001560.ab571c","name":"Smart_Meter_10m","func":"var msg1 = {};\n\nvar E_Grid_Exported = msg.payload.buffer.readFloatBE(116,117,118,119)/1000;\nvar E_Grid_Imported = msg.payload.buffer.readFloatBE(132,133,134,135)/1000;\n\n\n//Verfügbarkeit der Variablen für den Bereich Historical\nflow.set('E_Grid_Exported',E_Grid_Exported);\nflow.set('E_Grid_Imported',E_Grid_Imported);\n\n\nmsg1.payload = \n{\n \n //Alt\n E_Grid_Feedin : parseFloat(E_Grid_Exported.toFixed(3)),\n E_Grid_Consumption : parseFloat(E_Grid_Imported.toFixed(3)),\n\n //Neu\n E_Grid_Exported : parseFloat(E_Grid_Exported.toFixed(3)),\n E_Grid_Imported : parseFloat(E_Grid_Imported.toFixed(3)),\n}\n\nreturn msg1;","outputs":1,"noerr":0,"x":650,"y":300,"wires":[["1dcb80e1.edc50f"]]},{"id":"1dcb80e1.edc50f","type":"throttle","z":"56001560.ab571c","name":"10m","throttleType":"time","timeLimit":"10","timeLimitType":"minutes","countLimit":0,"blockSize":0,"locked":false,"x":870,"y":300,"wires":[["e51c6b85.f2db28"]]},{"id":"58593171.53ffa","type":"modbus-read","z":"56001560.ab571c","name":"Inverter [40072 bis 40109] [10s]","topic":"","showStatusActivities":false,"logIOActivities":false,"showErrors":false,"unitid":"1","dataType":"HoldingRegister","adr":"40071","quantity":"38","rate":"10","rateUnit":"s","delayOnStart":false,"startDelayTime":"","server":"3a2f0c99.2d367c","useIOFile":false,"ioFile":"","useIOForPayload":false,"x":250,"y":400,"wires":[[],["6745ed07.cd79fc","a078cc5a.a244b"]]},{"id":"6745ed07.cd79fc","type":"function","z":"56001560.ab571c","name":"Inverter_10s","func":"var msg1 = {};\n\nvar P_PV_AC = msg.payload.buffer.readFloatBE(40,41,42,43);\nvar P_PV_DC = msg.payload.buffer.readFloatBE(72,73,74,75);\n\n// Setzen der Flow Variable P_PV_AC\nflow.set('P_PV_AC',P_PV_AC);\n\n// Berechnung Auslastung Inverter und Panel\nvar Workload_Inverter = (P_PV_AC / 6000)*100;\nvar Wordload_Panel = (P_PV_AC / 6800)*100;\n\n\nif (P_PV_DC > 0){\n\n// Berechnung Wirkungsgrad AC / DC Leistung\nvar n_PV_DC_AC = (P_PV_AC / P_PV_DC) * 100;\n\n msg1.payload = \n {\n P_PV_AC : parseFloat(P_PV_AC.toFixed(2)),\n P_PV_DC : parseFloat(P_PV_DC.toFixed(2)),\n Workload_Inverter : parseFloat(Workload_Inverter.toFixed(2)),\n Wordload_Panel : parseFloat(Wordload_Panel.toFixed(2)),\n n_PV_DC_AC : parseFloat(n_PV_DC_AC.toFixed(2)),\n }\n}\nelse{\n msg1.payload = \n {\n P_PV_AC : parseFloat(P_PV_AC.toFixed(2)),\n P_PV_DC : parseFloat(P_PV_DC.toFixed(2)),\n Workload_Inverter : parseFloat(Workload_Inverter.toFixed(2)),\n Wordload_Panel : parseFloat(Wordload_Panel.toFixed(2)),\n }\n}\n\n//Filter für fehlerhafte Werte\nif (msg1.payload.n_PV_DC_AC > 100) {delete msg1.payload.n_PV_DC_AC}\n\n\n\n\nreturn msg1;","outputs":1,"noerr":0,"x":630,"y":400,"wires":[["edd717f2.99bf9"]]},{"id":"edd717f2.99bf9","type":"throttle","z":"56001560.ab571c","name":"10s","throttleType":"time","timeLimit":"10","timeLimitType":"seconds","countLimit":0,"blockSize":0,"locked":false,"x":870,"y":400,"wires":[["e51c6b85.f2db28"]]},{"id":"a078cc5a.a244b","type":"function","z":"56001560.ab571c","name":"Inverter_10m","func":"var msg1 = {};\n\nvar E_PV_AC = msg.payload.buffer.readFloatBE(60,61,62,63)/1000\n\n\n//Verfügbarkeit der Variablen für den Bereich Historical\nflow.set('E_PV_AC',E_PV_AC);\n\n\nmsg1.payload = \n{\n E_PV_AC : parseFloat(E_PV_AC.toFixed(3)),\n}\n\nreturn msg1;","outputs":1,"noerr":0,"x":630,"y":440,"wires":[["fc033e6c.595198"]]},{"id":"fc033e6c.595198","type":"throttle","z":"56001560.ab571c","name":"10m","throttleType":"time","timeLimit":"10","timeLimitType":"minutes","countLimit":0,"blockSize":0,"locked":false,"x":870,"y":440,"wires":[["e51c6b85.f2db28"]]},{"id":"2a1d2125.699bc6","type":"modbus-read","z":"56001560.ab571c","name":"Inverter [214] [10m]","topic":"","showStatusActivities":false,"logIOActivities":false,"showErrors":false,"unitid":"1","dataType":"HoldingRegister","adr":"213","quantity":"1","rate":"10","rateUnit":"m","delayOnStart":false,"startDelayTime":"","server":"3a2f0c99.2d367c","useIOFile":false,"ioFile":"","useIOForPayload":false,"x":210,"y":100,"wires":[[],["d50f76bf.59848"]]},{"id":"d50f76bf.59848","type":"function","z":"56001560.ab571c","name":"Inverter_10m","func":"var msg1 = {};\n\nmsg1.payload = \n{\n StateCode : msg.payload.buffer.readUInt16BE(0,1),\n}\n\nreturn msg1;\n\n","outputs":1,"noerr":0,"x":630,"y":100,"wires":[["e51c6b85.f2db28"]]},{"id":"5de1ed08.de2f74","type":"modbus-read","z":"56001560.ab571c","name":"Inverter [40266 bis 40313] [10s]","topic":"","showStatusActivities":false,"logIOActivities":false,"showErrors":false,"unitid":"1","dataType":"HoldingRegister","adr":"40265","quantity":"48","rate":"10","rateUnit":"s","delayOnStart":false,"startDelayTime":"","server":"3a2f0c99.2d367c","useIOFile":false,"ioFile":"","useIOForPayload":false,"x":250,"y":180,"wires":[[],["fd5b10f9.323d3"]]},{"id":"e51c6b85.f2db28","type":"influxdb out","z":"56001560.ab571c","influxdb":"a609b286.bc25d","name":"","measurement":"actual","precision":"","retentionPolicy":"","x":1310,"y":200,"wires":[]},{"id":"5533b18c.5e789","type":"influxdb out","z":"56001560.ab571c","influxdb":"a609b286.bc25d","name":"","measurement":"historical","precision":"","retentionPolicy":"","x":1380,"y":680,"wires":[]},{"id":"fd5b10f9.323d3","type":"function","z":"56001560.ab571c","name":"Inverter_10s","func":"var msg1 = {};\n\nvar Scale_Factor_I = msg.payload.buffer.readInt16BE(0,1);\nvar Scale_Factor_U = msg.payload.buffer.readInt16BE(2,3);\nvar Scale_Factor_P = msg.payload.buffer.readInt16BE(4,5);\nvar Scale_Factor_E = msg.payload.buffer.readInt16BE(6,7);\n\n\nmsg1.payload = {\n\n I_PV_DC_String_1 : msg.payload.buffer.readUInt16BE(34,35)*Math.pow(10.0, Scale_Factor_I),\n U_PV_DC_String_1 : msg.payload.buffer.readUInt16BE(36,37)*Math.pow(10.0, Scale_Factor_U),\n P_PV_DC_String_1 : msg.payload.buffer.readUInt16BE(38,39)*Math.pow(10.0, Scale_Factor_P),\n E_PV_DC_String_1 : msg.payload.buffer.readUInt32BE(40,41,42,43)*Math.pow(10.0, Scale_Factor_E)/1000,\n\n I_PV_DC_String_2 : msg.payload.buffer.readUInt16BE(74,75)*Math.pow(10.0, Scale_Factor_I),\n U_PV_DC_String_2 : msg.payload.buffer.readUInt16BE(76,77)*Math.pow(10.0, Scale_Factor_U),\n P_PV_DC_String_2 : msg.payload.buffer.readUInt16BE(78,79)*Math.pow(10.0, Scale_Factor_P),\n E_PV_DC_String_2 : msg.payload.buffer.readUInt32BE(80,81,82,83)*Math.pow(10.0, Scale_Factor_E)/1000,\n}\n\n\n//Filter für fehlerhafte Modbus Werte\nif (msg1.payload.I_PV_DC_String_1 == 655.35) {delete msg1.payload.I_PV_DC_String_1}\nif (msg1.payload.U_PV_DC_String_1 == 655.35) {delete msg1.payload.U_PV_DC_String_1}\nif (msg1.payload.P_PV_DC_String_1 == 655.35) {delete msg1.payload.P_PV_DC_String_1}\n\nreturn msg1;\n","outputs":1,"noerr":0,"x":630,"y":180,"wires":[["e51c6b85.f2db28"]]},{"id":"84657942.66d54","type":"cronplus","z":"56001560.ab571c","name":"","outputField":"payload","timeZone":"","options":[{"topic":"EOD","payload":"","type":"str","expression":"0 0 0 * * *"},{"topic":"EOM","payload":"","type":"str","expression":"0 0 0 1 * *"}],"x":140,"y":680,"wires":[["72c34caf.1fd79c"]]},{"id":"72c34caf.1fd79c","type":"switch","z":"56001560.ab571c","name":"","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"EOD","vt":"str"},{"t":"eq","v":"EOM","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":320,"y":680,"wires":[["85034beb.42d6d8"],["19f796ab.fb2389"]],"outputLabels":["Schedule Trigger","Control Reply"]},{"id":"19f796ab.fb2389","type":"influxdb in","z":"56001560.ab571c","influxdb":"a609b286.bc25d","name":"Abfrage Zählerstände Energie von vor einem Monat","query":"SELECT max(\"E_Grid_Imported_1M\"), max(\"E_Grid_Exported_1M\"), max(\"E_PV_AC_1M\") FROM historical","rawOutput":false,"precision":"","retentionPolicy":"","x":680,"y":720,"wires":[["896f291e.c44948"]]},{"id":"896f291e.c44948","type":"function","z":"56001560.ab571c","name":"Monatsauswertung","func":"var msg1 = {};\n\n//Übernehmen der Flow Variablen\nE_Grid_Imported = flow.get('E_Grid_Imported');\nE_Grid_Exported = flow.get('E_Grid_Exported');\nE_PV_AC = flow.get('E_PV_AC');\n\n//Berechnen des Monats Delta\nE_Grid_Imported_Monthly = E_Grid_Imported - msg.payload['0'].max;\nE_Grid_Exported_Monthly = E_Grid_Exported - msg.payload['0'].max_1;\nE_PV_AC_Monthly = flow.get('E_PV_AC') - msg.payload['0'].max_2;\n\n//Berechnen weiterer Monatswerte\nE_PV_AC_Self_Consumption_Monthly = E_PV_AC_Monthly - E_Grid_Exported_Monthly;\nP_PV_AC_Self_Consumption_Monthly = (E_PV_AC_Self_Consumption_Monthly / E_PV_AC_Monthly) * 100;\nP_GRID_Self_Sufficiency_Monthly = (E_PV_AC_Self_Consumption_Monthly / (E_PV_AC_Self_Consumption_Monthly + E_Grid_Imported_Monthly)) * 100;\n\n\nmsg1.payload = \n{\n E_Grid_Imported_Monthly : parseFloat(E_Grid_Imported_Monthly.toFixed(3)),\n E_Grid_Exported_Monthly : parseFloat(E_Grid_Exported_Monthly.toFixed(3)),\n E_PV_AC_Monthly : parseFloat(E_PV_AC_Monthly.toFixed(3)),\n\n E_PV_AC_Self_Consumption_Monthly : parseFloat(E_PV_AC_Self_Consumption_Monthly.toFixed(2)),\n P_PV_AC_Self_Consumption_Monthly : parseFloat(P_PV_AC_Self_Consumption_Monthly.toFixed(1)),\n P_GRID_Self_Sufficiency_Monthly : parseFloat(P_GRID_Self_Sufficiency_Monthly.toFixed(1)),\n \n E_Grid_Imported_1M : E_Grid_Imported,\n E_Grid_Exported_1M : E_Grid_Exported,\n E_PV_AC_1M : E_PV_AC,\n }\n\n\n\nreturn msg1;\n\n\n","outputs":1,"noerr":0,"x":1030,"y":720,"wires":[["5533b18c.5e789"]]},{"id":"e89b20a7.19f768","type":"throttle","z":"56001560.ab571c","name":"10s","throttleType":"time","timeLimit":"10","timeLimitType":"seconds","countLimit":0,"blockSize":0,"locked":false,"x":870,"y":260,"wires":[["e51c6b85.f2db28"]]},{"id":"85034beb.42d6d8","type":"influxdb in","z":"56001560.ab571c","influxdb":"a609b286.bc25d","name":"Abfrage Zählerstände Energie von vor 24h","query":"SELECT max(\"E_Grid_Imported_24h\"), max(\"E_Grid_Exported_24h\"), max(\"E_PV_AC_24h\") FROM historical","rawOutput":false,"precision":"","retentionPolicy":"","x":650,"y":660,"wires":[["20786f80.bc115"]]},{"id":"20786f80.bc115","type":"function","z":"56001560.ab571c","name":"Tagessauswertung","func":"var msg1 = {};\n\n//Übernehmen der Flow Variablen\nE_Grid_Imported = flow.get('E_Grid_Imported');\nE_Grid_Exported = flow.get('E_Grid_Exported');\nE_PV_AC = flow.get('E_PV_AC');\n\n\n//Berechnen des Tages Delta\nE_Grid_Imported_Daily = E_Grid_Imported - msg.payload['0'].max;\nE_Grid_Exported_Daily = E_Grid_Exported - msg.payload['0'].max_1;\nE_PV_AC_Daily = flow.get('E_PV_AC') - msg.payload['0'].max_2;\n\n//Berechnen weiterer Monatswerte\nE_PV_AC_Self_Consumption_Daily = E_PV_AC_Daily - E_Grid_Exported_Daily;\nP_PV_AC_Self_Consumption_Daily = (E_PV_AC_Self_Consumption_Daily / E_PV_AC_Daily) * 100;\nP_GRID_Self_Sufficiency_Daily = (E_PV_AC_Self_Consumption_Daily / (E_PV_AC_Self_Consumption_Daily + E_Grid_Imported_Daily)) * 100;\n\n\nmsg1.payload = \n{\n E_Grid_Imported_Daily : parseFloat(E_Grid_Imported_Daily.toFixed(3)),\n E_Grid_Exported_Daily : parseFloat(E_Grid_Exported_Daily.toFixed(3)),\n E_PV_AC_Daily : parseFloat(E_PV_AC_Daily.toFixed(3)),\n\n E_PV_AC_Self_Consumption_Daily : parseFloat(E_PV_AC_Self_Consumption_Daily.toFixed(2)),\n P_PV_AC_Self_Consumption_Daily : parseFloat(P_PV_AC_Self_Consumption_Daily.toFixed(1)),\n P_GRID_Self_Sufficiency_Daily : parseFloat(P_GRID_Self_Sufficiency_Daily.toFixed(1)),\n \n E_Grid_Imported_24h : E_Grid_Imported,\n E_Grid_Exported_24h : E_Grid_Exported,\n E_PV_AC_24h : E_PV_AC,\n }\n\n\n\nreturn msg1;\n\n\n","outputs":1,"noerr":0,"x":1030,"y":660,"wires":[["5533b18c.5e789"]]},{"id":"3a2f0c99.2d367c","type":"modbus-client","z":"","name":"","clienttype":"tcp","bufferCommands":true,"stateLogEnabled":false,"tcpHost":"192.168.16.24","tcpPort":"502","tcpType":"DEFAULT","serialPort":"/dev/ttyUSB","serialType":"RTU-BUFFERD","serialBaudrate":"9600","serialDatabits":"8","serialStopbits":"1","serialParity":"none","serialConnectionDelay":"100","unit_id":1,"commandDelay":1,"clientTimeout":1000,"reconnectOnTimeout":true,"reconnectTimeout":2000,"parallelUnitIdsAllowed":true},{"id":"a609b286.bc25d","type":"influxdb","z":"","hostname":"127.0.0.1","port":"8086","protocol":"http","database":"fronius","name":"","usetls":false,"tls":""}]

Teil 6: Konfiguration Grafana

Diesen Teil muss ich euch leider nocht schuldig bleiben. Ich denke im Laufe des Februars 2020 kommt auch dies.
Die meisten Sachen sind in Grafana aber selbst erklärend. Ihr könnt eure Influx Datenbank auswählen und die Datenreihen

sehr einfach in Grafen darstellen.


Teil 7: Backup der Daten


Auf der folgenden Seite ist beschrieben wie ihr ein Backup der Influx Datenbank erstellen könnt:

https://docs.influxdata.com/in…ation/backup_and_restore/


Folgenden Befehl nutze ich:

Code
sudo influxd backup -portable /home/pi/influxbackup_20200430



Damit ihr den Ordner danach mit dem User pi verschieben könnt müsst ihr die Rechte des Ordners anpassen:

Code
sudo chown -R pi:pi /home/pi/influxbackup_20200430/



Teil 8: Schonen der SD-Karte

Damit die vielen Schreibzugriffe nicht die SD Karte unnötig belasten hier ein paar Möglichkeiten diese zu reduzieren.


Swap deaktivieren:


Swapping-Dienst stoppen:

Code
sudo service dphys-swapfile stop


Prüfen ob das Swapping abgeschaltet ist:

Code
free


Stehen hier bei Swap nur noch Nullen, kann der Swap-Dienst deaktiviert werden.

Code
sudo systemctl disable dphys-swapfile


Alternativ Swap Dienst entfernen

Code
sudo apt-get purge dphys-swapfile





Todo:

Teil 6 schreiben

Teil 7 erweitern um automatisierung, Nodered und Grafana
Verifikation der ausgelesenen Daten

Changelog:

16.06.2020: Link zum Garafana Paket aktualisiert
30.04.2020: Backup hinzugefügt
05.03.2020: Fehler bei den Monatswerten Korrigiert

17.02.2020: Speicherung der Tages- und Monatswerte angepasst
10.02.2020: Fehler beim Auslesen der Spannung, Strom, Leistung der Strings korrigiert.
09.02.2020: Fehler beim Auslesen der Insgesamt produzierten Energie der Strings korrigiert. Jetzt sind Werte plausibel

09.02.2020: Teil 1 bis Teil 4 in einen Blog Eintrag zusammengeführt, Teil 5 (Modbus) beschrieben

Wechselrichter:

Fronius Symo 6.0-3-M


Verschaltung/Module:

MPPT1:
Hausdach 50 Grad Neigung, 185 Grad Süd: 7 * Axitec AXIworldpremium X HC BLK 400 Wp

MPPT2 (Serielle Verschaltung):

Garagendach 45 Grad Neigung, 95Grad Ost: 5 * Axitec AXIworldpremium X HC BLK 400 Wp

Garagendach 45 Grad Neigung, 275Grad West: 5 * Axitec AXIworldpremium X HC BLK 400 Wp mit Tigo TS4-R-O

Datenlogger mit Node-Red InfluxDB und Grafana