Das Script hatte ich hier irgendwo schon einmal gepostet.
Ich weiss nicht, ob das so jemanden hilft, da es sehr individuell und historisch gewachsen ist.
Ich pack’ euch mal ein paar Screenshots dazu, sonst blickt da keiner mit den ID’s durch.
// Regelung für die Einspeisung/Laden aus dem Netz (positiv => laden / negativ => Einspeisung ins Netz)
// ---------- Konfiguration ----------
$IDArchiveHandler = 10204;
$ID_Gesamtleistung = 42236;
$ID_Leistung_Mittelwert = 29827; // Werte zur Berechnung des möglichen Leistungsdurchschnitt
$ID_Sekunden = 27931; // ID Sekundenzähler für Netzteil zum Einschalten
$ID_Instanz_ESS_SOLL = 21696;
$ID_ESS_SOLL = 12332;
$ID_Instanz_Relais1 = 16100;
$ID_Status_Relais1 = 52086;
$ID_Instanz_Steckdose = 32438; // Steckdose Heizungsraum für Netzteil (Treppenlicht 15min.)
$ID_Steckdose_Status = 52398;
$ID_Instanz_Enable_Charger = 13532; // Modbus Instanz Charger
$ID_Instanz_Enable_Inverter = 43112; // Modbus Instanz Inverter
$Status_Charger = GetValue(21531); // aktueller Status Lader (aus = 0, ein = 100)
$Status_Inverter = GetValue(37530); // aktueller Status Inverter (aus = 0, ein = 100)
$SoC = GetValue(12410); // aktueller SoC Pylontech (Victron)
$ID_SoC_dyn = 16223; // ID des dynamischen SoC
$ID_SoC_100 = 34342; // ID des 0-100% SoC
$Laden_Offset = 100; // Vorgabe Offset zur Nullausregelung in W
$Entladen_Offset = -20;
$Laden_Max = 2200; // Ladeleistung Victron maximal in W
$Einspeisen_Max = -2400; // Einspeisleistung Victron maximal in W (max. 2400W)
$SoC_min = GetValue(47773); // minimum SoC bis abschalten des Inverters
$SoC_max = 100; // maximaler SoC beim Laden (Victron)
$Soc_max_Netzteil = 88; // maximaler SoC fürs Laden mit dem Netzteil
$SoC_Offset = 5; // Inverter wiedereinschalt SoC über min. SoC
//$Sekunden_Offset = 60; // Offsetzeit zum Zuschalten des Netzteils
$Sonnenstunden_morgen = GetValue(30733); // Sonnenstunden von morgen
$BatteryLife = GetValue(49237); // BatteryLife Status abfragen
$Leistung_Netzteil = 1400; // max. Leistung in W des zus. Ladenetzteils (aktiviert über Relais1)
$Leistung_Heizstab = GetValue(53870); // aktuelle Leistung der Heizstäbe
$Netzteilmodus = GetValue(33898); // Netzteil zum Laden benutzen ja/nein
$Bezug = round(GetValue(36301),0); // aktueller Bezug vom eHz in W
$Leistungssteller_aktuell = GetValueInteger(35077); // aktueller Wert vom ESS in W
// Ladeverhalten anpassen (normal/schnell)
if (GetValue(21454) == true) {
$Sekunden_Offset = 10; // Offsetzeit zum Zuschalten des Netzteils
$NetzteilStartWatt = 2200; // Netzteil Startleistung ESS in Watt
} else {
$Sekunden_Offset = 55;
$NetzteilStartWatt = 2500;
}
// ===================================================================================================================================
// Steuerung Einspeisleistung nach Batteriestatus (SoC)
if ($SoC < 20) {$Einspeisen_Max = -1000;} // Einspeisleistung bei niedriegen SoC begrenzen
if ($SoC < 15) {$Einspeisen_Max = -500;}
// ---------- BatteryLife - Steuerung dynamischer SoC_min (mit Sonnenstunden des nächsten Tages um 13:05) ----------
// einmal tägl. prüfen (13:05)
if (($_IPS['SENDER'] == "TimerEvent") and ($BatteryLife == 1)) { // wenn BatteryLife-Regelung nach Wetter (1)
if ($_IPS['EVENT'] == 40077) {
$SoC_min = 10;
if ($Sonnenstunden_morgen <= 5) {$SoC_min = 15;} //20%
if ($Sonnenstunden_morgen <= 4) {$SoC_min = 25;} //25%
if ($Sonnenstunden_morgen <= 2) {$SoC_min = 30;} //40%
if ($Sonnenstunden_morgen <= 1) {$SoC_min = 40;} //60%
SetValue(47773, $SoC_min);
return;
}
}
// beim Umschalten prüfen
if ($_IPS['SENDER'] == "Variable") {
if ($_IPS['VARIABLE'] == 49237) {
if ($BatteryLife == 0) {$SoC_min = 10;}
if ($BatteryLife == 1) {
$SoC_min = 10;
if ($Sonnenstunden_morgen <= 5) {$SoC_min = 15;} //20%
if ($Sonnenstunden_morgen <= 4) {$SoC_min = 25;} //25%
if ($Sonnenstunden_morgen <= 2) {$SoC_min = 30;} //40%
if ($Sonnenstunden_morgen <= 1) {$SoC_min = 40;} //60%
}
if ($BatteryLife == 2) {$SoC_min = 20;}
if ($BatteryLife == 3) {$SoC_min = 40;}
if ($BatteryLife == 4) {$SoC_min = 60;}
if ($BatteryLife == 5) {$SoC_min = 80;}
SetValue(47773, $SoC_min);
return;
}
}
// ---------------- Berechnung des dynamischen SoC ----------------------------
$SoC_dyn = ($SoC - $SoC_min) * 100 / ($SoC_max - $SoC_min); // Berechnung dynamischer Soc (zur Anzeige von 0-100% der verfügbaren Kapazität)
if (($SoC_dyn < 0) or ($Status_Inverter == 0)) {$SoC_dyn = 0;}
if ($SoC_dyn > 100) {$SoC_dyn = 100;}
SetValueInteger($ID_SoC_dyn, $SoC_dyn);
// ---------------- Berechnung des 0-100% SoC (10-95%)----------------------------
$min_SoC = 10;
$SoC_100 = ($SoC - $min_SoC) * 100 / ($SoC_max - $min_SoC); // Berechnung 0-100% Soc (zur Anzeige von 0-100% der Gesamt-Kapazität)
if ($SoC_100 < 0) {$SoC_100 = 0;}
if ($SoC_100 > 100) {$SoC_100 = 100;}
SetValueInteger($ID_SoC_100, $SoC_100);
// *************************************************** Notstromladen *****************************************************************
$Notstromladen = GetValue(45988);
if ($Notstromladen == true) {
$Bezug = -2000; // 2000W Einspeisung vorgaukeln
$SoC_min = 10; // Soc minimum zum entladen im Notstrombetrieb
$SoC_max = 92; // maximaler SoC beim Laden (Victron)
}
// ***********************************************************************************************************************************
// ---------- Steuerung des Inverters (ein/aus) ----------
if ($SoC <= $SoC_min) { // Wenn SoC < SoC_min Inverter ausschalten
if ($Status_Inverter > 0) {
ModBus_WriteRegisterShort($ID_Instanz_Enable_Inverter, 0);
}
}
if ($SoC >= ($SoC_min + $SoC_Offset)) { // Wenn SoC über (SoC_min. + Offset) Inverter einschalten
if ($Status_Inverter < 100) {
ModBus_WriteRegisterShort($ID_Instanz_Enable_Inverter, 100);
}
}
// ---------- Steuerung des zusätzlichen Netzteils zum Laden (über Relais 1 Venus GX) ----------
if ($_IPS['SENDER'] == "Variable") {
if ($_IPS['VARIABLE'] == 36301) {
$Netzteil_aktuell = GetValue($ID_Status_Relais1) * $Leistung_Netzteil; // aktuelle Leistung Netzteil
$Power_gesamt = $Leistungssteller_aktuell + $Netzteil_aktuell + ($Bezug * -1); // Gesamtleistung ermitteln
SetValue($ID_Gesamtleistung, $Power_gesamt); // mögliche Gesamtleistung in Variable schreiben
$Mittelwert = getMean ($IDArchiveHandler,$ID_Gesamtleistung,120,0); // Mittelwert mögliche Gesamtleistung über 2 min.
SetValue($ID_Leistung_Mittelwert, $Mittelwert);
// *** Sekundenzähler für Freigabe des Netzteils ***
if (($Power_gesamt + $Leistung_Heizstab) >= 2000) {
$Restzeit = (GetValue($ID_Sekunden) - (time() - (IPS_GetVariable($ID_Sekunden)['VariableUpdated'])));
if ($Restzeit < 0) {
$Restzeit = 0;
}
SetValue($ID_Sekunden, $Restzeit);
}
if (($Power_gesamt + $Leistung_Heizstab) < 2000) SetValue($ID_Sekunden, $Sekunden_Offset); // Sekundenzähler für Freigabe NT hochzählen oder löschen
// *** Netzteil zuschalten ***
if (($Power_gesamt > 2000) and ($SoC <= $Soc_max_Netzteil) and ($Netzteilmodus == true) and ($Notstromladen == false)) {
KNX_WriteDPT1($ID_Instanz_Steckdose, true); // Steckdose Heizungsraum ein (15 min. Treppenlicht)
}
// *** Netzteilausgang einschalten ***
if (($Power_gesamt > $NetzteilStartWatt) and (GetValue($ID_Sekunden) <= 0) and ($SoC <= $Soc_max_Netzteil) and ($Netzteilmodus == true) and ($Notstromladen == false)) { // Bedingungen für Netzteil einschalten
if (GetValue($ID_Status_Relais1) == 0){ // wenn Netzteil aus war, Netzteileinschaltzähler hochzählen
SetValueInteger(54069, (GetValueInteger(54069) + 1));
}
ModBus_WriteRegisterShort($ID_Instanz_Relais1, 1); // NT ein (Relais 1) wenn > 2500W und SoC < max.
SetValueBoolean(37354, true);
}
// *** Netzteil ausschalten ***
if ((($Power_gesamt + $Leistung_Heizstab) < 1500) or ($SoC > $Soc_max_Netzteil) or ($Netzteilmodus == false) or ($Notstromladen == true)) { // NT aus (Relais 1) wenn < 1500W oder SoC > max. oder Notstromladen
ModBus_WriteRegisterShort($ID_Instanz_Relais1, 0);
SetValueBoolean(37354, false); // Netzteil-Variable schalten
}
// *** Leistungen schreiben ***
$Netzteil_aktuell = GetValue($ID_Status_Relais1) * $Leistung_Netzteil; // aktuelle Leistung Netzteil
SetValue(47589, $Netzteil_aktuell); // testweise Leistung Netzteil in Variable schreiben
SetValue(19925, ($Netzteil_aktuell + $Leistungssteller_aktuell)); // Gesamt ESS-Leistung in Variable schreiben
}
}
// --------------- Steuerung des ESS Sollwertes (Victron GX) -------------------
if ($_IPS['SENDER'] == "Variable") {
if ($_IPS['VARIABLE'] == 36301) {
$Power = $Leistungssteller_aktuell + ($Bezug * -1); // Leistung ESS festlegen
if (($Power > $Entladen_Offset) and ($Power < $Laden_Offset)) { $Power = 0;} // Offset zum Laden/Entladen
if ($Power > $Laden_Max) {$Power = $Laden_Max;} // Ladeleistung begrenzen
if ($Power < $Einspeisen_Max) {$Power = $Einspeisen_Max;} // WR Leistung begrenzen
if (($Power > 0) and ($SoC >= $SoC_max)) {$Power = 0;} // Laden abschalten wenn SoC über Soc max.
// ModBus_WriteRegisterShort($ID_Instanz_ESS_SOLL, $Power); // neuen Wert in Soll Instanz schreiben (ESS_Soll)
SetValueInteger($ID_ESS_SOLL, $Power); // neuen Wert in Soll Variable schreiben
// return;
}
}
// ------------------ Status Inverter / Lader / Netzteil in Variable (für MDT GT2) ------------------
if ((GetValue(47589) + $Leistungssteller_aktuell) > 100) { // bei laden > 100W Variable setzen
SetValue(23656, true);
} else {
SetValue(23656, false);
}
if ((GetValue(47589) + $Leistungssteller_aktuell) < -100) { // bei entladen < -100W Variable setzen
SetValue(16828, true);
} else {
SetValue(16828, false);
}
if ($Bezug > 100) { // Bezug > 100W Variable setzen
SetValue(13025, true);
} else {
SetValue(13025, false);
}
if ($Bezug < -100) { // Bezug < -100W Variable setzen
SetValue(12883, true);
} else {
SetValue(12883, false);
}
// ---------------------------- Funktionen --------------------------------------------
function getMean ($IDArchivehandler,$varId,$log_interval,$default) {
$logData = AC_GetLoggedValues ($IDArchivehandler, $varId, time()- $log_interval,time(),-1);
if (count($logData) <1) return $default;
foreach ($logData as $key => $data)
{
$value[$key] = $data['Value'];
}
return array_sum($value)/count($value);
}
function getMedian ($IDArchivehandler,$varId,$log_interval,$default) {
$logData = AC_GetLoggedValues ($IDArchivehandler, $varId, time()-$log_interval,time(),-1);
if (count($logData) <1) return $default;
foreach ($logData as $key => $data)
{
$value[$key] = $data['Value'];
}
asort($value);
return $value[count($value)/2];
}