RegisterPropertyInteger("Peakleistung", 0); $this->RegisterPropertyInteger("Ueberschussleistung", 0); $this->RegisterPropertyInteger("Netzbezug", 0); // Initialisierung mit 0 $this->RegisterPropertyString("EnergyUserList", "[]"); // Timer registrieren $this->RegisterTimer("Timer_DistributeEnergy", 5000, 'IPS_RequestAction(' . $this->InstanceID . ', "DistributeEnergy", "");'); } public function ApplyChanges() { parent::ApplyChanges(); // Zusätzliche Konfigurationslogik hier hinzufügen $energyUserList = $this->ReadPropertyString("EnergyUserList"); } public function RequestAction($Ident, $Value) { switch ($Ident) { case "DistributeEnergy": $this->DistributeEnergy(); break; case "ApplyChanges": $this->ApplyChanges(); break; default: throw new Exception("Invalid Ident"); } } public function DistributeEnergy() { // Systemvariablen abrufen $Netzbezug = GetValue($this->ReadPropertyInteger('Netzbezug')); $Peakleistung = $this->ReadPropertyInteger('Peakleistung'); $Ueberschussleistung = $this->ReadPropertyInteger('Ueberschussleistung'); // Fallunterscheidung if ($Netzbezug < ($Peakleistung - $Ueberschussleistung) / 2) { $remainingPower = -1 * (-1 * $Ueberschussleistung + $Netzbezug); $getCurrentDataParam = false; } else { $remainingPower = $Peakleistung - $Netzbezug; $getCurrentDataParam = true; } // EnergyUserList auslesen und dekodieren $energyUserListJSON = $this->ReadPropertyString("EnergyUserList"); $energyUserList = json_decode($energyUserListJSON, true); if (empty($energyUserList)) { // Liste ist leer, daher nichts zu tun return; } // Schleife, um IPS_RequestAction für alle Benutzer auszuführen foreach ($energyUserList as $user) { if (IPS_InstanceExists($user['EnergyUser'])) { IPS_RequestAction($user['EnergyUser'], 'GetCurrentData', $getCurrentDataParam); } } $filteredEnergyUsers = []; $allIdle = true; // Variable zur Überprüfung, ob alle Benutzer Idle = true sind $totalCurrentPower = 0; // Variable zur Summierung der CurrentPower Werte foreach ($energyUserList as $user) { if (!IPS_InstanceExists($user['EnergyUser'])) { continue; } // Werte direkt von der EnergyUser-Instanz abrufen $currentPower = GetValue(IPS_GetObjectIDByIdent('CurrentPower', $user['EnergyUser'])); $usedEnergy = GetValue(IPS_GetObjectIDByIdent('UsedEnergy', $user['EnergyUser'])); $userPrio = GetValue(IPS_GetObjectIDByIdent('UserPrio', $user['EnergyUser'])); $lockPrio = GetValue(IPS_GetObjectIDByIdent('LockPrio', $user['EnergyUser'])); $idle = GetValue(IPS_GetObjectIDByIdent('Idle', $user['EnergyUser'])); $powerStepsJson = GetValue(IPS_GetObjectIDByIdent('PowerSteps', $user['EnergyUser'])); $powerSteps = json_decode($powerStepsJson, true); // EnergyUser-Daten zum gefilterten Array hinzufügen $filteredEnergyUsers[] = [ 'EnergyUser' => $user['EnergyUser'], 'InstanceID' => $user['EnergyUser'], 'CurrentPower' => $currentPower, 'UsedEnergy' => $usedEnergy, 'UserPrio' => $userPrio, 'LockPrio' => $lockPrio, 'Idle' => $idle, 'PowerSteps' => $powerSteps, // PowerSteps direkt hier hinzufügen ]; // Überprüfen, ob alle Benutzer Idle = true sind if (!$idle) { $allIdle = false; } // Add the totalCurrentPower to the remainingPower $totalCurrentPower += $currentPower; } $remainingPower += $totalCurrentPower; if (empty($filteredEnergyUsers)) { return; } // Wenn nicht alle Benutzer Idle = true sind, rufe SetCurrentPower mit CurrentPower Werten auf if (!$allIdle) { foreach ($filteredEnergyUsers as $user) { IPS_RequestAction($user['InstanceID'], 'SetCurrentPower', $user['CurrentPower']); } return; } // Sortiere die EnergyUser nach Priorität basierend auf dem Parameter usort($filteredEnergyUsers, function ($a, $b) use ($getCurrentDataParam) { $primaryKey = $getCurrentDataParam ? 'LockPrio' : 'UserPrio'; if ($a[$primaryKey] == $b[$primaryKey]) { return $a['UsedEnergy'] <=> $b['UsedEnergy']; } return $a[$primaryKey] <=> $b[$primaryKey]; }); // Primärschlüssel für die Priorität basierend auf dem Parameter auswählen $priorityKey = $getCurrentDataParam ? 'LockPrio' : 'UserPrio'; // Schleife durch alle Prioritäten $priorities = array_unique(array_column($filteredEnergyUsers, $priorityKey)); $groupedUsers = []; foreach ($priorities as $priority) { $groupedUsers[$priority] = array_filter($filteredEnergyUsers, function ($user) use ($priority, $priorityKey) { return $user[$priorityKey] == $priority; }); } IPS_LogMessage("Users", print_r($groupedUsers, true)); // Jetzt kannst du die Benutzer gruppenweise verarbeiten foreach ($groupedUsers as $priority => $users) { // EnergyUser mit gleicher Priorität sammeln $samePriorityUsers = isset($groupedUsers[$priority]) ? $groupedUsers[$priority] : []; // Wenn keine EnergyUser mit gleicher Priorität vorhanden sind, überspringen if (empty($samePriorityUsers)) { continue; } IPS_LogMessage("Manager", print_r($samePriorityUsers, true)); // Verbraucher die nicht 0 Annhemen können, bekommen einfach den tiefsten wert foreach ($samePriorityUsers as $entry) { if (in_array(0, $entry['PowerSteps'])) { $withZero[] = $entry; } else { $withoutZero[] = $entry; } } // Methode für alle im withoutZero-Array aufrufen if (!empty($withoutZero)) { foreach ($withoutZero as $entry) { $instanceID = $entry['InstanceID']; $minPowerStep = min($entry['PowerSteps']); // Simulierte Methode (Debug-Ausgabe) IPS_RequestAction($instanceID, 'SetCurrentPower', $minPowerStep); $remainingPower -= $entry['CurrentPower']; // Hier kann der tatsächliche Funktionsaufruf eingebaut werden // IPS_RequestAction($instanceID, 'SetCurrentPower', $minPowerStep); }} $samePriorityUsers = $withZero; // Array für die verteilte Energie pro User erstellen $userEnergyProv = array_fill_keys(array_column($samePriorityUsers, 'InstanceID'), 0); // Initialisierung für jeden Benutzer auf 0 setzen // Alle Schritte der Benutzer in einem Array sammeln $allSteps = []; foreach ($samePriorityUsers as $user) { foreach ($user['PowerSteps'] as $step) { $allSteps[] = ['user' => $user['InstanceID'], 'step' => $step]; } } IPS_LogMessage("allSteps", print_r($allSteps, true)); // Sortiere die Schritte nach Größe usort($allSteps, function ($a, $b) { return $a['step'] <=> $b['step']; }); IPS_LogMessage("sorted steps", print_r($allSteps, true)); // Iteriere durch alle Schritte foreach ($allSteps as $entry) { $user = $entry['user']; $powerstep = $entry['step']; // Überprüfe, ob noch genügend verbleibende Energie für den nächsten Schritt vorhanden ist if ($remainingPower >= $powerstep - $userEnergyProv[$user]) { // Aktualisiere die verbleibende Energie und die bereitgestellte Energie für den Benutzer $remainingPower -= $powerstep - $userEnergyProv[$user]; $userEnergyProv[$user] = $powerstep; } //else { // Wenn nicht genug Energie vorhanden ist, setze die verbleibende Energie // Test dieses break rauszunehmen ... break; //} } // Energie für jeden EnergyUser verbrauchen und loggen foreach ($userEnergyProv as $userInstanceID => $energy) { $weui = min( array_column( array_filter($allSteps, function ($entry) use ($userInstanceID) { return $entry['user'] == $userInstanceID; }), 'step' ) ); $energy = max($energy, $weui); // Testzeile // Methode SetCurrentPower für jeden EnergyUser aufrufen if (IPS_InstanceExists($userInstanceID)) { IPS_RequestAction($userInstanceID, 'SetCurrentPower', $energy); // Annahme: SetCurrentPower wird über eine Aktionsanfrage ausgeführt } } } // Debug-Ausgabe des Endzustands foreach ($filteredEnergyUsers as $user) { IPS_LogMessage("Manager", "Final state for instance {$user['InstanceID']}: CurrentPower = {$user['CurrentPower']}, UsedEnergy = {$user['UsedEnergy']}"); } } } ?>