====== Deye Wechselrichter ====== ==== Einleitung ==== In diesem Artikel geht es um Abfrage und Import von Daten der Wechselrichterreihe SUN300,SUN600,... von Deye und deren Clone (bsp. Bosswerk MI-300 MI600). Diese haben einen WLAN Controller integriert sowie eine Weboberfläche. Diese Wechselrichter haben eine bekannte Sicherheitslücke in der besagten WLAN-Implementierung.\\ Wer das WLAN nutzt sollte dringend die Firmware auf eine sicheren Stand updaten!\\ [[https://www.heise.de/news/Sicherheitsluecke-bei-Mikrowechselrichtern-von-Deye-Haendler-nicht-zustaendig-7483376.html|heise.de: Sicherheitslücke in Mikrowechselrichtern von Deye]]\\ [[https://asarah.de/blogs/news/firmware-update-zur-sicherheit-von-deye-mikrowechselrichtern|asarah.de: So aktualisieren Sie Ihren DEYE Mikrowechselrichter]] Die Sicherheitslücke sind ab der version 1.53 geschlossen diese wird auch automatisch Verteilt\\ Die Neuste Version ist 1.57 in dieser soll der "no Web-Interface" Bug nach Start des WR behoben worden sein Vielen Dank an [[https://github.com/dr-ni|DR_NI auf github]] für sein Abfragescript sowie die Hilfen und Anpassungen. ==== Lösungen ==== Zur Einbindung gibt es 2 Möglichkeiten - über die Cloud-API (Solarman APP) wieder zurück an Volkszähler oder Middle-in-the-Man Datenabgriff - Abfrage der Daten der Weboberfläche ( Vorteil: kein Internetverbindung nötig ; Nachteil: langsame Aktualsierungsrate => 2min) Die zweite Lösung wird im Folgenden beschrieben. ==== Schritt für Schritt ==== ==== Vorbereitung ==== * Wechselrichter über die Weboberfläche ins Netzwerk einbinden AP = AP_XXXXXX PW = 12345678 admin/admin Danach z.B die Internetverbindung des Wechselrichters am Router auf gesperrt setzen.\\ Zusätzlich sollte, wenn möglich, eine feste IP für den Wechselrichter festgelegt werden. * Abfragescript installieren git clone https://github.com/dr-ni/mi600.git * Verzeichnis wechseln cd mi600 * Installation starten sudo make install * Test einer Abfrage (IP-Adresse und Zugangsdaten admin/admin an seinen Wechselrichter anpassen) mi600 IP-Wechselrichter Nutzer Passwort webdata_today_e ==== Möglichkeit 1 CRON ==== * Sendescript Datei erstellen - Manuelle erstellen nano auslesen.sh - alternativ git clone git clone https://github.com/RaptorSDS/VZ_deye_script.git * darin folgenden Inhalt hinzufügen/editieren #!/bin/bash PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin set -e host_pv="192.168.xxxx" user="admin" password="admin" UUID1="768xxxx" UUID2="d69xxxx" UUID3="" host_db="192.168.xxx" TOTAL="" TOTAL_NUM="" DAY="" DAY_NUM="" ACTUAL="" ACTUAL_NUM="" #request value ACTUAL=$(/usr/local/bin/mi600 $host_pv $user $password webdata_now_p) #remove Zero in Front ACTUAL_NUM=$(($ACTUAL)) #send database wget -O - -q "http://"$host_db"/middleware/data/"$UUID1".json?operation=add&value="$ACTUAL_NUM"" #request value TOTAL TOTAL=$(/usr/local/bin/mi600 $host_pv $user $password webdata_total_e) #Remove end SPACE-Char TOTAL_NUM=$(echo $TOTAL | sed 's/[[:space:]]*$//') #check if non ZERO if [ $TOTAL_NUM != "0.0" ] || [ $TOTAL_NUM != "0" ]; then #Send to DB wget -O - -q "http://"$host_db"/middleware/data/"$UUID2".json?operation=add&value="$TOTAL_NUM"" fi #DAY ENERGY #DAY=$(/usr/local/bin/mi600 $host_pv $user $password webdata_today_e) #DAY_NUM=$(echo $DAY | sed 's/[[:space:]]*$//') #wget -O - -q "http://"$host_db"/middleware/data/"$UUID3".json?operation=add&value="$DAY_NUM"" #debug for console #echo 'Today:'$DAY_NUM #echo 'ACTUAL:'$ACTUAL_NUM #echo 'TOTAL:'$TOTAL_NUM Bitte IP Adressen, Wechselrichter Zugangsdaten, UUID an deine Gegebenheiten anpassen. Für den Kanal Leistung kann Auflösung "1" genommen werden Dieses Script sendet nur die aktuelle Leistung an die Middleware, bereits vorbereitet ist alternativ/zusätzlich der Zählerstand. Augrund der langsamen Daten ist eine Zählerstand nicht gut darstellbar\\ Zeilen mit "#" sind auskommentiert und können bei Bedarf genutzt werden für Debug oder um einen zweiten Kanal hinzuzufügen. * Datei Speichern und ausführbar machen chmod +x auslesen.sh * Datei zu CRON hinzufügen (hier als Beispiel Raspberry Pi mit 5 minuten Intervall) */5 * * * * /bin/bash /home/pi/auslesen.sh Die Weboberfläche hat eine sehr langsame Aktualisierungsrate daher sollte der Cronjob nur alle 3 oder 5 Minuten laufen. ==== Möglichkeit 2 VZlogger mit Exec ==== Nachteile Vzlogger darf nicht als root laufen --> umstellung vzlogger siehe [[software:controller:vzlogger|vzlogger]] "vzlogger als anderer Benutzer ausführen" * Sendescript Datei erstellen - Manuelle erstellen nano deye_read_exec.sh - alternativ git clone git clone https://github.com/RaptorSDS/VZ_deye_script.git * darin folgenden Inhalt hinzufügen/editieren #!/bin/bash PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin #set -e / set -u stop scripts if something is wrong set -e set -u # Script: deye_read_exec.sh # Author: Tobias Baumann aka RaptorSDS # License: MIT # with help of OpenAI GPT-3.5 and VZlogger Group # idee by script for KOSTAL_Pico JSON VZlogger exec # Function to display script usage usage() { echo "Usage: $0 ..." exit 1 } # Validate required arguments if [ "$#" -lt 2 ]; then usage fi # Extract hostname HOSTNAME="$1" shift # Extract readings READINGS="$*" user="admin" password="admin" # Request values based on input readings for READING in $READINGS; do if [ "$READING" == "ACTUAL" ]; then ACTUAL=$(/usr/local/bin/mi600 "$HOSTNAME" "$user" "$password" webdata_now_p) #Remove end SPACE-Char ACTUAL_NUM=$(($ACTUAL)) OUTPUT="$ACTUAL_NUM" printf "%s = %s\n" "$READING" "$OUTPUT" elif [ "$READING" == "TOTAL" ]; then TOTAL=$(/usr/local/bin/mi600 "$HOSTNAME" "$user" "$password" webdata_total_e) ##Remove end SPACE-Char TOTAL_NUM=$(echo "$TOTAL" | sed 's/[[:space:]]*$//') OUTPUT="$TOTAL_NUM" if [ $TOTAL_NUM == "0.0" ] || [ $TOTAL_NUM == "0" ] ; then printf "%s = %s\n" "undefine" "$OUTPUT" else printf "%s = %s\n" "$READING" "$OUTPUT" fi elif [ "$READING" == "DAY" ]; then DAY=$(/usr/local/bin/mi600 "$HOSTNAME" "$user" "$password" webdata_today_e) ##Remove end SPACE-Char DAY_NUM=$(echo "$DAY" | sed 's/[[:space:]]*$//') OUTPUT="$DAY_NUM" printf "%s = %s\n" "$READING" "$OUTPUT" else echo "Invalid reading: $READING" fi done Bitte Zugangsdaten, an deine Gegebenheiten anpassen. Der Script hat folgende Config xx.sh hostname reading1 reading2 ... / Reading dürfen sein DAY , TOTAL, ACTUAL * speichern und ausführbar machen sudo chmod +x deye_read_exec.sh * man kann nun zb nach /etc/deye/ kopiernen oder ander gut erkennbare Orte * Kanal Erstellen im Fronend * vzlogger.conf editieren oder erstellen mit folgendem Inhalt { "enabled": true, "allowskip": true, "interval": 240, "aggtime": -1, "aggfixedinterval": false, "channels": [ { "api": "volkszaehler", "uuid": "7680efc0-xxx", "identifier": "ACTUAL", "middleware": "http://localhost/middleware.php", "aggmode": "avg", "duplicates": 0 }, { "api": "volkszaehler", "uuid": "d69e8d40-xx", "identifier": "TOTAL", "middleware": "http://localhost/middleware.php", "aggmode": "none", "duplicates": 43200 } ], "protocol": "exec", "command": "/etc/deye/deye_read_exec.sh 192.168.xxxx ACTUAL TOTAL", "format": "$i = $v" } Der Inverter wird nun alle 240s gelesen , ACTUAL und TOTAL an die DB Übergeben , TOTAL wird auf Duplicate getestet und nur spätesten wenn kein neuer Wert vorhanden ist alle 43200s (12h) neu übernommen * vzlogger neu starten