E3/DC Hauskraftwerk - Modbus Schnittstelle

Hallo,

ich schaue mir gerade die Demoversion von IP-Symcon an und beisse mir die Zähne an der Modbus-Schnittstelle aus.
Es sollen die Werte aus einem E3/DC Hauskraftwerk (Solar-Wechselrichter mit Batteriespeicher) ausgelesen werden.
In ioBroker funktioniert das einwandfrei, in IP-Symcon kriege ich das nicht hin.
Beispielhaft sind 3 Werte eingerichtet, siehe auch in den Bilder weiter unten.
Es kommen auch Werte an, allerdings sind die Werte falsch.

Die Einstellmöglichkeiten, die geboten werden, hab ich jetzt alle durchprobiert.

So sieht das Ganze im ioBroker aus:

Hat jemand eine Idee ob man das in IP-Symcon ohne Programmierung hinbekommt?

ModBus-Dokumentation_2017-04-10.pdf (521 KB)

Hi,

in der Spliter Instanz von deinem ModBus Gerät Swap LSW/MSW for 32bit/64bit values Aktiviert?
modbus.PNG

Teste mal :slight_smile:

Gruß

„in der Spliter Instanz von deinem ModBus Gerät Swap LSW/MSW for 32bit/64bit values Aktiviert?“

Das hatte ich gestern einige male probiert, hatte aber kein Änderung gebracht.
Heute, nach erneutem Test werden , wie durch Wunderhand, auf einmal die Werte für ein Register richtig dargestellt, nachdem ich die Option deaktiviert habe :). Es wird auch brav die Werte jede Sekunde aktualisiert, danke.

das nächste Problem ist jetzt das von 3 konfigurierten Werten (Registern) nur eines aktualisiert wird und zwar ‚40072_Hausverbrauch_Leistung‘.

Die beiden anderen Instanzen haben immer den Wert 0 und aktualisieren sich auch nicht. Die Konfiguration der Instanzen ist genau gleich, bis auf die Modbus Adresse. :confused:

modbus_IPS_ob.PNG

Inzwischen bin ich schon ein Stück weitergekommen.
Wenns fertig ist melde ich mich hier nochmal.

Hallo,

bedenke die angegebenen Register stimmen nicht
Photovoltaik-Leistung in Watt => 40067
Batterie-Leistung in Watt => 40069

probiere das mal:)

„bedenke die angegebenen Register stimmen nicht
Photovoltaik-Leistung in Watt => 40067
Batterie-Leistung in Watt => 40069“

Danke für den Hinweis.
Das habe ich in mühevoller Trial and Test Manier schon herausgefunden.

Dazu kommt noch das die Werte teilweise z.B. 65535 statt 0 sind und ich die mit einem Script umrechnen muß.
Das hat wohl mit dem „unsigned“ zu tun.

E3/DC verwendet für manche Register den Typ ‚UInt8+UInt8‘.
Das kann man auch nur mit einem Script lösen.

so, in der Zwischenzeit habe ich eine Lösung gefunden.
Dabei wird phpmodbus verwendet, das man sich vorher herunterladen muß und auf den Server kopiert werden muß. -> GitHub - krakorj/phpmodbus: Modbus library for PHP (Google code follower)

Mit der in Symcon integrierten Modbus Funktion oder Modul habe ich das nicht hinbekommen.

Das Ganze ist noch nicht ganz fertig, sieht aber für mich schon ganz gut aus.

Wenn ich mal Zeit und Lust habe mache ich daraus evtl. ein eigenes Modul.

In den Skripten muss man noch jeweils die richtige IP-Adresse eintragen.

Mein Script zum Erstellen von Variablen, das nur einmal ausgeführt werden muss:

<?

// Prüfen ob Variablen schon vorhanden sind, ansonsten anlegen (im Ordner des Skripts):
function CreateVariable($VarName, $Type, $ParentID){
	$ID_Variable = @IPS_GetVariableIDByName($VarName, $ParentID );
	if ($ID_Variable === false) {
		$ID_Variable = IPS_CreateVariable($Type);
		IPS_SetName($ID_Variable, $VarName); // Variable benennen
		IPS_SetParent($ID_Variable, $ParentID); // Variable einsortieren unter dem Objekt mit der ID $ParentID
	}
	return $ID_Variable;
}



$ParentID = IPS_GetParent($_IPS['SELF']);

$ID_PV_Leistung				= CreateVariable("Solar Produktion", 1, $ParentID);
$ID_Batterie_Leistung		= CreateVariable("Batterie Leistung", 1, $ParentID);
$ID_Hausverbrauchs_Leistung	= CreateVariable("Hausverbrauch", 1, $ParentID);
$ID_Netz_Leistung			= CreateVariable("Netz Leistung", 1, $ParentID);
$ID_Batterie_SoC			= CreateVariable("Batterie Status", 1, $ParentID);
$ID_Autarkie_Eigenverbrauch	= CreateVariable("Autarkie_Eigenverbrauch", 1, $ParentID);
$ID_Autarkie				= CreateVariable("Autarkie", 1, $ParentID);
$ID_Eigenverbrauch			= CreateVariable("Eigenverbrauch", 1, $ParentID);

//Tagesproduktionen berechnen:
$ID_PV_Tages_Solarproduktion		= CreateVariable("Tages Solarproduktion", 2, $ParentID); // hier wird die Solarproduktion pro Tag kontinuierlich hochgezählt.
$ID_Tages_Hausverbrauch				= CreateVariable("Tages Hausverbrauch", 2, $ParentID); // hier wird die Hausverbrauch pro Tag kontinuierlich hochgezählt.

$ID_Tages_Netzeinspeisung			= CreateVariable("Tages Netzeinspeisung", 2, $ParentID); // hier wird die Netzeinspeisung pro Tag kontinuierlich hochgezählt.
$ID_Tages_Netzbezug					= CreateVariable("Tages Netzbezug", 2, $ParentID); // hier wird die Netzbezug pro Tag kontinuierlich hochgezählt.
$ID_Tages_Batterieladen				= CreateVariable("Tages Batterieladen", 2, $ParentID); // hier wird die Baterrieladung pro Tag kontinuierlich hochgezählt.
$ID_Tages_Batterieentladen			= CreateVariable("Tages Batterieentladen", 2, $ParentID); // hier wird die Batterieentladung pro Tag kontinuierlich hochgezählt.


//$ID_PV_Solarproduktion_Tageswerte 	= CreateVariable("E3DC_PV_Solarproduktion_Tageswerte", 2, $ParentID); // Wert wird einmal pro Tag gespeichert!

$ID_tmp_logging = CreateVariable("E3DC_tmp_logging", 3, $ParentID);

?>

Und hier das Skript für die Leistungsdaten, das bei mir einmal pro Sekunde ausgeführt wird:

<?php
// Modul Phpmodbus ins Skript Verzeichnis kopieren (bei Ubuntu /var/lib/symcon/scripts/); https://github.com/krakorj/phpmodbus

// Beginn Konfiguration:
require_once dirname(__FILE__) . '/_OwnLibraries/Phpmodbus_0.8.r106/Phpmodbus/ModbusMaster.php'; 
$ipaddress_E3DC = "192.168.178.31"; // IP-Adresse des E3/DC Geräts.
// Ende Konfiguration, ab hier nichts mehr ändern


// Variablen nur speichern wenn sich der Wert geändert hat:
function SetVariable($var2set, $value) {
	if (GetValue($var2set) != $value)
		SetValue($var2set, $value);
}


function logTageswerteZaehler($value, $var2set) {	
	if ($value > 0) {
		$Energie_letzer_Wert = GetValue($var2set);
		$temp = $value/3600000;
	
		$temp2 = $Energie_letzer_Wert + $temp;
		//SetValue(27764, '$temp :' . $temp . '|$temp2:' . $temp2 . '|$letzterWert:' . $Energie_letzer_Wert);
		SetValue($var2set , $temp2);
	}
}
 
// Create Modbus object
$modbus = new ModbusMaster($ipaddress_E3DC, "TCP");
 
try {
    $PV_Leistung 				= $modbus->readMultipleRegisters(0, 40067, 2);
	$Batterie_Leistung 			= $modbus->readMultipleRegisters(0, 40069, 2);
	$Hausverbrauchs_Leistung 	= $modbus->readMultipleRegisters(0, 40071, 2);
	$Netz_Leistung 				= $modbus->readMultipleRegisters(0, 40073, 2);	
	$Batterie_Status			= $modbus->readMultipleRegisters(0, 40082, 1);	
	$Autarkie_Eigenverbrauch 	= $modbus->readMultipleRegisters(0, 40081, 1);
}
catch (Exception $e) {
    // Print error information if any
    echo $modbus;
    echo $e;
    exit;
}

$ParentID = IPS_GetParent($_IPS['SELF']);


$ID_PV_Leistung 			= IPS_GetVariableIDByName("Solar Produktion", $ParentID);
$ID_Batterie_Leistung 		= IPS_GetVariableIDByName("Batterie Leistung", $ParentID);
$ID_Hausverbrauchs_Leistung = IPS_GetVariableIDByName("Hausverbrauch", $ParentID);
$ID_Netz_Leistung 			= IPS_GetVariableIDByName("Netz Leistung", $ParentID);
$ID_Batterie_Status			= IPS_GetVariableIDByName("Batterie Status", $ParentID);
$ID_Autarkie_Eigenverbrauch = IPS_GetVariableIDByName("Autarkie_Eigenverbrauch", $ParentID);
$ID_Autarkie 				= IPS_GetVariableIDByName("Autarkie", $ParentID);
$ID_Eigenverbrauch 			= IPS_GetVariableIDByName("Eigenverbrauch", $ParentID);


$ID_Tages_Solarproduktion 		= IPS_GetVariableIDByName("Tages Solarproduktion", $ParentID);
$ID_Tages_Hausverbrauch 		= IPS_GetVariableIDByName("Tages Hausverbrauch", $ParentID);


$PV_Leistung_aktuell 				= PhpType::bytes2signedInt($PV_Leistung);
$Batterie_Leistung_aktuell 			= PhpType::bytes2signedInt($Batterie_Leistung);
$Hausverbrauchs_Leistung_aktuell 	= PhpType::bytes2signedInt($Hausverbrauchs_Leistung);
$Netz_Leistung_aktuell				= PhpType::bytes2signedInt($Netz_Leistung);
$Batterie_Status_aktuell			= PhpType::bytes2signedInt($Batterie_Status);

logTageswerteZaehler($PV_Leistung_aktuell, $ID_Tages_Solarproduktion );
logTageswerteZaehler($Hausverbrauchs_Leistung_aktuell , $ID_Tages_Hausverbrauch );


$ID_Tages_Netzeinspeisung			= IPS_GetVariableIDByName("Tages Netzeinspeisung", $ParentID);
$ID_Tages_Netzbezug					= IPS_GetVariableIDByName("Tages Netzbezug", $ParentID);
if ($Netz_Leistung_aktuell > 0){
	logTageswerteZaehler($Netz_Leistung_aktuell, $ID_Tages_Netzbezug);
}

if ($Netz_Leistung_aktuell < 0){
	//SetValue(53391 /*[E3DC_Modbus_TCP\E3DC_tmp_logging]*/, "Wert:".abs($Netz_Leistung_aktuell)."|ID".$ID_Tages_Netzeinspeisung);
	logTageswerteZaehler(abs($Netz_Leistung_aktuell), $ID_Tages_Netzeinspeisung);
}

$ID_Tages_Batterieladen				= IPS_GetVariableIDByName("Tages Batterieladen", $ParentID);
$ID_Tages_Batterieentladen			= IPS_GetVariableIDByName("Tages Batterieentladen", $ParentID);
if ($Batterie_Leistung_aktuell > 0){	
	logTageswerteZaehler($Batterie_Leistung_aktuell, $ID_Tages_Batterieladen);
}

if ($Batterie_Leistung_aktuell < 0){
	logTageswerteZaehler(abs($Batterie_Leistung_aktuell), $ID_Tages_Batterieentladen);
}






SetVariable($ID_PV_Leistung, $PV_Leistung_aktuell ); 
SetVariable($ID_Batterie_Leistung, $Batterie_Leistung_aktuell ); 
SetVariable($ID_Hausverbrauchs_Leistung, $Hausverbrauchs_Leistung_aktuell ); 
SetVariable($ID_Netz_Leistung, $Netz_Leistung_aktuell ); 
SetVariable($ID_Batterie_Status, $Batterie_Status_aktuell	 ); 


$temp = PhpType::bytes2signedInt($Autarkie_Eigenverbrauch);
SetVariable($ID_Autarkie_Eigenverbrauch, $temp ); 
SetVariable($ID_Autarkie, ($temp >> 8 ) & 0xFF );
SetVariable($ID_Eigenverbrauch, $temp & 0xFF );

Ein Skript um statische Information abzuholen, z.B. Hersteller, Seriennummer, Firmware:

<?php
// Beginn Konfiguration:

// Modul Phpmodbus ins Skript Verzeichnis kopieren (bei Ubuntu /var/lib/symcon/scripts/); https://github.com/krakorj/phpmodbus
require_once dirname(__FILE__) . '/_OwnLibraries/Phpmodbus_0.8.r106/Phpmodbus/ModbusMaster.php'; 
$ipaddress_E3DC = "192.168.178.31"; // IP-Adresse des E3/DC Geräts.
// Ende Konfiguration, ab hier nichts mehr ändern


// Prüfen ob Variablen schon vorhanden sind, ansonsten anlegen (im Ordner des Skripts):
function CreateVariable($VarName, $Type, $ParentID){
	$ID_Variable = @IPS_GetVariableIDByName($VarName, $ParentID );
	if ($ID_Variable === false) {
		$ID_Variable = IPS_CreateVariable($Type);
		IPS_SetName($ID_Variable, $VarName); // Variable benennen
		IPS_SetParent($ID_Variable, $ParentID); // Variable einsortieren unter dem Objekt mit der ID $ParentID
	}
	return $ID_Variable;
}

function ConvertArray2String($array) {
	$string = "";
	foreach ($array as $chr) {
    	$string .= chr($chr);
	}
	return $string;
}

$ParentID = IPS_GetParent($_IPS['SELF']);

$ID_Hersteller 				= CreateVariable("Hersteller", 3, $ParentID);
$ID_Modell 					= CreateVariable("Modell", 3, $ParentID);
$ID_Seriennummer 			= CreateVariable("Seriennummer", 3, $ParentID);
$ID_S10_Firmware_Release 	= CreateVariable("S10_Firmware_Release", 3, $ParentID);

 
// Create Modbus object
$modbus = new ModbusMaster($ipaddress_E3DC, "TCP");
 
try {
    $Hersteller 			= $modbus->readMultipleRegisters(0, 40003, 8);
	$Modell		 			= $modbus->readMultipleRegisters(0, 40019, 8);
	$Seriennummer 			= $modbus->readMultipleRegisters(0, 40035, 8);
	$S10_Firmware_Release 	= $modbus->readMultipleRegisters(0, 40051, 8);
}
catch (Exception $e) {
    // Print error information if any
    echo $modbus;
    echo $e;
    exit;
}

SetValue($ID_Hersteller, 			ConvertArray2String($Hersteller));
SetValue($ID_Modell, 				ConvertArray2String($Modell));
SetValue($ID_Seriennummer, 			ConvertArray2String($Seriennummer));
SetValue($ID_S10_Firmware_Release, 	ConvertArray2String($S10_Firmware_Release));

Zum Schluss ein Skript zum zurücksetzen der Tageswerte (Tageszähler):

<?
$ParentID = IPS_GetParent($_IPS['SELF']);

$ID_Tages_Solarproduktion 		= IPS_GetVariableIDByName("Tages Solarproduktion", $ParentID);
$ID_Tages_Hausverbrauch 		= IPS_GetVariableIDByName("Tages Hausverbrauch", $ParentID);
$ID_Tages_Netzeinspeisung		= IPS_GetVariableIDByName("Tages Netzeinspeisung", $ParentID);
$ID_Tages_Netzbezug				= IPS_GetVariableIDByName("Tages Netzbezug", $ParentID);
$ID_Tages_Batterieladen			= IPS_GetVariableIDByName("Tages Batterieladen", $ParentID);
$ID_Tages_Batterieentladen		= IPS_GetVariableIDByName("Tages Batterieentladen", $ParentID);

setValue($ID_Tages_Solarproduktion, 0);
setValue($ID_Tages_Hausverbrauch, 0);
setValue($ID_Tages_Netzeinspeisung, 0);
setValue($ID_Tages_Netzbezug, 0);
setValue($ID_Tages_Batterieladen, 0);
setValue($ID_Tages_Batterieentladen, 0);

?>

Und so sieht das im Frontend aus:

Moin,

die Lösung sieht sauber aus! Überlegen auch grad PV zu installieren mit nem Speicher,
da schaue ich auch in die Richtung des E3/DC.

Funktioniert alles immer noch tadellos über IPS?

Gruß

Servus,
ja, es funktioniert nach wie vor tadellos.
IP-Symcon läuft bei mir auf einem Beelink BT3 PRO II Intel Atom X5-Z8350 4GB/64GB Mini PC.

E3/DC ist teurer als andere, aber dafür hat man ein Rundum-Sorglospaket, das einfach funktioniert.

Hi,

ich habe auch mein E3DC mit Symcon verbunden. Aktuell läuft das bei mir jedoch über das KNX Modul von E3DC und funktioniert soweit auch gut. Leider fehlt mit aber eine wichtige Konfigurationsmöglichkeit. Und zwar habe ich über das KNX Modul keinen Zugriff auf die Optionen der Ladepriorisierung im Bezug auf die Wallbox:

[ol]
[li]Wallbox priorisiert
[/li][li]Batterieentladung durch Wallbox
[/li][/ol]
Dies ist für mich aber wichtig, da ich so die Ladung des Autos deutlich optimieren könnte (aktuell mache ich dass immer von Hand).
Daher meine Frage an Euch, kann man diese Option per ModBus mit Symcon beeinflussen?

Grüße vom Bodensee

Manuel

Du sprichst von der Wallbox von E3/DC?

Wenn ja, kann ich dazu nichts sagen, ich habe den go-eCharger HOME+, damit hat man alle Freiheiten.

Die E3/DC Wallbox war mit zu teuer.

Die Batterieentladung beim Laden vom E-Auto zu verhindern wäre mir auch sehr recht, dazu habe ich noch nichts gefunden.

Hallo Manuel,

nach meinem Wissen, und der aktuell E3DC Modbus Doku gibt es diese Optionen nicht als Write Option.
Hätte dies auch gerne als Option um die Lademöglichkeit zu „Optimieren“.

Gruß

Philipp

ich denke, die Lösung, wird in diesem Thread im photovoltaikforum beschrieben:

E3DC Ãœberschusssteuerung per RSCP und Raspberry PI - Sonstiges - Photovoltaikforum

Hi,

klar mit RSCP kann man alles am E3/DC steuern (damit betreiben sie ja auch ihr Farming von mehreren Hauskraftwerken), allerdings ist die Implementierung in IPS mit Verschlüsselung nach meiner Einschätzung nicht gerade einfach zu machen.

Wenn jemand da motiviert ist ein Modul zu bauen, biete ich mich gerne als Tester an ;-):smiley:

Viele Grüße

Philipp

Danke für die vielen Hinweise. Das es mir lediglich um die beiden Optionen geht wäre der Aufwand mit RSCP recht umständlich, aber vielleicht werde ich mir das dennoch mal ansehen, diese Option war mir bisher nicht bekannt. Schade das E3DC die Optionen nicht direkt in M-BUS und das KNX Modul integriert. Der Aufwand für deren Seite sollte eigentlich nicht all zu groß sein.

Grüße

Manuel

Hallo Zusammen,

ich habe mit der ModBus Funktionalität von IPS ein Modul erstellt:
[Modul] E3DC Stromspeicher

Sehr sehr cool… bei uns wird es wohl auch das Teil von e3dc!
Bin schon gespannt. Danke fürs Modul und teilen eurer Skripte…
Peter

Gesendet von iPhone mit Tapatalk

Servus,
auch ich hab‘ mir Gedanken zur Beeinflussung des S10 gemacht.
Mein aktueller (aber etwas umständlicher) Weg:
Aus IP-Symcon starte ich eine SSH Sitzung auf einem Raspi
Auf dem Raspi ist das Programm „e3dcset“ installiert
Am Hauskraftwerk ist RSCP aktiv.

Wenn ich nun in IP-Symcon die Variablen „Funktion“&“Wert“ setze, überträgt die Ablaufkette von oben den Wert…dauert ca. 3Sekunden.

Somit kann ich aktuell die maximale Lade- und Entladeleistung jederzeit setzen, um im Sommer nicht in die Einspeiseabregelung zu laufen und im Winter beim Laden des Autos den Speicher nicht leer zu ziehen.