Es gibt Menschen die tun einfach Gutes und welche die fordern lautstark von den anderen Gutes zu tun. Bei mir werkelt mehr oder weniger wirtschaftlich sinnvoll seit 2000 eine Solaranlage für Warmwasser am Dach. Ergänzt wird dies nun um eine Solaranlage (auch Photovoltaik genannt) auf dem Carport Dach. Ideal Richtung Süden ausgerichtet, Kaufpreis knapp 600€ (aktuell ohne Mwst in Deutschland) in der Miniausführung als sogenanntes Balkonkraftwerk. Eigentlich 840W installierte Leistung aber durch irgendein Gesetz und Regler auf 600W limitiert.
Natürlich ist das China Ware. Natürlich weil dort der Strom einen Bruchteil kostet, die Arbeitskraft billiger ist, der Umweltschutz geringer usw. Dafür sind unsere Werte besser und alle neidisch oder so. Das man das Zeugs dafür noch in Containern 12.000km weit schippern muss, geschenkt.
Jedenfalls ist da ein Wechselrichter den es unter der Bezeichnung Deye 600 von X Herstellern, alle aus China, gibt. Bekommt der Wandler Strom aus den Solarpanels, kann man per App den ins heimische Wlan konfigurieren und dann auch per eigenen “Not” Webinterface über seine Befindlichkeiten befragen.
In dem schmucken Silberkästchen ist vermutlich Hardware und Prozessor verbaut, das sich gewaschen hat. Der Wandler spricht auch automatisch mit seiner chinesischen Heimat und übermittelt Daten. Mit Zugriff zum Wlan, ist da bestimmt interessantes dabei. Um sich den zumindest offiziellen Part zu gemüte zu führen, kann man sich noch einen Account bei Solarmanpv.com erstellen und den Wandler per Seriennummer mit dem Portal verbinden. Auf dem Wandler ist der Server schon konfiguriert.
Aber wir tun ja Gutes. Persönlich bin ich fest davon überzeugt, das man damit alle Wandler und damit die Stromerzeugung bei Bedarf zentral stilllegen kann, für immer. Aber darum gehts nicht. Beim Blick in das Web Portal stellt man fest: Ui das ist schick und mein Wandler regelt dauernd bei knapp unter 600W ab. (es gäbe auch einen 800W)
Also ich verschenke hier schon staatlich gewollt mal 30% wenn die Sonne knallt. Aber noch schlimmer, wer soll den Rest verbrauchen? Ich schätze die Grundlast meines Hauses auf unter 200W. Also 400 bekommt der Stromanbieter geschenkt. Da erinnere ich mich an den wertvollen Tipp “grundlastfrei und angebotsorientiert” irgendeiner grünen Trulle (Liebe Grünwähler ich entschuldige mich schon mal bei Ihnen).
Als stolzer Poolbesitzer betreibe ich eine Pumpe, die rund 800W braucht und die man in der Tat tagsüber bei Sonnenschein mit gecutetten 600W immerhin “stützen” kann. Ok das Problem hätte ich schon mal, aber wie löse ich das?
Probleme:
- Leistungsdaten der PV Anlage
- Schalter für die Pumpe
- Steuerungscomputer
Der Wandler kann bestimmt ganz wunderbar Daten nach China liefern, aber zu mir ist er zickig. Die meisten Lösungen aus der Google Echo Kammer gehen über die API von SolarmanPV nach China um die erzeugte Leistung von meinem Wandler im Garten zu bekommen. Leider hat der Wandler keine API sondern nur obiges rudimentäres Web Interface. Durch Reverse Engineering bin ich ihm auf die Schliche gekommen, dass es noch eine kleinere Seite gibt, die als eine Art Service agiert und die produzierte Leistung enthält. Sind rund 4KB pro Request auf den Wandler.
Achtung undokumentiert und wenn die Chinesen…
Dann habe ich mir einen Raspberry 3B aus dem Regal genommen. Da die Pflaumen aus Seattle Windows nicht mehr mögen, da Windows IoT durch ein RaspberryOS ersetzt wird, mich dann über SSH Visual Studio Code gehandelt und tatsächlich ein Python Script zum laufen gebracht habe, dass meinen Wandler als API missbraucht. Man muss sich per Basic Authentifizierung anmelden. Das kann man leicht per Username: Passwort Kombi in einem Base64 String konvertieren und statisch anlegen oder wie hier dynamisch.
1: import requests
2: import time
3: import re
4: url = "http://10.0.0.22/status.html"
5: username = "admin"
6: password = "sf345dgdf"
7: pattern = r'var webdata_now_p = "([\d]+)";'
8: while True:
9: response = requests.get(url, auth=(username, password))
10:
11: if response.status_code == 200:
12: match = re.search(pattern, response.content.decode("utf-8"))
13: if match:
14: # Extrahiere den Wert aus dem Muster
15: value = match.group(1)
16: print("Wert: ", value)
17: if value > 200:
18: # Rufen Sie die High-Value-URL auf
19: high_value_response = requests.get(high_value_url)
20: if high_value_response.status_code == 200:
21: print("High-Value-URL aufgerufen")
22: else:
23: print("Fehler beim Aufrufen der High-Value-URL:", high_value_response.status_code)
24: else:
25: print("Kein Muster gefunden.")
26:
27: else:
28: print("Fehler beim Abrufen der URL:", response.status_code)
29:
30: time.sleep(60) # Wartezeit in Sekunden
Fehlt nur noch der Schalter. Zuerst einen für 10€ bestellt und dann festgestellt, das Ding spricht wieder nur mit einem China Server über mein Wlan über ne Android App. Genau das wollte ich nicht. Ich will es AntiCloud gelöst haben. Per Twitter wurde mir zur Shelly Familie geraten. Hersteller Allterco sitzt in Bulgarien und vermutlich gehört die Bude auch den Chinesen.
Beim Amazon den Shelly Plus 1 bestellt. Das Beste seit geschnitten Brot für ca 17€. Schalten kann man das Ding per App, Cloud, Api, Web Interface (Wifi), Bluetooth und Analog Schalter. So kann ich den Pool nach wie vor am Schalter bewässern oder von China aus.
Bild aus Webinterface zeigt Schalter physikalisch und logisch
Wer per Software arbeiten will, Http Api, MQTT und zig anderes. Das ist ein Wundercomputer. Für mich wars zuerst die HTTP RPC APi
http://192.168.33.1/rpc/Switch.Set?id=0&on=true
Einfacher gehts nicht. Für das wollte ich einen Raspberry Pico W nehmen, der eigentlich so 7€ kosten soll und aktuell beim doppelten liegt Bestellt ist er sogar. Aber….
Die Bulgaren haben ihren Shelly ein Programmierinterface spendiert in einer Art mini JavaScript basierend auf mjs. Direkt auf dem Low Budget Device per Webbrowser ohne Debugger und dafür mit einer Output Console die man mit Print befüllt. So irgendwie C64 Programmierfeeling. Aber macht Spaß.
Die Shelly Entwicklungsumgebung
Jetzt wird es ein wenig sonderbar. Mit JavaScript hat das nur bedingt zu tun, so muss alles mit let initialisiert werden. Fehler meldet aber die Console. Auch den Auth Token habe ich vorbelegt weil mir die Api unbekannt. Folgender Code ruft alle 5 Sekunden, meinen Wandler auf, parst die aktuelle Leistung (watt) und schaltet das Relais (Switch.Set). Sonderbar auch wie man einen String zu int castet. Number ist nicht, *1 wirft Fehler. Json Parse tut.
1: print("start");
2: let Auth = {'Authorization': 'Basic xWrtaW56YWrtaW4='};
3: let DataURL = "http://10.0.0.22/status.html";
4: let CONFIG = {
5: toggleTimeout: 5,
6: inputId: 0,
7: switchId: 0,
8: };
9: let swParams = {
10: id: CONFIG.switchId,
11: on: true,
12: };
13:
14: function httpCall(){
15: Shelly.call("HTTP.Request",
16: { method: "GET", url: DataURL, headers: Auth },
17: function (res, error_code, error_msg, ud) {
18: if (!error_code) {
19: if (res.code === 200) {
20: let wert=extractWert(res.body);
21: if (wert>500)
22: {
23: Shelly.call("Switch.Set", swParams);
24: print("ON");
25: }
26: print(wert);
27: } else { print("HTTP Status code", res.code); }
28: } else { print("Error", error_code, error_msg); }
29: },
30: null
31: );
32: };
33:
34: function extractWert(body)
35: {
36: print(extractWert);
37: let startIndex = body.indexOf('var webdata_now_p = "')
+ 'var webdata_now_p = "'.length;
38: let endIndex = body.indexOf('";', startIndex);
39: let watt = body.slice(startIndex, endIndex);
40: print(watt);
41: return JSON.parse(watt);
42: }
43:
44: Timer.set(5000, true, httpCall, null);
45:
Das ist natürlich nicht das Ende meiner PV Pool Steuerung. So muss ich die Pumpe auch wieder abschalten, was kein technisches sondern logisches Problem ist. Irgendwie muss Mensch ja auch noch einen Override hinbekommen, wenn Katze oder Kleinkind im Skimmer hängen. Die Cloud Verbindung ist nur Komfort um den Status des Shelly Schalters remote prüfen zu können ohne eine Port Freigabe reverse zu legen. Cooles Gerät für die paar Euro.