RegisterPropertyInteger("MaxBatterieleistung", 0); $this->RegisterPropertyInteger("Batteriespannung", 50); $this->RegisterPropertyInteger("Batterie_Ladezustand", 50); $this->RegisterPropertyFloat("AufdasNachladen",0); $this->RegisterPropertyFloat("MinimumEntladen",0); $this->RegisterPropertyInteger("Batteriemanagement", 1); $this->RegisterPropertyInteger("Kotnrolle_TOU_Spannung", 0); $this->RegisterPropertyInteger("Kotnrolle_Selling_CT", 0); $this->RegisterPropertyInteger("MaxNachladen",0); $this->RegisterPropertyInteger("Netzbezug", 0); // Initialisierung mit 0 $this->RegisterPropertyInteger("Interval", 2); // Recheninterval // Variabeln für Kommunkation mit Manager $this->RegisterVariableInteger("Batteriemanagement_Variabel","Batteriemanagement_Variabel", "",0); $this->RegisterVariableInteger("Ladestrom","Ladestrom", "",0); $this->RegisterVariableInteger("Entladestrom","Entladestrom", "",0); $this->RegisterVariableInteger("Batteriespannung_laden_entladen","Batteriespannung_laden_entladen","",0); $this->RegisterVariableInteger("Aktuelle_Leistung", "Aktuelle_Leistung", "", 0); $this->RegisterVariableString("PowerSteps", "PowerSteps"); $this->RegisterVariableBoolean("Idle", "Idle", "", 0); $this->RegisterVariableInteger("Sperre_Prio", "Sperre_Prio"); $this->RegisterVariableInteger("PV_Prio", "PV_Prio"); $this->RegisterVariableInteger("Power", "Power"); $this->RegisterVariableBoolean("Is_Peak_Shaving", "Is_Peak_Shaving"); $this->RegisterVariableInteger("Leistung_Delta", "Leistung_Delta", "", 0); $this->RegisterVariableBoolean("Hysterese", "Hysterese","",false); $this->RegisterVariableBoolean("Schreibkontrolle", "Schreibkontrolle","",false); $this->RegisterVariableFloat("Bezogene_Energie", "Bezogene_Energie", "", 0); // Hilfsvariabeln für Idle zustand $this->RegisterPropertyInteger("IdleCounterMax", 2); $this->RegisterVariableInteger("IdleCounter", "IdleCounter", "", 0); $this->SetValue("IdleCounter", 0); // Initialisiere Idle $this->SetValue("Idle", true); $this->RegisterTimer("Timer_Do_UserCalc_Battery",$this->ReadPropertyInteger("Interval")*1000,"IPS_RequestAction(" .$this->InstanceID .', "Do_UserCalc", "");'); } public function ApplyChanges() { parent::ApplyChanges(); $batterieManagement = $this->ReadPropertyInteger("Batteriemanagement"); $this->SetValue("Batteriemanagement_Variabel", $batterieManagement); $this->SetTimerInterval("Timer_Do_UserCalc_Battery",$this->ReadPropertyInteger("Interval")*1000); } private function GeneratePowerSteps($additionalValue) { $maxleistung = $this->ReadPropertyInteger("MaxBatterieleistung"); $stepSize = 250; // Schrittgröße $stepSizeSmall = 50; // Kleine Schrittgröße // Array direkt als Range erzeugen (schneller als Schleife) $array_powersteps = range(-$maxleistung, $maxleistung, $stepSize); // Nächstgelegenen Wert direkt bestimmen (rundet auf den nächsten Step) $closestValue = round($additionalValue / $stepSize) * $stepSize; // Falls der Wert nicht im Bereich liegt, abbrechen if (!in_array($closestValue, $array_powersteps)) { return $array_powersteps; } // Index des gefundenen Werts suchen $index = array_search($closestValue, $array_powersteps); // Zusätzliche Werte berechnen und auf MaxLeistung begrenzen $newValues = array_filter([ $closestValue - 4 * $stepSizeSmall, $closestValue - 3 * $stepSizeSmall, $closestValue - 2 * $stepSizeSmall, $closestValue - $stepSizeSmall, $closestValue, $closestValue + $stepSizeSmall, $closestValue + 2 * $stepSizeSmall, $closestValue + 3 * $stepSizeSmall, $closestValue + 4 * $stepSizeSmall, ], function ($value) use ($maxleistung) { return $value >= -$maxleistung && $value <= $maxleistung; }); // Effizienteres Einfügen der Werte (direkt an der Stelle) array_splice($array_powersteps, $index, 1, $newValues); return $array_powersteps; } public function RequestAction($Ident, $Value) { switch ($Ident) { case "SetAktuelle_Leistung": $this->SetValue("Power", (int)$Value); break; case "GetCurrentData": $this->SetValue("Is_Peak_Shaving", (bool)$Value); break; case "Do_UserCalc": $this->SetAktuelle_Leistung($this->GetValue("Power")); $this->GetCurrentData($this->GetValue("Is_Peak_Shaving")); break; default: throw new Exception("Invalid Ident"); } } public function SetAktuelle_Leistung(int $power) { $y = (-1)*$power; if ($y < 0) { // Laden $uVarID = $this->ReadPropertyInteger("Batteriespannung"); if ($uVarID > 0 && IPS_VariableExists($uVarID)) { $U = GetValue($uVarID); if ($U > 0) { $lade_strom = abs($y) / $U; } else { $lade_strom = 0; } } else { $lade_strom = 0; } $this->SetValue("Ladestrom", $lade_strom); $this->SetValue("Entladestrom", 0); $this->SetValue("Batteriespannung_laden_entladen", 100); } elseif ($y > 0) { // Entladen $uVarID = $this->ReadPropertyInteger("Batteriespannung"); if ($uVarID > 0 && IPS_VariableExists($uVarID)) { $U = GetValue($uVarID); if ($U > 0) { $entlade_strom = $y / $U; } else { $entlade_strom = 0; } } else { $entlade_strom = 0; } $this->SetValue("Entladestrom", $entlade_strom); $this->SetValue("Ladestrom", 0); $this->SetValue("Batteriespannung_laden_entladen", 5); } else { // Kein Stromfluss (Leistung = 0) $this->SetValue("Ladestrom", 0); $this->SetValue("Entladestrom", 0); } $batterieManagement = $this->ReadPropertyInteger("Batteriemanagement"); // Wechselrichter steuert das Laden/Entladen der Batterie if ($batterieManagement == 2) { $this->SetValue("Ladestrom", 0); $this->SetValue("Entladestrom", 0); return; } // Prüfe auf Änderung der Leistung im Vergleich zur letzten Einstellung $lastPower = GetValue($this->GetIDForIdent("Aktuelle_Leistung")); if ($power != $lastPower) { $this->SetValue("Idle", false); $this->SetValue( "IdleCounter", $this->ReadPropertyInteger("IdleCounterMax") ); } // Setze die neue aktuelle Leistung $this->SetValue("Aktuelle_Leistung", $power); $this->SetValue("Bezogene_Energie", ($this->GetValue("Bezogene_Energie") + ($this->GetValue("Aktuelle_Leistung")*($this->ReadPropertyInteger("Interval")/3600)))); // IdleCounter verarbeiten $this->ProcessIdleCounter(); } public function GetCurrentData(bool $Peak) { $ct = GetValue($this->ReadPropertyInteger("Kotnrolle_Selling_CT")); $sell_Ct = $this->GetValue("Batteriemanagement_Variabel"); if ($ct != $sell_Ct) { $this->SetValue("Schreibkontrolle", false); } else { $this->SetValue("Schreibkontrolle", true); } //$a = 2.54 * pow($V, 2) - 252 * $V + 6255.4; $ladestrom_1 = $this->GetValue("Ladestrom"); $entadestrom_1 = $this->GetValue("Entladedestrom"); /* if ($ladestrom_1 > 0 ) { $V = GetValue($this->ReadPropertyInteger("Batteriespannung")) - 1; }elseif ($entadestrom_1 > 0) { $V = GetValue($this->ReadPropertyInteger("Batteriespannung")) + 1; } else { $V = GetValue($this->ReadPropertyInteger("Batteriespannung")); } */ IPS_LogMessage("Batterie", "Currentdata"); $array_powersteps = $this->GeneratePowerSteps($this->GetValue("Aktuelle_Leistung")); $aufdasnachladen = $this->ReadPropertyFloat("AufdasNachladen"); $minimumentladen = $this->ReadPropertyFloat("MinimumEntladen"); $maxleistung = $this->ReadPropertyInteger("MaxBatterieleistung"); $dummy_array = []; $batterieladezustand = GetValue($this->ReadPropertyInteger("Batterie_Ladezustand")); $filtered_powersteps_entladen = []; if ($this->ReadPropertyInteger("Batteriemanagement") == 2) { $dummy_array[] = 0; return $this->SetValue("PowerSteps", json_encode($dummy_array)); } $netzbezug = GetValue($this->ReadPropertyInteger("Netzbezug")); if (abs($netzbezug) > $maxleistung) { $netzbezug = $maxleistung * (-1); } if($batterieladezustand>(5+$aufdasnachladen)){ $this->SetValue("Hysterese", false); }elseif($batterieladezustand<=$aufdasnachladen){ $this->SetValue("Hysterese", true); } $hyst = $this->GetValue("Hysterese"); if($Peak){ IPS_LogMessage("Batterie", "Im if teil"); if($batterieladezustand>$aufdasnachladen && $hyst==false){ $dummy_array[] = $netzbezug; $this->SetValue("PowerSteps", json_encode($dummy_array)); }elseif($batterieladezustand>$aufdasnachladen && $hyst==true){ $filtered_powersteps = array_filter($array_powersteps, function ($value) { return $value <= 0; }); $filtered_powersteps_laden = array_values($filtered_powersteps); $this->SetValue("PowerSteps", json_encode($filtered_powersteps_laden)); }elseif($batterieladezustand>$minimumentladen){ $this->SetValue("PowerSteps", json_encode($array_powersteps)); } else{ $filtered_powersteps = array_filter($array_powersteps, function ($value) { return $value >= 0; }); $filtered_powersteps_laden = array_values($filtered_powersteps); $this->SetValue("PowerSteps", json_encode($filtered_powersteps_laden)); } }else{ IPS_LogMessage("Batterie", "Im else teil"); if($batterieladezustand>99.9){ IPS_LogMessage("Batterie", "im 1"); $filtered_powersteps = array_filter($array_powersteps, function ($value) { return $value <= 0; }); $filtered_powersteps_laden = array_values($filtered_powersteps); $this->SetValue("PowerSteps", json_encode($filtered_powersteps_laden)); }elseif($batterieladezustand>$aufdasnachladen && $hyst==false){ $this->SetValue("PowerSteps", json_encode($array_powersteps)); IPS_LogMessage("Batterie", "im 2"); }elseif($batterieladezustand>=$aufdasnachladen && $hyst==true){ $filtered_powersteps = array_filter($array_powersteps, function ($value) { return $value >= 0; }); $filtered_powersteps_laden = array_values($filtered_powersteps); $this->SetValue("PowerSteps", json_encode($filtered_powersteps_laden)); }elseif($batterieladezustand<$aufdasnachladen){ $dummy_array[] = $this->ReadPropertyInteger("MaxNachladen"); $this->SetValue("PowerSteps", json_encode($dummy_array)); IPS_LogMessage("Batterie", "im 3"); } } } private function CheckIdle($power) { $lastpower = GetValue("Aktuelle_Leistung"); if ($lastpower != GetValue("Aktuelle_Leistung")) { $this->SetValue("Idle", false); $this->SetValue( "IdleCounter", $this->ReadPropertyInteger("IdleCounterMax") ); } // IdleCounter auslesen und verarbeiten $idleCounter = $this->GetValue("IdleCounter"); if ($idleCounter > 0) { $this->SetValue("Idle", false); $this->SetValue("IdleCounter", $idleCounter - 1); } else { $this->SetValue("Idle", true); } } private function ProcessIdleCounter() { // IdleCounter auslesen und verarbeiten $idleCounter = $this->GetValue("IdleCounter"); if ($idleCounter > 0) { $this->SetValue("Idle", false); $this->SetValue("IdleCounter", $idleCounter - 1); } else { $this->SetValue("Idle", true); } } } ?>