$wechselrichter * @param array $letzteGrenzen * @return array{ * Netzabweichung_W: float, * ZielGesamtleistung_W: float, * Abregelbedarf_W: float, * Grenzen_W: array * } */ public static function verteile( float $netzleistung, float $einspeisegrenze, array $wechselrichter, array $letzteGrenzen = [] ): array { if ($einspeisegrenze < 0.0) { throw new InvalidArgumentException('Einspeisegrenze darf nicht negativ sein.'); } if ($wechselrichter === []) { throw new InvalidArgumentException('Mindestens ein regelbarer Wechselrichter ist erforderlich.'); } $nennleistungGesamt = 0.0; $istleistungGesamt = 0.0; $bisherigeGrenzeGesamt = 0.0; $normalisiert = []; $kennungen = []; foreach ($wechselrichter as $eintrag) { $id = $eintrag['ID'] ?? null; $nennleistung = $eintrag['Nennleistung_W'] ?? null; $istleistung = $eintrag['Istleistung_W'] ?? null; if (!is_string($id) || trim($id) === '' || isset($kennungen[$id])) { throw new InvalidArgumentException('Wechselrichter-ID fehlt oder ist mehrfach vorhanden.'); } if (!is_numeric($nennleistung) || (float) $nennleistung <= 0.0) { throw new InvalidArgumentException('Wechselrichter-Nennleistung muss groesser als 0 sein.'); } if (!is_numeric($istleistung) || (float) $istleistung < 0.0) { throw new InvalidArgumentException('Wechselrichter-Istleistung darf nicht negativ sein.'); } $nennleistung = (float) $nennleistung; $istleistung = min((float) $istleistung, $nennleistung); $bisherigeGrenze = $letzteGrenzen[$id] ?? $nennleistung; if (!is_numeric($bisherigeGrenze)) { throw new InvalidArgumentException('Gespeicherte Wechselrichtergrenze ist ungueltig.'); } $bisherigeGrenze = max(0.0, min((float) $bisherigeGrenze, $nennleistung)); $normalisiert[] = [ 'ID' => $id, 'Nennleistung_W' => $nennleistung, 'Istleistung_W' => $istleistung, ]; $kennungen[$id] = true; $nennleistungGesamt += $nennleistung; $istleistungGesamt += $istleistung; $bisherigeGrenzeGesamt += $bisherigeGrenze; } $netzabweichung = $netzleistung + $einspeisegrenze; $zielGesamt = $bisherigeGrenzeGesamt; $nachIstleistungVerteilen = false; if ($netzabweichung < 0.0) { $nachIstleistungVerteilen = $istleistungGesamt > 0.0; $zielGesamt = min($bisherigeGrenzeGesamt, $istleistungGesamt) + $netzabweichung; } elseif ($netzabweichung > 0.0) { $zielGesamt = $bisherigeGrenzeGesamt + $netzabweichung; } $zielGesamt = max(0.0, min($zielGesamt, $nennleistungGesamt)); $grenzen = []; foreach ($normalisiert as $eintrag) { $anteil = $nachIstleistungVerteilen ? $eintrag['Istleistung_W'] / $istleistungGesamt : $eintrag['Nennleistung_W'] / $nennleistungGesamt; $grenzen[$eintrag['ID']] = round( min($eintrag['Nennleistung_W'], $zielGesamt * $anteil), 3 ); } return [ 'Netzabweichung_W' => $netzabweichung, 'ZielGesamtleistung_W' => round($zielGesamt, 3), 'Abregelbedarf_W' => round(max(0.0, $istleistungGesamt - $zielGesamt), 3), 'Grenzen_W' => $grenzen, ]; } public static function stellwert(float $grenzeW, float $nennleistungW, string $art): float { if ($nennleistungW <= 0.0 || $grenzeW < 0.0) { throw new InvalidArgumentException('Leistungsgrenzen sind ungueltig.'); } $grenzeW = min($grenzeW, $nennleistungW); if ($art === 'percent') { return round($grenzeW / $nennleistungW * 100.0, 2); } if ($art === 'watt') { return round($grenzeW, 1); } throw new InvalidArgumentException('Begrenzungsart muss percent oder watt sein.'); } }