Inhaltsverzeichnis

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!
heise.de: Sicherheitslücke in Mikrowechselrichtern von Deye
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 DR_NI auf github für sein Abfragescript sowie die Hilfen und Anpassungen.

Lösungen

Zur Einbindung gibt es 2 Möglichkeiten

  1. über die Cloud-API (Solarman APP) wieder zurück an Volkszähler oder Middle-in-the-Man Datenabgriff
  2. 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

 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.
 git clone https://github.com/dr-ni/mi600.git
 cd mi600
 sudo make install
 mi600 IP-Wechselrichter Nutzer Passwort webdata_today_e 

Möglichkeit 1 CRON

  1. Manuelle erstellen
     nano auslesen.sh 
  2. alternativ git clone
    git clone https://github.com/RaptorSDS/VZ_deye_script.git 
bash | auslesen.sh
#!/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.

 chmod +x auslesen.sh
*/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 vzlogger „vzlogger als anderer Benutzer ausführen“

  1. Manuelle erstellen
     nano deye_read_exec.sh 
  2. alternativ git clone
    git clone https://github.com/RaptorSDS/VZ_deye_script.git 
bash | deye_read_exec.sh.sh
#!/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 <hostname> <reading1> <reading2> ..."
  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
 sudo chmod +x deye_read_exec.sh 
    {
      "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