Files
Enelix-EMS/tests/ManagerReglerTest.php
T
2026-09-16 05:18:01 +00:00

160 lines
5.0 KiB
PHP

<?php
declare(strict_types=1);
namespace Belevo\EnelixEMS\Tests;
use Belevo\EnelixEMS\ManagerRegler;
use Belevo\EnelixEMS\Nachrichtenvertrag;
use InvalidArgumentException;
use PHPUnit\Framework\TestCase;
final class ManagerReglerTest extends TestCase
{
public function testOhnePeakBegrenzungBleibtSolarladenAktiv(): void
{
self::assertSame(
ManagerRegler::BETRIEBSART_PV,
ManagerRegler::bestimmeBetriebsart(
true,
true,
25000.0,
ManagerRegler::BETRIEBSART_INAKTIV,
false,
-100.0,
10000.0,
0.0,
15000.0,
0.0
)
);
}
public function testBetriebsartBleibtZwischenDenSchwellenErhalten(): void
{
self::assertSame(
ManagerRegler::BETRIEBSART_PEAK,
ManagerRegler::bestimmeBetriebsart(
true,
true,
5000.0,
ManagerRegler::BETRIEBSART_PEAK,
true,
0.0,
10000.0,
0.0,
12000.0,
0.0
)
);
}
public function testUmschaltdifferenzVerhindertZuKleineAenderung(): void
{
self::assertSame(
ManagerRegler::BETRIEBSART_PV,
ManagerRegler::bestimmeBetriebsart(
true,
true,
11000.0,
ManagerRegler::BETRIEBSART_PV,
true,
0.0,
10000.0,
10000.0,
10500.0,
60.0
)
);
}
public function testVerteilungBeruecksichtigtPrioritaetEinzelwerteUndBereiche(): void
{
$ergebnis = ManagerRegler::verteile(
0.0,
4500.0,
[
$this->verbraucher(20, 5, [0, 3000], 0),
$this->verbraucher(10, 0, [0, ['Von_W' => 1000, 'Bis_W' => 2000], 4000], 0),
],
'PrioritaetPV'
);
self::assertSame(4500, $ergebnis['Verteilbudget_W']);
self::assertSame([10 => 4000, 20 => 0], $ergebnis['Sollwerte']);
self::assertSame(500, $ergebnis['Restabweichung_W']);
}
public function testNichtAenderbarerVerbraucherReserviertSeineIstleistung(): void
{
$fest = $this->verbraucher(10, 0, [0, 3000], 3000, false);
$steuerbar = $this->verbraucher(20, 1, [0, ['Von_W' => 1, 'Bis_W' => 4000]], 0);
$ergebnis = ManagerRegler::verteile(3000.0, 5000.0, [$fest, $steuerbar], 'PrioritaetPV');
self::assertSame(3000, $ergebnis['NichtSteuerbar_W']);
self::assertSame([20 => 2000], $ergebnis['Sollwerte']);
self::assertSame(0, $ergebnis['Restabweichung_W']);
}
public function testFehlendeIstleistungFaelltAufAngenommenenSollwertZurueck(): void
{
$verbraucher = $this->verbraucher(10, 0, [0, 3000], null, false);
$verbraucher['Daten']['Leistungsquelle'] = Nachrichtenvertrag::LEISTUNGSQUELLE_NICHT_VORHANDEN;
$verbraucher['Daten']['Istleistung_W'] = null;
$verbraucher['Daten']['Zustand'][0]['Wert'] = 3000;
$ergebnis = ManagerRegler::verteile(3000.0, 0.0, [$verbraucher], 'PrioritaetPV');
self::assertSame(3000, $ergebnis['AktuelleVerbraucherleistung_W']);
self::assertSame(-3000, $ergebnis['Restabweichung_W']);
}
public function testMonatlicheGrenzeMussVollstaendigSein(): void
{
$this->expectException(InvalidArgumentException::class);
ManagerRegler::wirksameLastspitzengrenze(2, 0.0, [1 => 12000.0], 9);
}
/**
* @param list<int|array{Von_W: int, Bis_W: int}> $leistungswerte
* @return array{InstanzID: int, Daten: array<string, mixed>}
*/
private function verbraucher(
int $instanzID,
int $prioritaet,
array $leistungswerte,
?int $istleistung,
bool $aenderungMoeglich = true
): array {
$quelle = $istleistung === null
? Nachrichtenvertrag::LEISTUNGSQUELLE_NICHT_VORHANDEN
: Nachrichtenvertrag::LEISTUNGSQUELLE_GEMESSEN;
return [
'InstanzID' => $instanzID,
'Daten' => [
'Kopf' => [
'Version' => Nachrichtenvertrag::VERSION,
'AbsenderID' => $instanzID,
'EmpfaengerID' => 1,
'Zeitpunkt' => 1788825600,
],
'PrioritaetPV' => $prioritaet,
'PrioritaetPeak' => $prioritaet,
'Leistungswerte_W' => $leistungswerte,
'AenderungMoeglich' => $aenderungMoeglich,
'Verfuegbar' => true,
'Istleistung_W' => $istleistung,
'Leistungsquelle' => $quelle,
'Zustand' => [[
'Kennung' => 'Sollleistung_W',
'Art' => 'Sollwert',
'Wert' => $istleistung,
'Einheit' => 'W',
]],
],
];
}
}