Nulleinspeisung Hoymiles HM-1500 mit OpenDTU & Python Steuerung

Wir bieten keinen Support für die Python Steuerung an! Unser Smart Micro Solar basiert auf dem Python Script und ist sehr einfach einzurichten.

 

Dies ist ein Python-Skript, das den aktuellen Hausverbrauch aus einem Shelly 3EM ausliest, die Nulleinspeisung berechnet und die Ausgangsleistung eines Hoymiles-Wechselrichters mit Hilfe der OpenDTU entsprechend anpasst. Somit wird kein unnötiger Strom ins Betreibernetz abgegeben.


Funktionsdiagramm:


Funktionsweise Diagramm


Python Code


#!/usr/bin/env python3
import requests, time, sys
from requests.auth import HTTPBasicAuth


# Diese Daten müssen angepasst werden:
serial = "112100000000" # Seriennummer des Hoymiles Wechselrichters
maximum_wr = 300 # Maximale Ausgabe des Wechselrichters
minimum_wr = 100 # Minimale Ausgabe des Wechselrichters

dtu_ip = '192.100.100.20' # IP Adresse von OpenDTU
dtu_nutzer = 'admin' # OpenDTU Nutzername
dtu_passwort = 'openDTU42' # OpenDTU Passwort

shelly_ip = '192.100.100.30' # IP Adresse von Shelly 3EM


while True:
    try:
        # Nimmt Daten von der openDTU Rest-API und übersetzt sie in ein json-Format
        r = requests.get(url = f'http://{dtu_ip}/api/livedata/status/inverters' ).json()

        # Selektiert spezifische Daten aus der json response
        reachable   = r['inverters'][0]['reachable'] # Ist DTU erreichbar?
        producing   = int(r['inverters'][0]['producing']) # Produziert der Wechselrichter etwas?
        altes_limit = int(r['inverters'][0]['limit_absolute']) # Altes Limit
        power_dc    = r['inverters'][0]['AC']['0']['Power DC']['v']  # Lieferung DC vom Panel
        power       = r['inverters'][0]['AC']['0']['Power']['v'] # Abgabe BKW AC in Watt
    except:
        print('Fehler beim Abrufen der Daten von openDTU')
    try:
        # Nimmt Daten von der Shelly 3EM Rest-API und übersetzt sie in ein json-Format
        phase_a     = requests.get(f'http://{shelly_ip}/emeter/0', headers={'Content-Type': 'application/json'}).json()['power']
        phase_b     = requests.get(f'http://{shelly_ip}/emeter/1', headers={'Content-Type': 'application/json'}).json()['power']
        phase_c     = requests.get(f'http://{shelly_ip}/emeter/2', headers={'Content-Type': 'application/json'}).json()['power']
        grid_sum    = phase_a + phase_b + phase_c # Aktueller Bezug - rechnet alle Phasen zusammen
    except:
        print('Fehler beim Abrufen der Daten von Shelly 3EM')

    # Werte setzen
    print(f'\nBezug: {round(grid_sum, 1)} W, Produktion: {round(power, 1)} W, Verbrauch: {round(grid_sum + power, 1)} W')
    if reachable:
        setpoint = grid_sum + altes_limit - 5 # Neues Limit in Watt

        # Fange oberes Limit ab
        if setpoint > maximum_wr:
            setpoint = maximum_wr
            print(f'Setpoint auf Maximum: {maximum_wr} W')
        # Fange unteres Limit ab
        elif setpoint < minimum_wr:
            setpoint = minimum_wr
            print(f'Setpoint auf Minimum: {minimum_wr} W')
        else:
            print(f'Setpoint berechnet: {round(grid_sum, 1)} W + {round(altes_limit, 1)} W - 5 W = {round(setpoint, 1)} W')

        if setpoint != altes_limit:
            print(f'Setze Inverterlimit von {round(altes_limit, 1)} W auf {round(setpoint, 1)} W... ', end='')
            # Neues Limit setzen
            try:
                r = requests.post(
                    url = f'http://{dtu_ip}/api/limit/config',
                    data = f'data={{"serial":"{serial}", "limit_type":0, "limit_value":{setpoint}}}',
                    auth = HTTPBasicAuth(dtu_nutzer, dtu_passwort),
                    headers = {'Content-Type': 'application/x-www-form-urlencoded'}
                )
                print(f'Konfiguration gesendet ({r.json()["type"]})')
            except:
                print('Fehler beim Senden der Konfiguration')

    sys.stdout.flush() # write out cached messages to stdout
    time.sleep(5) # wait
          

GitHub Repo: https://github.com/Selbstbau-PV/Selbstbau-PV-Hoymiles-nulleinspeisung-mit-OpenDTU-und-Shelly3EM

Einrichtung:

  • Shelly 3EM: Sie müssen den Shelly 3EM mit dem Netzwerk verbinden, in dem sich Ihr Computer befindet. Sie können dies tun, indem Sie das Web-GUI Ihres Shelly-Produkts aufrufen → Internet & Sicherheit → WIFI-MODUS – CLIENT. Setzen Sie ein Häkchen, um das Shelly-Gerät mit einem bestehenden WiFi-Netzwerk zu verbinden, geben Sie den Namen und das Passwort Ihres Netzwerks in die entsprechenden Felder ein und klicken Sie auf Speichern.

Shelly Setup
  • OpenDTU: Sie müssen die OpenDTU an das gleiche Netz wie Ihr eigenes anschließen. Dazu öffnen Sie die OpenDTU Web-GUI → Einstellungen → Netzwerkeinstellungen, füllen die entsprechenden Felder aus und drücken auf Speichern

OpenDTU Setup
  • Python-Skript: Einige Parameter müssen noch im Python Skript angepasst werden. Danach übertragen Sie das Skript auf Ihren Raspberry PI.

Setup von Skript

 

Service anlegen: Um sicherzustellen, dass das Skript gestartet wird, wenn der Raspberry Pi neu startet, rebootet oder hochfährt, müssen Sie einen Service einrichten. Dazu benutzen sie den Befehl sudo nano /etc/systemd/system/nulleinspeisung.service. Dadurch öffnet sich ein Texteditor, in den Sie den folgenden Text einfügen:

[Unit]
Description=Nulleinspeisung Service
After=multi-user.target
[Service]
Type=simple
Restart=always
ExecStart=/usr/bin/python3 /path/to/your/script.py
[Install]
WantedBy=multi-user.target
  • natürlich, muss der Pfad zur Python-Datei entsprechend angepasst werden
  • Skript-Abhängigkeiten: Um das Skript auszuführen wird eine Python Abhängigkeit benötigt. Benutzen sie das Kommando sudo apt install python3-pip um den Paketmanager auf ihrem System zu installieren. Mit sudo pip install requests installieren sie die Abhängigkeit
  • Service-Starten: Nun müssen Sie den Dienst initialisieren, dazu müssen Sie die folgenden Befehle in Ihre Konsole schreiben: sudo systemctl daemon-reload -> sudo systemctl enable nulleinspeisung.service -> sudo systemctl start nulleinspeisung.service. Nachdem Sie das getan haben, überprüfen Sie, ob Ihr Dienst läuft, indem Sie sudo systemctl status nulleinspeisung.service in Ihrer ssh eingeben. So sollte die Ausgabe aussehen:
● nulleinspeisung.service - Nulleinspeisung Service
     Loaded: loaded (/etc/systemd/system/nulleinspeisung.service; enabled; vendor preset: enabled)
     Active: active (running) since Fri 2023-01-27 14:31:08 GMT; 4s ago
   Main PID: 32195 (python3)
      Tasks: 1 (limit: 415)
        CPU: 4.505s
     CGroup: /system.slice/nulleinspeisung.service
             └─32195 /usr/bin/python3 /home/nulleinspeisung/nulleinspeisung.py

Hinweis: Das es sich bei dem Skript um ein Python Skript handelt, muss dies nicht zwingend auf einem Raspberry Pi installiert und ausgeführt werden. Wenn sie ein anders System zum ausführen des Scripts benutzen wollen ist dies völlig in Ordnung. Das System muss nur Python fähig sein.

Zurück zur Übersicht