SENEC Modul

Anfragen zum Erstellen von Modulen, Fragen zu Modulen
cjungde
Beiträge: 121
Registriert: Mo Jan 27, 2020 9:48 pm

SENEC Modul

Beitrag von cjungde »

Meldung vom 21.10.2024: Ich habe mein SENEC System durch ein anderes System ersetzt und habe daher keine Chance mehr, die Integration weiter zu entwickeln.
Ich bedanke mich für die tolle Zusammenarbeit !!


Hallo zusammen,

2023-02-13: BetaVersion SENEC Modul für die V2 Link

nachdem ich sehr viel in diesem Forum gelernt habe, möchte ich hier meine Lösung zur Diskussion stellen. Evtl. hilft es anderen auch ihre eigene Lösung zu bauen. Ich werde sicher aus Kommentaren lernen, diese Änderungen werde ich in diesem Post dann einarbeiten. Daher werden ggf. Kommentare etwas aus dem Kontext geraten.

Der Ausgangspunkt dieses Postes ist mein Setup zuhause:

Ich habe eine 9,9 kWp PV Anlage mit einem Fronius Wechselrichter.
Das System hat zudem noch eine 5 kWh SENEC Batterie vom Typ:Senec Home V2.1 1ph / Lithium
Der Speicher agiert in meinem System auch als Steuerung der Einspeisebegrenzung von 70%.
Um die Steuerung durchführen zu können, ist ein eigene Zähler über Modbus am Speicher angeschlossen, der direkt vor dem Zähler meines Netzbetreiber eingebaut ist.
Der Zähler des Netzbetreiber ist ein Echelon, der sich ohne Key meines Betreibers leider nicht direkt auslesen lässt.

In meinem Setup sind alle Daten im Speicher verfügbar: PV-Produktion, Speicher und alle EVU Daten. Zusätzlich sind auch Statistikdaten verfügbar.

Nun das Problem: SENEC unterstützt keine Opensource Lösung mit einer dokumentierten API. Alle Lösungen (OpenHab, FHEM, ...) sind durch motivierte Tüftler gebaut worden. Mit dieser Basis wird es zu SENEC kein offizielles Modul in OpenWB geben. (Meine Meinung) Mein ganzes Wissen für dieses Modul ist aus verschiedenen Posts zusammen getragen worden. In diesem Forum haben mir die Posts von Vize besonders geholfen. (Wie schonmal geschrieben: Danke !!)
Daher teile ich hier jetzt mein Setup und freue mich über jeden Verbesserungsvorschag der Experten. Ich bin kein Linux Experte, aber ich weiß mir zu helfen.

Da ich heute meine Hardware in Betrieb nehmen konnte dokumentiere ich hier jetzt den kompletten Ablauf:

Setup im Filesystem:

1. Als erstes habe ich mich in die UI eingeloggt und auf die aktuelle Nightly aktualisiert.

2. Dann habe ich per Terminal eine SSH Verbindung geöffnet

3. Wechsel ins Verzeichnis "cd /var/www/html/openWB/modules"

4. Anlegen des Verzeichnisses "mkdir _senec" - Das Verzeichnis wird beim Update von OpenWB nicht überschrieben.

5. Wechsel ins Verzeichnis "cd _senec"

6. Erstellen einer leeren Python datein "ls > senec.py" - Das geht sicher anders besser, reicht aber für mich.

7. starten des Editors "nano senec.py" und löschen des Inhaltes

8. Copy & paste des Scriptes weiter unten.

9. Speichern

10. Datei ausführbar machen "chmod -v 755 senec.py"

11. Datei ausführen als Test "./senec.py" als Ergebnis darf keine Fehlermeldung kommen, sonst hat es irgendein Problem gegeben.

12. Da dieses Script beim Aufruf jedesmal immer neue Werte in bestimmte Ramdisk Files schreibt, möchte ich, dass die Werte vor jedem Lesevorgang neu geschrieben werden. Das erreiche ich damit, dass ich in crontab alle OpenWB Zeilen durch mein Script erweitere: z.B.
"sleep 10 && /var/www/html/openWB/modules/_senec/senec.py && /var/www/html/openWB/regel.sh >> /var/log/openWB.log 2>&1 "

Dazu rufe ich in der Shell "crontab -e" auf und baue insgesamt 6 mal meine Scriptzeile mit ein.

Code: Alles auswählen

/var/www/html/openWB/modules/_senec/senec.py &&
(Tips für vi Anfänger wie mich: zuerst "i" tippen um in den Einfüge modus zu kommen. Alle Zeilen ändern. "ESC" drücken um aus dem Einfügemodus wieder heraus zu kommen. ":w!" tippen "Enter" zum Speichern, ":q!" tippen und "Enter" um vi zu verlassen.)

Setup in OpenWB:

Das Script schreibt die notwendigen Werte in eigene RamDisk files, die dann über die Http Konfiguration für EVU und Speicher in OpenWB eingelesen werden.

In der OpenWB Oberfläche gehe ich auf: Einstellungen > Einstellungen > Modulkonfiguration und wähle im Bereich "Strombezugsmessmodul (EVU-Übergabepunkt)" das Strombezugsmodul "HTTP" aus.
Um meine Konfigurationen nun einzulesen gebe ich nacheinander die Pfade zu meinen RamDisk Dateien ein:

Code: Alles auswählen

http://127.0.0.1/openWB/ramdisk/wattbezug_senec
http://127.0.0.1/openWB/ramdisk/bezugkwh_senec
http://127.0.0.1/openWB/ramdisk/einspeisungkwh_senec
http://127.0.0.1/openWB/ramdisk/bezuga1_senec
http://127.0.0.1/openWB/ramdisk/bezuga2_senec
http://127.0.0.1/openWB/ramdisk/bezuga3_senec
Im Bereich "Speicher-Modul" wähle ich "HTTP Abfrage" und trage nacheinander folgendes ein:

Code: Alles auswählen

http://127.0.0.1/openWB/ramdisk/speicherleistung_senec
http://127.0.0.1/openWB/ramdisk/speichersoc_senec
http://127.0.0.1/openWB/ramdisk/speicherikwh_senec
http://127.0.0.1/openWB/ramdisk/speicherekwh_senec
Im Bereich "PV" wähle ich "HTTP Abfrage" und trage nacheinander folgendes ein:

Code: Alles auswählen

http://127.0.0.1/openWB/ramdisk/pvwatt_senec
http://127.0.0.1/openWB/ramdisk/pvewh_senec
Dann natürlich jeweils speichern.

Hier ist mein Script (der Inhalt der Datei senec.py) zur Nutzung bitte die IP Adresse anpassen.

Der grundsätzliche Aufbau des Scriptes ist:
Ich hole mit über einen HTTP Request einen JSON String, den ich dann auslese. Die werte rechne ich das aus dem Hex Code in Dezimal um, formatiere sie und schreibe sie dann in ein RamDisk File. Das mache ich zweimal: einmal für die EVU Daten und einmal für die Speicherdaten.
Da manche Werte nicht in der Modulkonfiguration eingetragen werden können, schreibe ich die EVU Spannung, Leistung sowie die Frequenz direkt.

Code: Alles auswählen

#!/usr/bin/python

import struct
import json
import urllib2
import ssl
import time
import sys


ipaddress = "192.168.XXX.YYY"
debug = False


ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE

#ipaddress = str(sys.argv[1])


def myDecode(stringValue):
# Parameter: 
# stringValue:	String Wert, im Format Typ_Wert 
# 
# Rueckgabe:
# result: 		Floatzahl
    splitValue = stringValue.split('_')

    if splitValue[0] == 'fl':
        #Hex >> Float
        result = struct.unpack('f',struct.pack('I',int('0x'+splitValue[1],0)))[0]
    elif splitValue[0] == 'u3': 
        pass #TBD
    elif splitValue[0] == 'u8':
        pass #TBD
    
    return result

def writeVal(filePath,stringValue,multiplier,decimalpoints):

#Parameter
#filePath: 		Pfad und Dateiname in der ein Wert geschrieben wird
#stringValue: 	Wert der nach dem knonvertieren in die Datei geschrieben wird
#multiplier: 	Wert mit dem die Zahl vor der Rundung multipliziert wird
#decimalpoints:	Anzahl Kommastellen 
#
#Rueckgabe: nichts

    val= myDecode(stringValue)

	# Format anpassen
    if multiplier != 0:
        val = val * multiplier

    #auf 2 Ziffern runden
    if decimalpoints == 0:
        val = int(val)
    elif decimalpoints != 0:
        val = round(val,decimalpoints)

    if debug:
        print(filePath + ' ' + str(val))
    else:
        print(filePath + ' ' + str(val))
        f = open(filePath, 'w')
        f.write(str(val))
        f.close()

#EVU Daten
try:
    reqdata='{"PM1OBJ1":{"FREQ":"","U_AC":"","I_AC":"","P_AC":"","P_TOTAL":""}}'
    response = urllib2.urlopen('https://'+ ipaddress +'/lala.cgi' ,data=reqdata, context=ctx, timeout=2)
    jsondata = json.load(response)
except:
    sys.exit(1)

#keine Werte gefunden
# echo $evupf1 > /var/www/html/openWB/ramdisk/evupf1
# echo $evupf2 > /var/www/html/openWB/ramdisk/evupf2
# echo $evupf3 > /var/www/html/openWB/ramdisk/evupf3

#SENEC: Gesamtleistung (W) Werte -3000  >> 3000
if not (jsondata['PM1OBJ1'] ['P_TOTAL'] is None):
    writeVal('/var/www/html/openWB/ramdisk/wattbezug_senec', jsondata['PM1OBJ1'] ['P_TOTAL'],0,0)

#SENEC: Frequenz(Hz) Werte 49.00 >> 50.00
if not (jsondata['PM1OBJ1'] ['FREQ'] is None):
    writeVal('/var/www/html/openWB/ramdisk/evuhz',jsondata['PM1OBJ1'] ['FREQ'],0,0)

#SENEC: Spannung (V) Werte 219.12 >> 223.43
if not (jsondata['PM1OBJ1'] ['U_AC'] [0] is None):
    writeVal('/var/www/html/openWB/ramdisk/evuv1', jsondata['PM1OBJ1'] ['U_AC'] [0],0,0)
if not (jsondata['PM1OBJ1'] ['U_AC'] [1] is None):
    writeVal('/var/www/html/openWB/ramdisk/evuv2', jsondata['PM1OBJ1'] ['U_AC'] [1],0,0)
if not (jsondata['PM1OBJ1'] ['U_AC'] [2] is None):
    writeVal('/var/www/html/openWB/ramdisk/evuv3', jsondata['PM1OBJ1'] ['U_AC'] [2],0,0)

#SENEC: Leistung (W) Werte -2345 >> 3000
if not (jsondata['PM1OBJ1'] ['P_AC'] [0] is None):
    writeVal('/var/www/html/openWB/ramdisk/bezugw1', jsondata['PM1OBJ1'] ['P_AC'] [0],0,0)
if not (jsondata['PM1OBJ1'] ['P_AC'] [1] is None):
    writeVal('/var/www/html/openWB/ramdisk/bezugw2', jsondata['PM1OBJ1'] ['P_AC'] [1],0,0)
if not (jsondata['PM1OBJ1'] ['P_AC'] [2] is None):
    writeVal('/var/www/html/openWB/ramdisk/bezugw3', jsondata['PM1OBJ1'] ['P_AC'] [2],0,0)

#SENEC: Strom (A) Werte 0 >> 1 
if not (jsondata['PM1OBJ1'] ['I_AC'] [0] is None):
    writeVal('/var/www/html/openWB/ramdisk/bezuga1_senec', jsondata['PM1OBJ1'] ['I_AC'] [0],0,0)
if not (jsondata['PM1OBJ1'] ['I_AC'] [1] is None):    
    writeVal('/var/www/html/openWB/ramdisk/bezuga2_senec', jsondata['PM1OBJ1'] ['I_AC'] [1],0,0)
if not (jsondata['PM1OBJ1'] ['I_AC'] [2] is None):    
    writeVal('/var/www/html/openWB/ramdisk/bezuga3_senec', jsondata['PM1OBJ1'] ['I_AC'] [2],0,0)

#Batteriedaten:
try:
    reqdata='{"ENERGY":{"GUI_BAT_DATA_FUEL_CHARGE":"","GUI_BAT_DATA_POWER":"","GUI_BAT_DATA_VOLTAGE":"","GUI_INVERTER_POWER":""}}'
    response = urllib2.urlopen('https://'+ ipaddress +'/lala.cgi' ,data=reqdata, context=ctx,timeout=2)
    jsondata = json.load(response)
except:
    sys.exit(1)

#SENEC: Batterieleistung (W) Werte -345 (Entladen) >> 1200 (laden)
if not (jsondata['ENERGY'] ['GUI_BAT_DATA_POWER'] is None):
    writeVal('/var/www/html/openWB/ramdisk/speicherleistung_senec', jsondata['ENERGY'] ['GUI_BAT_DATA_POWER'],0,0)

#SENEC: Fuellmenge in Prozent Werte 10 >> 55 >> 100
if not (jsondata['ENERGY'] ['GUI_BAT_DATA_FUEL_CHARGE'] is None):
    writeVal('/var/www/html/openWB/ramdisk/speichersoc_senec', jsondata['ENERGY'] ['GUI_BAT_DATA_FUEL_CHARGE'],0,0)

#SENEC: Leistung Wechselrichter in (W) Werte 
if not (jsondata['ENERGY'] ['GUI_INVERTER_POWER'] is None):
    writeVal('/var/www/html/openWB/ramdisk/pvwatt_senec', jsondata['ENERGY'] ['GUI_INVERTER_POWER'],0,0)

Update 12.05.2024:
Ich habe um die HTTP Abfragen jetzt ein try ... except gesetzt, damit ein nicht antwortendes SENEC System nicht die OpenWB einfrieren lässt. (Danke an Newbe2020 für die Frage.)
Sollte nun innerhalb von 2 Sekunden keine Antwort kommen, wird die komplette Funktion einfach beendet, ohne den weiteren Code abzuarbeiten
Beispiel hier:

Code: Alles auswählen

try:
    reqdata='{"PM1OBJ1":{"FREQ":"","U_AC":"","I_AC":"","P_AC":"","P_TOTAL":""}}'
    response = urllib2.urlopen('https://'+ ipaddress +'/lala.cgi' ,data=reqdata, context=ctx, timeout=2)
    jsondata = json.load(response)
except:
    sys.exit(1)
Update 27.12.2021:
In einer der letzten Nightlys scheint es nochmal eine Änderung der HTTP Module gegeben zu haben.
Das 'localhost' muss jetzt durch '127.0.0.1' ersetzt werden. Daher müssen jetzt alle Module mit http://127.0.0.1/.... starten.

Update 02.10.2021:
Durch eine Änderungen im Weg wie die HTTP Module die Werte aus meinem Modul abrufen, ist es nun notwendig, dass das korrekte Protokoll in der OpenWB Konfiguration angegeben werden muss. Daher muss vor alle localhost/... ein 'http://' gesetzt werden. Ich habe die Anleitung oben entsprechend geändert. (Genaueres zum Grund: https://openwb.de/forum/viewtopic.php?f=9&t=4092)

Update 16.05.2021:
Auf zweifachen Wunsch habe ich nun auch die Daten des Wechselrichters aus der SENEC Batterie geladen.
Dafür bitte den Code der senec.py mit dem oben austauschen und die Konfiguration des PV Moduls auf HTTP einstellen.
fall jemand - wie ich selbst - von einem direkten PV Modul zu den ausgelesenen Daten aus der SENEC wechselt: der zweite Wert 'pvewh' wir auf jeden Fall unterschiedlich sein, da sie SENEC die Gesamt-PV Erzeugung selbst errechnet und nicht aus dem Wechselrichter lädt.


Update 26.07.2020:
Nachdem SENEC eine neue Firmware in die Speicher geschrieben hat war der Aufruf der Statistischen Daten nicht mehr möglich und das Script führte zu einem kompletten Hänger in der OpenWB. Das ist mit diesem Update behoben. Das Script lief jetzt eine Woche ohne Probleme bei mir.
Vielen Dank an vize und Topper für die Fehlersuche und Fehlerlösung.

Änderungen in diesem Update:
- Vor der Verarbeitung jedes Einzelwertes wird geprüft ob der Wert vorhanden ist, das sollte Hänger von OpenWB verhindern, wenn SENEC wieder etwas ändert.
- Die Werte für den Gesamtnetz- import und export wurden von ['STATISTIC'] ['STAT_GRID_IMPORT'] und ['STATISTIC'] ['STAT_GRID_EXPORT'] auf ['STATISTIC'] ['LIVE_GRID_IMPORT'] und ['STATISTIC'] ['LIVE_GRID_EXPORT'] geändert.
Zuletzt geändert von cjungde am Mo Okt 21, 2024 7:20 pm, insgesamt 10-mal geändert.
PV 22,3 kWp
Sigenergy 17kw WR
SigenStore 2x 8kWh
openWB series2 standard+
Auto: Zoe R110
Restliche Hausautomation: Home Assistant
aiole
Beiträge: 7747
Registriert: Mo Okt 08, 2018 4:51 pm
Has thanked: 18 times
Been thanked: 32 times

Re: Mein SENEC Modul

Beitrag von aiole »

Super Anleitung cjungde! Detailliert bis in die Haarspitzen und ich kann mir gut vorstellen, was das für eine Recherchearbeit war. Vielen Dank!
Da werden sich die Senec-user sehr, sehr freuen.
VG aiole
okaegi
Beiträge: 2382
Registriert: Fr Mär 08, 2019 1:57 pm
Has thanked: 1 time
Been thanked: 9 times

Re: Mein SENEC Modul

Beitrag von okaegi »

[quote=cjungde post_id=9274 time=1589311652 user_id

...
- Wo lege ich die Datei am besten ab?
- Muss ich es jetzt in Python 2 oder 3 schreiben ?
- ist es OK, manche Werte direkt zu schrieben ?
- könnte es evtl. einen Hook geben, damit ich mein Script nicht in crontab schreiben muss. Zusätzlich zu den HTTP Modulen könnte es auch jeweils einen Scriptaufruf geben.
[/quote]
Dateiablage und hook:
Ich steuere meine Wärmepumpe über openwb an. Dafür habe ich auf dem Raspi ein Verzeichnis angelegt
Schau mal hier:
viewtopic.php?f=6&t=607#p4148
Du kannst auch die generische ipadresse 127.0.0.1/...cust nehmen. Die bezieht sich auf den Raspi (localhost).Wenn du deinen Hook in Verbraucher 1 einbaust , wird dieser regelmässig (Regelintervall ) aufgerufen. Ich würde dann keine Wert zurückgeben und schauen was passiert und du must nichts mit crontab machen.
Tolle Arbeit !
Gruss Oliver
Entwickler- openWB (ehrenamtlich) / Feedback zu Funktionen immer erwünscht..
Smarthomeprobleme siehe hier (update :!: ): viewtopic.php?f=14&t=5923
andre
Beiträge: 76
Registriert: So Apr 26, 2020 5:57 am

Re: Mein SENEC Modul

Beitrag von andre »

Hi,

von mir auch vielen Dank für die ganze Infos!
Das hilft mir bei meinem zukünftigen Projekt (HyCube Modul) sicher weiter und gibt ein Einblick wie das System arbeitet.

Viele Grüsse
Andre
openWB
Site Admin
Beiträge: 8505
Registriert: So Okt 07, 2018 1:50 pm
Has thanked: 1 time
Been thanked: 29 times

Re: Mein SENEC Modul

Beitrag von openWB »

Super Anleitung!

Falls sich andere wundern warum das nicht übernommen wird, Senec möchte nicht unterstützt werden.
Wenn Nutzer sich das selbst programmieren liegt das natürlich nicht in unserer Hand ;)

Neulingen "vor Kauf" kann man Senec aufjedenfall nur abraten falls sie irgendeine form von Kompatibilität wollen.
Supportanfragen bitte NICHT per PN stellen.
Hardwareprobleme bitte über die Funktion Debug Daten senden mitteilen oder per Mail an support@openwb.de
Topper
Beiträge: 31
Registriert: Mi Sep 11, 2019 7:29 pm

Re: Mein SENEC Modul

Beitrag von Topper »

cjungde hat geschrieben: Di Mai 12, 2020 7:27 pm Hallo zusammen,

nachdem ich sehr viel in diesem Forum gelernt habe, möchte ich hier meine Lösung zur Diskussion stellen. Evtl. hilft es anderen auch ihre eigene Lösung zu bauen. Ich werde sicher aus Kommentaren lernen, diese Änderungen werde ich in diesem Post dann einarbeiten. Daher werden ggf. Kommentare etwas aus dem Kontext geraten.

Der Ausgangspunkt dieses Postes ist mein Setup zuhause:

Ich habe eine 9,9 kWp PV Anlage mit einem Fronius Wechselrichter.
Das System hat zudem noch eine 5 kWh SENEC Batterie vom Typ:Senec Home V2.1 1ph / Lithium
Der Speicher agiert in meinem System auch als Steuerung der Einspeisebegrenzung von 70%.
Um die Steuerung durchführen zu können, ist ein eigene Zähler über Modbus am Speicher angeschlossen, der direkt vor dem Zähler meines Netzbetreiber eingebaut ist.
Der Zähler des Netzbetreiber ist ein Echelon, der sich ohne Key meines Betreibers leider nicht direkt auslesen lässt.

In meinem Setup sind alle Daten im Speicher verfügbar: PV-Produktion, Speicher und alle EVU Daten. Zusätzlich sind auch Statistikdaten verfügbar.

Nun das Problem: SENEC unterstützt keine Opensource Lösung mit einer dokumentierten API. Alle Lösungen (OpenHab, FHEM, ...) sind durch motivierte Tüftler gebaut worden. Mit dieser Basis wird es zu SENEC kein offizielles Modul in OpenWB geben. (Meine Meinung) Mein ganzes Wissen für dieses Modul ist aus verschiedenen Posts zusammen getragen worden. In diesem Forum haben mir die Posts von Vize besonders geholfen. (Wie schonmal geschrieben: Danke !!)
Daher teile ich hier jetzt mein Setup und freue mich über jeden Verbesserungsvorschag der Experten. Ich bin kein Linux Experte, aber ich weiß mir zu helfen.

Da ich heute meine Hardware in Betrieb nehmen konnte dokumentiere ich hier jetzt den kompletten Ablauf:

Setup im Filesystem:

1. Als erstes habe ich mich in die UI eingeloggt und auf die aktuelle Nightly aktualisiert.

2. Dann habe ich per Terminal eine SSH Verbindung geöffnet

3. Wechsel ins Verzeichnis "cd /var/www/html/openwb/modules"

4. Anlegen des Verzeichnisses "mkdir _senec" - Das Verzeichnis wird beim Update von OpenWB nicht überschrieben.

5. Wechsel ins Verzeichnis "cd _senec"

6. Erstellen einer leeren Python datein "ls > senec.py" - Das geht sicher anders besser, reicht aber für mich.

7. starten des Editors "nano senec.py" und löschen des Inhaltes

8. Copy & paste des Scriptes weiter unten.

9. Speichern

10. Datei ausführbar machen "chmod -v 755 senec.py"

11. Datei ausführen als Test "./senec.py" als Ergebnis darf keine Fehlermeldung kommen, sonst hat es irgendein Problem gegeben.

12. Da dieses Script beim Aufruf jedesmal immer neue Werte in bestimmte Ramdisk Files schreibt, möchte ich, dass die Werte vor jedem Lesevorgang neu geschrieben werden. Das erreiche ich damit, dass ich in crontab alle OpenWB Zeilen durch mein Script erweitere: z.B.
"sleep 10 && /var/www/html/openWB/modules/_senec/senec.py && /var/www/html/openWB/regel.sh >> /var/log/openWB.log 2>&1 "

Dazu rufe ich in der Shell "crontab -e" auf und baue insgesamt 6 mal meine Scriptzeile mit ein.

Code: Alles auswählen

/var/www/html/openWB/modules/_senec/senec.py &&
(Tips für vi Anfänger wie mich: zuerst "i" tippen um in den Einfüge modus zu kommen. Alle Zeilen ändern. "ESC" drücken um aus dem Einfügemodus wieder heraus zu kommen. ":w!" tippen "Enter" zum Speichern, ":q!" tippen und "Enter" um vi zu verlassen.)

Setup in OpenWB:

Das Script schreibt die notwendigen Werte in eigene RamDisk files, die dann über die Http Konfiguration für EVU und Speicher in OpenWB eingelesen werden.

In der OpenWB Oberfläche gehe ich auf: Einstellungen > Einstellungen > Modulkonfiguration und wähle im Bereich "Strombezugsmessmodul (EVU-Übergabepunkt)" das Strombezugsmodul "HTTP" aus.
Um meine Konfigurationen nun einzulesen gebe ich nacheinander die Pfade zu meinen RamDisk Dateien ein:

Code: Alles auswählen

localhost/openWB/ramdisk/wattbezug_senec
localhost/openWB/ramdisk/bezugkwh_senec
localhost/openWB/ramdisk/einspeisungkwh_senec
localhost/openWB/ramdisk/bezuga1_senec
localhost/openWB/ramdisk/bezuga2_senec
localhost/openWB/ramdisk/bezuga3_senec
Im Bereich "Speicher-Modul" wähle ich "HTTP Abfrage" und trage nacheinander folgendes ein:

Code: Alles auswählen

localhost/openWB/ramdisk/speicherleistung_senec
localhost/openWB/ramdisk/speichersoc_senec
localhost/openWB/ramdisk/speicherikwh_senec
localhost/openWB/ramdisk/speicherekwh_senec
Dann natürlich speichern.

Hier ist mein Script (der Inhalt der Datei senec.py) zur Nutzung bitte die IP Adresse anpassen.

Der grundsätzliche Aufbau des Scriptes ist:
Ich hole mit über einen HTTP Request einen JSON String, den ich dann auslese. Die werte rechne ich das aus dem Hex Code in Dezimal um, formatiere sie und schreibe sie dann in ein RamDisk File. Das mache ich zweimal: einmal für die EVU Daten und einmal für die Speicherdaten.
Da manche Werte nicht in der Modulkonfiguration eingetragen werden können, schreibe ich die EVU Spannung, Leistung sowie die Frequenz direkt.

Code: Alles auswählen

#!/usr/bin/python

import struct
import json
import urllib2
import time


ipaddress = "192.168.XXX.XXX"
debug = False

#ipaddress = str(sys.argv[1])


def myDecode(stringValue):
# Parameter: 
# stringValue:	String Wert, im Format Typ_Wert 
# 
# Rueckgabe:
# result: 		Floatzahl
    splitValue = stringValue.split('_')

    if splitValue[0] == 'fl':
        #Hex >> Float
        result = struct.unpack('f',struct.pack('I',int('0x'+splitValue[1],0)))[0]
    elif splitValue[0] == 'u3': 
        pass #TBD
    elif splitValue[0] == 'u8':
        pass #TBD
    
    return result

def writeVal(filePath,stringValue,multiplier,decimalpoints):

#Parameter
#filePath: 		Pfad und Dateiname in der ein Wert geschrieben wird
#stringValue: 	Wert der nach dem konvertieren in die Datei geschrieben wird
#multiplier: 	Wert mit dem die Zahl vor der Rundung multipliziert wird
#decimalpoints:	Anzahl Kommastellen 
#
#Rueckgabe: nichts

    val= myDecode(stringValue)

	# Format anpassen
    if multiplier != 0:
        val = val * multiplier

    #auf 2 Ziffern runden
    if decimalpoints == 0:
        val = int(val)
    elif decimalpoints != 0:
        val = round(val,decimalpoints)

    if debug:
        print(str(val))
        print filePath
    else:
        f = open(filePath, 'w')
        f.write(str(val))
        f.close()

#EVU Daten
reqdata='{"PM1OBJ1":{"FREQ":"","U_AC":"","I_AC":"","P_AC":"","P_TOTAL":""}}'
response = urllib2.urlopen('http://'+ ipaddress +'/lala.cgi' ,data=reqdata)
jsondata = json.load(response)
#keine Werte gefunden
# echo $evupf1 > /var/www/html/openWB/ramdisk/evupf1
# echo $evupf2 > /var/www/html/openWB/ramdisk/evupf2
# echo $evupf3 > /var/www/html/openWB/ramdisk/evupf3

#SENEC: Gesamtleistung (W) Werte -3000  >> 3000
writeVal('/var/www/html/openWB/ramdisk/wattbezug_senec', jsondata['PM1OBJ1'] ['P_TOTAL'],0,0)

#SENEC: Frequenz(Hz) Werte 49.12 >> 50.34
writeVal('/var/www/html/openWB/ramdisk/evuhz',jsondata['PM1OBJ1'] ['FREQ'],0,2)

#SENEC: Spannung (V) Werte 219.12 >> 223.43
writeVal('/var/www/html/openWB/ramdisk/evuv1', jsondata['PM1OBJ1'] ['U_AC'] [0],0,2)
writeVal('/var/www/html/openWB/ramdisk/evuv2', jsondata['PM1OBJ1'] ['U_AC'] [1],0,2)
writeVal('/var/www/html/openWB/ramdisk/evuv3', jsondata['PM1OBJ1'] ['U_AC'] [2],0,2)

#SENEC: Leistung (W) Werte -2345 >> 3000
writeVal('/var/www/html/openWB/ramdisk/bezugw1', jsondata['PM1OBJ1'] ['P_AC'] [0],0,0)
writeVal('/var/www/html/openWB/ramdisk/bezugw2', jsondata['PM1OBJ1'] ['P_AC'] [1],0,0)
writeVal('/var/www/html/openWB/ramdisk/bezugw3', jsondata['PM1OBJ1'] ['P_AC'] [2],0,0)

#SENEC: Strom (A) Werte 0.88 >> 1.67 
writeVal('/var/www/html/openWB/ramdisk/bezuga1_senec', jsondata['PM1OBJ1'] ['I_AC'] [0],0,2)
writeVal('/var/www/html/openWB/ramdisk/bezuga2_senec', jsondata['PM1OBJ1'] ['I_AC'] [1],0,2)
writeVal('/var/www/html/openWB/ramdisk/bezuga3_senec', jsondata['PM1OBJ1'] ['I_AC'] [2],0,2)

#Batteriedaten:
reqdata='{"ENERGY":{"GUI_BAT_DATA_FUEL_CHARGE":"","GUI_BAT_DATA_POWER":"","GUI_BAT_DATA_VOLTAGE":"","GUI_BAT_DATA_OA_CHARGING":""}}'
response = urllib2.urlopen('http://'+ ipaddress +'/lala.cgi' ,data=reqdata)
jsondata = json.load(response)

#SENEC: Batterieleistung (W) Werte -345 (Entladen) >> 1200 (laden)
writeVal('/var/www/html/openWB/ramdisk/speicherleistung_senec', jsondata['ENERGY'] ['GUI_BAT_DATA_POWER'],0,0)

#SENEC: Fuellmenge in Prozent Werte 10 >> 55 >> 100
writeVal('/var/www/html/openWB/ramdisk/speichersoc_senec', jsondata['ENERGY'] ['GUI_BAT_DATA_FUEL_CHARGE'],0,0)

#Statistik
reqdata='{"STATISTIC":{"STAT_BAT_CHARGE":"","STAT_BAT_DISCHARGE":"","STAT_GRID_EXPORT":"","STAT_GRID_IMPORT":"","STAT_HOUSE_CONSUMPTION":"","STAT_PV_GENERATION":""}}'
response = urllib2.urlopen('http://'+ ipaddress +'/lala.cgi' ,data=reqdata)
jsondata = json.load(response)

#SENEC: Gesamtlademenge (Wh) Werte 1692
writeVal('/var/www/html/openWB/ramdisk/speicherikwh_senec', jsondata['STATISTIC'] ['STAT_BAT_CHARGE'],1000,0)

#SENEC: Gesamtentlademenge (Wh) Werte 1590
writeVal('/var/www/html/openWB/ramdisk/speicherekwh_senec', jsondata['STATISTIC'] ['STAT_BAT_DISCHARGE'],1000,0)

#SENEC: Gesamtimport (Wh) Werte 1809000
writeVal('/var/www/html/openWB/ramdisk/bezugkwh_senec', jsondata['STATISTIC'] ['STAT_GRID_IMPORT'],1000,0)

#SENEC: Gesamteinspeisung Werte (Wh) 7085000
writeVal('/var/www/html/openWB/ramdisk/einspeisungkwh_senec', jsondata['STATISTIC'] ['STAT_GRID_EXPORT'],1000,0)
Fragen die mir beim schreiben gekommen sind:
- Wo lege ich die Datei am besten ab?
- Muss ich es jetzt in Python 2 oder 3 schreiben ?
- ist es OK, manche Werte direkt zu schrieben ?
- könnte es evtl. einen Hook geben, damit ich mein Script nicht in crontab schreiben muss. Zusätzlich zu den HTTP Modulen könnte es auch jeweils einen Scriptaufruf geben.
WOW
eine sehr geile Anleitung dafür schonmal ein fettes Danke.

Ich habe auch tatsächlich das meiste hin bekommen.

allerdings scheint bei mir es mit den Werten noch ein wneig zu hängen.

Ich habe eine Senec V2 7,5 kwh Lithium mit 2 Enfluis der misst darüber was rein und raus geht aus dem Haus.

Auf dem OpenWb sieht es wie Folgt aus:
openwb1.JPG
bei PV kommt nichts und bei Hausverbrauch auch nicht das was er ins netzt einspeist ist richtig und entspricht der Differenz zwischen Hausverrbauch und PV Erzeugung

Schalte ich einen Verbraucher von 2 KW an gescheit folgendes:
openwb2.JPG
der Hausverbrauch und Speicherleistung erscheint allerdings um die Differenz der PV leistung reduziert.


Hier benötige ich glaube ich mal einen Denkanstoß oder einfach HILFEEEE :-)

Beste Grüße Topper
cjungde
Beiträge: 121
Registriert: Mo Jan 27, 2020 9:48 pm

Re: Mein SENEC Modul

Beitrag von cjungde »

Hi Topper,

schön wenn ich Dir den Start erleichtern konnte.
Anhand der Screenshots kann man schonmal sehen, das das Script ausgeführt wird: Sehr gut.

Eigentlich passt alles. Das einzige was fehlt, ist die Einrichtung der PV Anlage. Die Daten bekomme ich bei mir durch einen Fronus Wechselrichter, den ich in einer weiteren Konfig eingerichtet habe.

Schau mal nach was Du in OpenWB unter Einstellungen > Einstellungen > Modulkonfiguration > PV-Modul stehen hast (oder haben solltest)

Viele Grüße
Christoph
PV 22,3 kWp
Sigenergy 17kw WR
SigenStore 2x 8kWh
openWB series2 standard+
Auto: Zoe R110
Restliche Hausautomation: Home Assistant
Topper
Beiträge: 31
Registriert: Mi Sep 11, 2019 7:29 pm

Re: Mein SENEC Modul

Beitrag von Topper »

Hi Christoph

ja ich habe es herausgefunden ich musste in deinem Script die Quelle des zweiten Enflui nutzen ( PM1OBJ2) als Quelle.

bei PV Einstellungen habe ich nun über die Modbus Schnittstelle meine SMA Tripowers eine Verbindung hin bekommen bin gespannt ob morgen bei Sonne alles richtig angezeigt wird aber ich bin zuversichtlich :-)

Du hast da echt nen super Job gemacht hatte mich vor einem halben Jahr schon mal daran versucht über Umwege die Daten aus dem Senec zu bekommen aber deine Lösung ist mega :-)

Ich halte dich auf dem Laufenden

Gruß Topper
cjungde
Beiträge: 121
Registriert: Mo Jan 27, 2020 9:48 pm

Re: Mein SENEC Modul

Beitrag von cjungde »

Sehr gut, danke für die Rückmeldung.
Den Job hab ich zum Glück nicht alleine machen müssen.
Ich habe nur gesammelt :-)

Poste doch den Codeteil mit dem Du den zweiten EinFluRi eingebunden hast. Das wird anderen sicher weiterhelfen.

Viel Erfolg weiterhin
Christoph
PV 22,3 kWp
Sigenergy 17kw WR
SigenStore 2x 8kWh
openWB series2 standard+
Auto: Zoe R110
Restliche Hausautomation: Home Assistant
cjungde
Beiträge: 121
Registriert: Mo Jan 27, 2020 9:48 pm

Re: Mein SENEC Modul

Beitrag von cjungde »

Senec hat offensichtlich die Schnittstelle angepasst.
Ich kann es mir leider erst nach dem 15.07. wieder anschauen.

Gruß Christoph
PV 22,3 kWp
Sigenergy 17kw WR
SigenStore 2x 8kWh
openWB series2 standard+
Auto: Zoe R110
Restliche Hausautomation: Home Assistant
Antworten