ja, danke. Das hatten wir ja schonmal im Vorfeld grob besprochen.
Die Anbindung des TibberPulse über Uni-Meter werde ich angehen, wenn ich mit dem Testen der API durch bin.
Ich melde mich dann nochmal, wenn ich Hilfe brauche.
ich hätte Interesse an Deinen Skripten für die Marstek API. Vielleicht reicht mir das ja schon und ich muss nicht den Umweg über Modbus nehmen……..
Kannst gerne mal hier berichten, wie es mit der local API läuft.
Hatte die auch an getestet, aber lief nicht so Rund bei mir.
Vor allem musst aufpassen mit der Häufigkeit der Anfragen bzw. mit dem Poling,
weil wenn zu häufig Anfragen sendest hängt sich die Schnittstelle auf.
mache ich gerne…
und für @marcusb
- Vorbereitung API: UDP-Socket und Registervariable in Symcon anlegen.
- Zwei Programme: aufbereiten und senden der Befehle über den UDP-Socket und als 2. PGM= Auswertung der Registervariable mit den Rückmeldungen dewr Venus.
- Aktivierung der API in der APP. Hier ist auch ein Link zur API-Dokumentation
Die Programme sind noch unfertig, aber ich kann den aktuellen Status auch hier posten.
Nächste woche kommt mein Venus E 3.0 Speicher. Bei einem Preis inkl. Versand von 989€ konnte ich nicht wiederstehen…
Noch bin ich am grübeln, ob ich den Ecotracker kaufe und auf den Zähler packe. Oder ob ich einen CT002 vom Elektriker einbauen lasse…
ALternativ hätte ich aber eigentlich auch ein Fronius Smartmeter von meiner PV Anlage - das sich wohl auch emulieren lässt.
Bin schon gespannt auf deine Skripte/Anbindung des Marsteks.
Funktioniert das mit dem uni-meter Projekt und einem Fronius wirklich stressfrei?
ESP8266 und ESP32 hätte ich noch rumliegen….
Der CT002 hat den Vorteil, wenn ich es richtig verstanden habe, dass er bis zu 3 Venus steuern kann. Das geht mit dem ShellyPro3EM NICHT (egal ob emuliert über Uni-Meter oder physikalisch eingebaut). Der Shelly kann nur einen steuern.
Ich habe nun Uni-Meter über MQTT an IP-Symcon angebunden. Das läuft seit 3 Tagen problemlos.
Am liebsten wäre mir eine Lösung, mit der ich in IP-Symcon bis zu 3 Venus Speicher über die Energieverteilung laden und entladen könnte. Es gibt wohl schon etwas für HA: GitHub - diegoschlauri/marstek_venus_ha: Home Assistant - Intelligente Batteriesteuerung für Marstek Venus E . Dann würde auch die Einspeisung/Verbrauch wieder korrekt angezeigt werden. Im Moment wird die Venus dem Zähler für den Haushaltsstrom zugerechnet.
Das wird über den Modbus gesteuert. Ich werde also nun im nächsten Schritt die Modbus-Schnittstelle testen.
poste doch gerne mal den aktuellen Status. ![]()
Wenn ich die API Doku richtig gelesen habe, dann geht nur lesen aber kein forcen von laden oder entladen. Richtig?
Achso was ist denn das Ziel der Register Variable?
Hast Du den Standard Port 30000 gewählt? Warum sollte ich und wenn wie ändere ich ihn?
Bei deinem Wunsch ist aber zwingend ein laufendes IP-Symcon nötig.
Da wäre ich “altmodisch”, und würde mir fürs erste einen Ecotracker zum aufstecken kaufen.
Wenn AKKU 2 oder 3 kommen soll, dann in den sauren Apfel beissen und einen Elektriker machen lassen, mit nem CT002
Ich benutze die erste Einstellung (0-9 möglich) der manuellen Steuerung. Dann kann ich Lade-/entladedaten einstellen. Das mache ich im Programm „Ladesteuerung“.
Als Ziel für die Registervariable habe ich mein Programm „Registervariable lesen“ angegeben. Die Registervariable liefert z.B. die Antwort auf Abfragen.
Ja habe den Port 30000 gewählt. Man kann auch einen anderen Port zwischen 49152 und 65535 nehmen. Eingestellt wird er im UDP-Socket.
Meinen aktuellen Programmstand werde ich gleich mal posten.
Hier mal mein aktueller Programmstand für die API:
- API über UDP-Socket abfragen:
<?php
//******************************************************************************
// Abfrage der Marstek API
// 24405
//******************************************************************************
include '17825.ips.php';
$id_udp = 44188;
$id_method = 27139;
$test = false;
$meldung = "";
$sender = $_IPS['SENDER'];
$webfrontNR = 40850;
$ip = "192.168.1.42";
$port = 30000;
$method = "method fehlerhaft";
//******************************************************************************
IF($sender == "WebFront")
{
SetValue($_IPS["VARIABLE"], $_IPS["VALUE"]); // Variable im WF aktualisieren
$var = $_IPS['VARIABLE']; // auslösende Variable
$wert = $_IPS['VALUE']; // aktueller Wert der Variablen
}
//******************************************************************************
// PGM-Aufruf mit z.B.
// IPS_RunScriptEx(31688, Array("VAR"=>0, "WERT"=>0));
//******************************************************************************
IF($sender == "RunScript")
{
$var = $VAR;
$wert = $WERT;
}
//******************************************************************************
// 16392
// 27076
// 40518
IF($sender == "TimerEvent")
{
$var = $_IPS['EVENT'];
}
//******************************************************************************
IF($_IPS['SENDER'] == "Variable")
{
$var = $_IPS['VARIABLE']; // z.B. Taste Wandsender #37031
$wert = $_IPS['VALUE']; // aktueller Wert der Variablen
}
//******************************************************************************
// hier den Auslöser zum Testen eintragen
IF($sender == "Execute")
{
$var = 16392;
$wert = 0.0;
}
//******************************************************************************
// Funktion ausführen
// Auswahl = $var z.B. auslösende Variable
// Wert = $wert z.B. Wert der auslösenden Variable
// mehrfach = case <var>: case <var>:
//******************************************************************************
switch ($var)
{
case 16392:
//
$method = "ES.GetStatus";
$json = '{
"id": 1,
"method": "ES.GetStatus",
"params": {
"id": 0
}
}';
break;
case 27076:
//
$method = "Marstek.GetDevice";
$json = '{
"id": 0,
"method": "Marstek.GetDevice",
"params": {
"ble_mac":"009b08a5b73f"
}
}';
break;
case 40518:
//
$method = "Bat.GetStatus";
$json = '{
"id": 1,
"method": "Bat.GetStatus",
"params": {
"id": 0
}
}';
break;
default:
// zum testen von abfragen
$method = "ES.GetMode";
$json = '{
"id": 0,
"method": "ES.GetMode",
"params": {
"id": 0
}
}
}';
break;
}
// methode abfragen
$response = USCK_SendText($id_udp, $json);
// methode speichern für Auswertung Register-Variable
SetValueString($id_method, $method);
//******************************************************************************
// Testausgabe
//******************************************************************************
if($sender == "Execute") $test = true;
if($test == true)
{
echo "Rückmeldung: ";
Var_dump($response);
echo "json: ";
Var_dump($json);
//echo "meldung: ";
//Var_dump($meldung);
}
//******************************************************************************
// universelle Ausgabe auf verschiedene Medien als Funktionsaufruf
//******************************************************************************
IF($meldung <> "")
{
//MELDUNG_soundfile($meldung);
//MELDUNG_usb(10);
//MELDUNG_logfile($meldung);
//MELDUNG_prowl('', '1110', $meldung);
//MELDUNG_webfront($webfrontNR, $meldung);
//MELDUNG_vu($meldung);
//MELDUNG_mail();
//WFC_PushNotification($webfrontNR, 'Marstek', $meldung, '', 0);
}
- Die Antwort kommt über die Registervariable und wird in diesem PGMausgewertet:
<?php
//******************************************************************************
// 54713
//******************************************************************************
// Register-Variable = 23078
//******************************************************************************
include '17825.ips.php';
$id_method = 27139;
$id_soc = 37451;
$id_firmware = 40251;
$id_netzpower = 34007;
$id_temperatur = 42434;
$id_energie = 48202;
$id_powerplan = 30128;
$id_enable = 54255;
$id_error = 19033;
$test = false;
$meldung = "";
$webfrontNR = 40850;
$error = "";
$method = GetValueString($id_method);
//******************************************************************************
// Werte aus RegisterVariable holen
//******************************************************************************
$data = $_IPS['VALUE'];
// JSON bereinigen (falls nötig)
$clean = trim($data);
// JSON in Array wandeln
$data = json_decode($clean, true);
// auf Fehler prüfen
if (!empty($data['error'])) {
$error = $method.": ".$data['error']['message'];
$method = "Fehler";
}
switch ($method)
{
case "Fehler":
//
$meldung = "Fehler erkannt: ".$error;
SetValueInteger($id_powerplan,GetValueInteger($id_netzpower)); // rücksetzen neuer Wert für laden/entladen
break;
case "ES.GetStatus":
// Result-Werte
$result = $data['result'];
$res_id = $result['id'];
$soc = $result['bat_soc'];
$bat_cap = $result['bat_cap'];
$pv_power = $result['pv_power'];
$netzpower = $result['ongrid_power'];
$offgrid_power = $result['offgrid_power'];
$total_pv_energy = $result['total_pv_energy'];
$total_grid_output = $result['total_grid_output_energy'];
$total_grid_input = $result['total_grid_input_energy'];
$total_load_energy = $result['total_load_energy'];
$netzpower = $netzpower-$offgrid_power;
SetValueInteger($id_soc, $soc);
SetValueInteger($id_netzpower,$netzpower);
SetValueInteger($id_powerplan,$netzpower);
//SetValueInteger($id_netzpower,$netzpower-$offgrid_power);
break;
case "Marstek.GetDevice":
// Result-Werte
$result = $data['result'];
$firmware = $result['ver'];
/*
[device] => VenusE 3.0
[ver] => 144
[ble_mac] => 009b08a5b73f
[wifi_mac] => 2c3afd050423
[wifi_name] => FRITZ!Box WLAN 3170
[ip] => 192.168.1.42
*/
SetValueInteger($id_firmware,$firmware);
break;
case "Bat.GetStatus":
// Result-Werte
$soc = $data['result']['soc'];
$temperatur = $data['result']['bat_temp'];
$energie = $data['result']['bat_capacity'];
/*
[result] => Array
(
[id] => 0
[soc] => 100
[charg_flag] => 1
[dischrg_flag] => 1
[bat_temp] => 17
[bat_capacity] => 5120
[rated_capacity] => 5120
)
)
*/
SetValueInteger($id_soc, $soc);
SetValueInteger($id_temperatur,$temperatur);
SetValueInteger($id_energie,$energie);
break;
case "ES.SetMode":
//
SetValueInteger($id_netzpower,GetValueInteger($id_powerplan));
break;
default:
//
break;
}
if($error<>"") $error = date("H:i:s ").$error; // Fehlermeldung mit Zeit
SetValueString($id_error,$error); // für Anzeige speichern
//******************************************************************************
// Testausgabe
//******************************************************************************
if($test == true)
{
echo "Methode: ";
Var_dump($method);
echo "Fehler: ";
var_dump($error);
echo "meldung: ";
Var_dump($meldung);
print_r($data);
}
//******************************************************************************
// universelle Ausgabe auf verschiedene Medien als Funktionsaufruf
//******************************************************************************
IF($meldung <> "")
{
//MELDUNG_soundfile($meldung);
//MELDUNG_usb(10);
//MELDUNG_logfile($meldung);
//MELDUNG_prowl('', '1110', $meldung);
//MELDUNG_webfront($webfrontNR, $meldung);
//MELDUNG_vu($meldung);
//MELDUNG_mail();
//WFC_PushNotification($webfrontNR, 'Marstek', $meldung, '', 0);
}
Für die Lade-/Entladesteuerung mein 3. PGM:
<?php
//******************************************************************************
// Steuerung der Venus zum Laden/Entladen
// 36589
//******************************************************************************
include '17825.ips.php';
$id_udp = 44188;
$id_method = 27139;
$id_preis = 51164;
$id_powerist = 55934;
$id_powerplan = 30128;
$id_soc = 37451;
$id_enable = 54255;
$test = false;
$meldung = "";
$sender = $_IPS['SENDER'];
$webfrontNR = 40850;
$ip = "192.168.1.42";
$port = 30000;
//$response = false;
// Variable für json
$json = "";
$method = "ES.SetMode";
$mode = "Manual";
$time_num = 0;
$start_time = "00:00";
$end_time = "23:59";
$week_set = 127;
$power = -200; // wird neu berechnet, negativ = Akku laden
$enable = 1;
//******************************************************************************
// logik für Laden/entladen/inaktiv = Eigenverbrauch (Nulleinspeisung)
//******************************************************************************
$powerist = (int)GetValueFloat($id_powerist); // power vom Tibber-Pulse
$powerplan = GetValueInteger($id_powerplan)+$powerist; // Berechnung Nullwert
$power = round($powerplan / 10) * 10; // auf 10-er runden
if($power > 800) $power = 800; // max 800 Watt einspeisen
if(($power < 0) and ($power > -100)) $power = 0; // min. 100 Watt aus dem Netz speichern / Ladesteuerung deaktiviert
if($power < -2000) $power = -2000; // max 2000 Watt aus dem Netz speichern
// wenn SOC < x%, dann keine weitere Entladung
if($power > 0){
$soc = GetValueInteger($id_soc);
if($soc < 15) $enable = 0; // Steuerung deaktivieren
}
$json = Venus_ES_SetMode($id_udp,$id_method,$id_powerplan,$power,$enable); // Befehl aufbereiten und senden
SetValueInteger($id_enable,$enable); // Status speichern
//******************************************************************************
// Testausgabe
//******************************************************************************
if($sender == "Execute") $test = true;
if($test == true)
{
echo "manuelle Steuerung: ";
Var_dump($enable);
echo "Power neu: ";
Var_dump($power);
echo "Power Zähler: ";
Var_dump($powerist);
echo "json: ";
Var_dump($json);
//echo "meldung: ";
//Var_dump($meldung);
}
//******************************************************************************
// universelle Ausgabe auf verschiedene Medien als Funktionsaufruf
//******************************************************************************
IF($meldung <> "")
{
//MELDUNG_soundfile($meldung);
//MELDUNG_usb(10);
//MELDUNG_logfile($meldung);
//MELDUNG_prowl('', '1110', $meldung);
//MELDUNG_webfront($webfrontNR, $meldung);
//MELDUNG_vu($meldung);
//MELDUNG_mail();
//WFC_PushNotification($webfrontNR, 'Marstek', $meldung, '', 0);
}
//******************************************************************************
// json aus Variablen erstellen und senden
//******************************************************************************
function Venus_ES_SetMode($id_udp,$id_method,$id_powerplan,$power,$enable){
$method = "ES.SetMode";
$mode = "Manual";
$time_num = 0;
$start_time = "00:00";
$end_time = "23:59";
$week_set = 127;
//$power = -200; // wird neu berechnet, negativ = Akku laden
//$enable = 1;
// Array zusammenbauen
$data = [
"id" => 1,
"method" => $method,
"params" => [
"id" => 0,
"config" => [
"mode" => $mode,
"manual_cfg" => [
"time_num" => $time_num,
"start_time" => $start_time,
"end_time" => $end_time,
"week_set" => $week_set,
"power" => $power,
"enable" => $enable
]
]
]
];
// JSON erzeugen
$json = json_encode($data, JSON_PRETTY_PRINT);
// json senden
$response = USCK_SendText($id_udp, $json); // Daten an Venus senden
SetValueString($id_method, $method); // methode speichern für Auswertung Register-Variable
SetValueInteger($id_powerplan, $power); // Einstellung speichern / wird durch ES.GetStatus aktualisiert
return $json;
}
und hier noch ein Auszug aus Symcon-Objektbaum:
Bitte nur als Anregung/Muster verstehen. Das sind meine ersten Versuche.
Die Variablen-ID’s müsst ihr natürlich anpassen.
Fragen dazu beantworte ich natürlich gerne.

