Test mit HMS-2000-4T, OpenDTU-C526A4, v24.1.4 erfolgreich
grasmax opened this issue · 2 comments
python-Script zum Auslesen und Einstellen des Limits erfolgreich getestet:
OpenDTU mit externer Magnetfuß Antenne für OpenDTU HMS/HMT Serie
865 MHz, 5dBm, 40m Luftlinie Antenne-Wechselrichter
Großer Dank an die Macher!
Moin Moin, ich versuche mich jetzt hier seit Stunden duch die verschiedensten Versionen, aber ich verliere den Überblick bei den ganzen FORKS weil teilweise die Dokumentation für einen Laien schwer verfolgbar ist, und irgendwie läuft das script nicht.
Mag mir jemand verhelfen meine OpenDTU mit meinem Shelly3EM Pro und meinem RASPI5 zum laufen zu bekommen, am HMS-2000-4t ?
Steht die WLAN-Verbindung zwischen DTU und dem Router?
Steht die Funkverbindung zum Wechselrichter?
Hier die Codefragemente, mit denen ich getestet habe.
Aber Achtung! Das Setzen von Konfigurationswerten zerstört irgendwas!
Hinweise unbedingt beachten!!!
Nur das Auslesen der Werte und das Setzen des Limits funktionieren.
# Hier gefunden: https://github.com/Selbstbau-PV/Selbstbau-PV-Hoymiles-nulleinspeisung-mit-OpenDTU-und-Shelly3EM
# Testergebnis gepostet: https://github.com/Selbstbau-PV/Selbstbau-PV-Hoymiles-nulleinspeisung-mit-OpenDTU-und-Shelly3EM/issues/29
#!/usr/bin/env python3
import requests, time, sys
from requests.auth import HTTPBasicAuth
serial = "nnnnnnnnn" # Seriennummer des Hoymiles Wechselrichters
maximum_wr = 1990 # Maximale Leistung des Wechselrichters in Watt
minimum_wr = 100 # Minimale Leistung des Wechselrichters in Watt
dtu_ip = 'nnn.nnn.nnn.nnn' # IP Adresse von OpenDTU
dtu_nutzer = 'xxxxx' # OpenDTU Nutzername
dtu_passwort = 'yyyyyyy' # OpenDTU Passwort
shelly_ip = '192.100.100.30' # IP Adresse von Shelly 3EM
# API siehe https://www.opendtu.solar/firmware/web_api/
while True:
try:
#url = f'http://{dtu_ip}/api/dtu/config' err
# url = f'http://{dtu_ip}/api/limit/status' ok
#url = f'http://{dtu_ip}/api/ntp/status' ok
# url = f'http://{dtu_ip}/api/ntp/config' err
# url = f'http://{dtu_ip}/api/system/status' ok
# in https://www.opendtu.solar/firmware/web_api/ findet man nur /api/dtu/config
# dann muss man sich selbst zusammenreimen über
# https://www.opendtu.solar/firmware/configuration/dtu_settings/
# wie man die Werte setzen kann
# Leider muss man nicht nur beim Post, sondern auch beim GET Nutzer und Passwort mitgeben!
ret = requests.get(
url = f'http://{dtu_ip}/api/dtu/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'}
)
jData = ret.json()
#Achtung! dieser Aufruf unterbricht die Funkverbindung zum Wechselrichter!
# Vorher unbedingt die config.json sichern, denn nur durch Einlesen der geretteten Konfig und Setzen der Sendeleistung über den
# GUI kann man die Verbindung wiederherstellen!!!
ret = requests.post(
url = f'http://{dtu_ip}/api/dtu/config',
data = f'data={{"serial":"{serial}", "pollinterval":8, "nrf_enabled": "True", "nrf_palevel":0, "cmt_enabled": "True", "cmt_palevel":17,"cmt_frequency": 865000}}',
auth = HTTPBasicAuth(dtu_nutzer, dtu_passwort),
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
)
# 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 Exception as e:
print(f'Fehler beim Abrufen der Daten von openDTU: {e}')
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
setpoint = 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')
print(f'Setpoint {setpoint} neu')
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