Skip to content

Instantly share code, notes, and snippets.

@mklooss
Created February 10, 2024 09:49
Show Gist options
  • Save mklooss/3967f5fe6d14e4cfb9797c75fc4de645 to your computer and use it in GitHub Desktop.
Save mklooss/3967f5fe6d14e4cfb9797c75fc4de645 to your computer and use it in GitHub Desktop.
Nulleinspeisung HM1500 und Shelly 3EM
import pycurl
import json
import math
import time
from io import BytesIO
import sys
import requests
from requests.auth import HTTPBasicAuth
from datetime import datetime
# based on: https://github.com/Selbstbau-PV/Selbstbau-PV-Hoymiles-nulleinspeisung-mit-OpenDTU-und-Shelly3EM
# for an hm-1500 and Shelly 3EM
# with offset (manipulate current wattage usage)
# auth is possible
# submit to opendtu will be as Percent
class HelperClass:
def openurl(self, url, auth = None, postData = None):
buffer = BytesIO()
c = pycurl.Curl()
if auth is not None:
c.setopt(c.USERPWD, auth)
if postData is not None:
c.setopt(c.POST, 1)
c.setopt(c.POSTFIELDS, postData)
c.setopt(c.URL, url)
c.setopt(c.TIMEOUT, 3)
c.setopt(c.CONNECTTIMEOUT, 3)
c.setopt(c.WRITEDATA, buffer)
c.perform()
status = c.getinfo(c.HTTP_CODE)
c.close()
return buffer.getvalue();
while True:
try:
now = datetime.now()
dt_string = now.strftime("%Y-%m%-d %H:%M:%S")
print('Start Check: ', dt_string)
helper = HelperClass()
shellyData = helper.openurl(url = 'http://192.168.2.144/status')
jsonShelly = json.loads(shellyData)
dtuData = helper.openurl(url = 'http://192.168.2.127/api/livedata/status/inverters')
jsonDtu = json.loads(dtuData)
emeter_power = 0;
offset = 300;
for emeter in jsonShelly['emeters']:
emeter_power = emeter_power + round(emeter['power']*-1);
reachable = jsonDtu['inverters'][0]['reachable'] # Ist DTU erreichbar?
producing = int(jsonDtu['inverters'][0]['producing']) # Produziert der Wechselrichter etwas?
current_limit = int(jsonDtu['inverters'][0]['limit_absolute']) # Altes Limit
power_dc = jsonDtu['inverters'][0]['AC']['0']['Power DC']['v'] # Lieferung DC vom Panel
power = round(jsonDtu['inverters'][0]['AC']['0']['Power']['v']) # Abgabe BKW AC in Watt
home_usage = emeter_power+power;
home_usage_extra = emeter_power+power+offset;
home_usage_clean = math.ceil(home_usage_extra / 10)*10
new_limit = home_usage_clean
if new_limit < 800:
new_limit = 1500
if new_limit > 1500:
new_limit = 1500
new_limit_percent = math.ceil((new_limit/1500)*100);
if new_limit_percent > 99:
new_limit_percent = 100
if current_limit != new_limit:
try:
dtuSettings = helper.openurl(url = 'http://192.168.2.127/api/limit/config', postData = f'data={{"serial":"SERIALNUMBER", "limit_type":1, "limit_value":{new_limit_percent}}}')
dtuSettingsJson = json.loads(dtuSettings)
print(f'Konfiguration gesendet ({dtuSettingsJson["type"]})')
except:
print('Fehler beim Senden der Konfiguration')
else:
print('Kein Update notwendig')
except:
print('Fehler beim verarbeiten!')
sys.stdout.flush()
time.sleep(5)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment